问题
class Test
class << self
attr_accessor :some
def set_some
puts self.inspect
some = 'some_data'
end
def get_some
puts self.inspect
some
end
end
end
Test.set_some => Test
puts Test.get_some.inspect => Test nil
Here above I could find self as Test itself but not returning the some_data
as output.
But while I modified in following way it returns expected output
class Test
class << self
attr_accessor :some
def set_some
puts self.inspect
self.some = 'some_data'
end
def get_some
puts self.inspect
self.some
end
end
end
Test.set_some => Test
puts Test.get_some.inspect => Test some_data
What is the differences?
EDIT
Now in the first example if I set as get some
method as
Test.some = 'new_data'
puts Test.some.inspect #=> new_data
Test.set_some
puts Test.get_some.inspect => new_data
Now it made me much more confused.
回答1:
some = :foo
makes ruby think it should create a new local variable with name some
. If you want to call some=()
, you have to use an explicit reciever - as in self.some = :foo
. I once lost a bet on that... :-/
回答2:
It's (local) variable in the first example
回答3:
In the first example some
is a local variable.
In the second one, some
is a method of self
. Why? Because attr_accessor :some
is the same as:
def some= (val)
@some = val
end
def some
return @some
end
So, you have created the getter and setter methods for the instance variable @some
(it's an instance variable of the object Test
, as every class is also an object of class Class
).
回答4:
in the first method
def set_some
puts self.inspect
some = 'some_data'
end
some is a local variable.. its not the same as @some that is a instance variable (in this case a class instance variable) so the value disappears when the method ends.
if you want to call the setter method some or set @some to something then do this
@some = 'some_data'
or
self.some = 'some_data'
in the second method
def get_some
puts self.inspect
self.some
end
your calling the method some. which returns the instace variable @some.. and since at this point @some has no value.. returns nil..
回答5:
Example 1 with no method override and no local variable
class Foo
def initialize
@foo = 'foo'
end
def print_foo
print @foo
print self.foo
print foo
end
end
@foo, self.foo, and foo will access instance variable @foo within the instance method:
Foo.new.print_foo #=> foofoofoo
Example 2 with method override
class Foo
def initialize
@foo = 'foo'
end
def foo
return 'bar'
end
def print_foo
print @foo
print self.foo
print foo
end
end
@foo will access the instance variable, but self.foo and foo will call the foo override method:
Foo.new.print_foo #=> foobarbar
Example 3 with method override and local variable
class Foo
def initialize
@foo = 'foo'
end
def foo
return 'bar'
end
def print_foo
foo = 'baz'
print @foo
print self.foo
print foo
end
end
@foo accesses instance variable, self.foo accesses override method, and foo accesses local variable:
Foo.new.print_foo #=> foobarbaz
来源:https://stackoverflow.com/questions/5963076/understand-self-for-attr-accessor-class-method