课外实例变量

如实例变量属于某个类别,我可否直接使用该类别的实例来存取该实例变量(例如 @hello) ?

class Hello
def method1
@hello = "pavan"
end
end


h = Hello.new
puts h.method1
86799 次浏览

Yes, you can use instance_variable_get like this:

class Hello
def method1
@hello = "pavan"
end
end


h = Hello.new
p h.instance_variable_get(:@hello) #nil
p h.method1                        #"pavan" - initialization of @hello
p h.instance_variable_get(:@hello) #"pavan"

If the variable is undefined (first call of instance_variable_get in my example) you get nil.


As Andrew mention in his comment:

You should not make this the default way you access instance variables as it violates encapsulation.

A better way is to define an accessor:

class Hello
def method1
@hello = "pavan"
end
attr_reader :hello
end


h = Hello.new
p h.hello #nil
p h.method1                        #"pavan" - initialization of @hello
p h.hello #"pavan"

If you want another method name, you could alias the accessor: alias :my_hello :hello.

And if the class is not defined in your code, but in a gem: You can modify classes in your code and insert new functions to classes.

You can also accomplish this by calling attr_reader or attr_accessor like this:

class Hello
attr_reader :hello


def initialize
@hello = "pavan"
end
end

or

class Hello
attr_accessor :hello


def initialize
@hello = "pavan"
end
end

Calling attr_reader will create a getter for the given variable:

h = Hello.new
p h.hello        #"pavan"

Calling attr_accessor will create a getter AND a setter for the given variable:

h = Hello.new
p h.hello        #"pavan"
h.hello = "John"
p h.hello        #"John"

As you might understand, use attr_reader and attr_accessor accordingly. Only use attr_accessor when you need a getter AND a setter and use attr_reader when you only need a getter