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

kriysna
  • 6,118
  • 7
  • 30
  • 30
  • `some = 'some_data'` in first example is only a local variable, assigning of instance variable should use self as receiver (as in second example) or with @ sign (like `@some = 'some_data'`). – taro May 11 '11 at 11:00

5 Answers5

12

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

Reactormonk
  • 21,472
  • 14
  • 74
  • 123
1

It's (local) variable in the first example

lzap
  • 16,417
  • 12
  • 71
  • 108
0

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

ewH
  • 2,553
  • 2
  • 20
  • 13
0

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

Sony Santos
  • 5,435
  • 30
  • 41
  • But in the first example I could set value for `some` as `Test.some = 'new_data'`. Which means `some` getter and setter method is class methods. Isn't it? – kriysna May 12 '11 at 03:03
0

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

Orlando
  • 9,374
  • 3
  • 56
  • 53