开发者

understand self for attr_accessor class method

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

cla开发者_JAVA百科ss 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.


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... :-/


It's (local) variable in the first example


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).


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..


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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜