问题
I'm new to Ruby programming and I've seen a few examples now where an instance variable is being called without the "@" symbol in front of it.
I'm not sure if this because the method is being called and the instance variable is stored in the method as a result of a attr_reader
in the class or if because I have the wrong understanding of instance variables.
Here's an example of what I'm referring to taken from Russ Olsen's Eloquent Ruby, where the @unique
array has the size
method called on it without the "@" symbol in front of it:
class TextCompressor
attr_reader :unique, :index
def initialize(text)
@unique = []
@index = []
add_text(text)
end
def add_text(text)
words = text.split
words.each { |word| add_word(word) }
end
def add_word(word)
i = unique_index_of(word) || add_unique_word(word)
@index << i
end
def unique_index_of(word)
@unique.index(word)
end
def add_unique_word(word)
@unique << word
unique.size - 1
end
end
回答1:
I'm also new to Ruby and have been learning for a couple weeks. I believe:
attr_reader :unique
is functionally identical to defining the method:
def unique
@unique
end
回答2:
You don't "call" instance variables, but you call methods. Your assumption is right, that you do an actual method call without the "@". The attr_accessor :unique, :index
is basically equivalent to:
def unique
@unique
end
def unique=(val)
@unique = val
end
def index
@index
end
def index=(val)
@index = val
end
That you can write unique = val
when a unique=(val)
method is defined is syntactic sugar provided by Ruby to make it look like a variable assignment, even though it's actually a method call.
In general you shouldn't mix the different ways of referencing the instance variable in one method though. If a method has to know the implementation details of how the value is stored, you can use the direct access with @
. Otherwise, you should use the accessor methods. The less code is relying on implementation details, the better. Even if it's inside instance methods of the respective instance.
回答3:
attr_reader creates method with the name of the argument you supplied, returning a instance variable with same name. eg: -
attr_reader :name
it will create a method at runtime like this
def name
@name
end
and same with attr_writer, it creates a setter method for that argument like
attr_writer :name
def name=(value)
@name = value
end
and, attr_accessor creates both getter and setter with the name of the argument you supplied.
回答4:
The line :
attr_reader :unique, :index
creates getter methods for unique and index like :
def unique
@unique
end
So when you call :
unique.size
It first calls the getter method which returns @unique and then size method on it.
来源:https://stackoverflow.com/questions/18502005/calling-instance-variables-without