- When declaring an attribute field with:
attr_accessor :name
how do you acces the new :name created in order to make an array could i just say :name = [0,0,0,0,0] in the initializer? .
You don't. You access @name
internally, and name
externally. :name
is a symbol, it's not the name of the variable.
- How do you access an attribute defined with @name
Internally with @name
. You cannot access it outside the class without defining accessors
- What's the difference between :name and @name ?
Everything. One is an instance variable, the other is a symbol. They're completely different things.
Ok. You're quite confused here.
In Ruby, @name
is an instance variable on the current class. You can read and write to it while you're in the context of that class (inside one of its methods) but you cannot read or write to it from outside that class.
To do so, you need to define accessor methods. Typically the accessor methods have the same name as the @variable
, but they do not have the @
prefix, because they're methods not instance variables.
So, if I had a variable @name
on my class, I would give external code access to reading it with a "getter" method:
def name
@name
end
Now, people can use some_instance_of_my_class.name
to get access to @name
. Internally as well, you can now access the name
method to read @name
, and this is often a good idea.
If I wanted to let people have write access, I'd define a setter, which in Ruby has a special syntax:
def name=(value)
@name = value
end
Now, people can use some_instance_of_My_class.name = "new name"
to write to @name
. Internally you can write to name with name=
, but you must prefix it with self.name=
or Ruby will assume you're defining a new local variable called name
.
So, attr_accessor
. This is just a method, like any other method, except that it does a little bit of meta-programming for you. When you use attr_accessor :name
or attr_accessor 'name'
, you're simply invoking a method with an argument, and the argument is the name of the method to define. It will create the above def name
and def name=
methods for you, with the same method bodies, wrapping around an @name
variable.
If you'd written attr_accessor :bob
, it would give you:
def bob
@bob
end
def bob=(value)
@bob = value
end
On to your specific problems:
@rolled.each do |item|
item = 1 + rand(6)
end
This won't work, because item
is passed by value to the block
. The item
variable inside the loop is it's own variable, and modifying it through assignment doesn't affect the values stored in @rolled
. To change those values, you need to assign to @rolled
directly.
You can do this easily with map
, which overwrites the entire array with a new array:
@rolled = (1..6).map do |roll|
rand(1..6)
end
You can do this for individual items with an each_with_index
, though there isn't any value to doing this when the entire array is filled with 0
anyways:
@rolled.each_with_index do |item,index|
@rolled[index] = rand(1..6)
end