1

Here as you see we have one attribute called "attributes" and we initialize it in our class, so the question is where the name and shirt attributes come from, as we dont initialize and define them in our class?

class Shirt 
  attr_accessor :attribute
  def initialize(attributes)
    @attributes = attributes
  end
end

store = Shirt.new(name: "go", size: "42")

Also when I inspect this instance of the shirt class I get a hash:

@attributes={:name=>"go", :size=>"42"}

Anyone can help explain it?

Artjom B.
  • 61,146
  • 24
  • 125
  • 222

3 Answers3

1

In Ruby if correctly defined, the last argument is automatically interpreted to be a hash and you are allowed to pass it without the {}. Since there is only one argument it too is considered as the last argument:

store = Shirt.new(name: "go", size: "42")
#=> #<Shirt:0x000000022275c0 @attribute={:name=>"go", :size=>"42"}>

is the same as:

store = Shirt.new({name: "go", size: "42"})
#=> #<Shirt:0x000000022271d8 @attribute={:name=>"go", :size=>"42"}>
Sagar Pandya
  • 9,323
  • 2
  • 24
  • 35
  • 1
    For Ruby 2.7, this implicit hash attribute generates a warning, and for Ruby 3, this generates an error. Newer versions of Ruby does not allow an implicit passage of a hash as the last parameter of a method. You have to explicit expect and call method with the double splat operator. [Reference](https://www.ruby-lang.org/en/news/2019/12/12/separation-of-positional-and-keyword-arguments-in-ruby-3-0/) – Allam Matsubara May 03 '21 at 18:09
0
@attributes={:name=>"go", :size=>"42"}

What this line says to you is that you have one instance variable named @attributes and its value is an hash, {:name=>"go", :size=>"42"}

Look the difference with two simple variables instead

class A
  def initialize(dogs, cats)
    @dogs = dogs
    @cats = cats
  end
end

A.new(4, 5)
 => #<A:0x007f96830e3c80 @dogs=4, @cats=5> 
Ursus
  • 29,643
  • 3
  • 33
  • 50
0

the directive attr_accessor :attribute define 2 methods

def attribute; @attribute;end

and

def attribute=(value); @attribute=value;end

but when you type store = Shirt.new(name: "go", size: "42") you are define an hash and pass it to the attributes param:

init_values={name: "go", size: "42"}
store = Shirt.new(init_values)

in the initialize methods, attributes param is treated as a Hash and passed to the @attributes instance variable

try inspect

store = Shirt.new(["go","42"])
store = Shirt.new({})

ps.

try with attr_accessor :attributes and then you will able to use

store.attributes
store.attributes=
Luca Arcara
  • 46
  • 1
  • 3