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

在上面,我可以找到 self 作为 Test 本身,但不返回some_dataas 输出。

但是,虽然我按照以下方式进行了修改,但它返回了预期的输出

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

有什么区别?

编辑

现在在第一个示例中,如果我将 getsome方法设置为

Test.some = 'new_data'
puts Test.some.inspect #=> new_data
Test.set_some
puts Test.get_some.inspect => new_data

现在这让我更加困惑了。

4

5 回答 5

12

some = :foo让 ruby​​ 认为它应该使用 name 创建一个新的局部变量some。如果你想打电话some=(),你必须使用一个显式的接收者——如self.some = :foo. 我曾经在那个赌注上输了... :-/

于 2011-05-11T11:08:38.637 回答
1

在第一个示例中它是(局部)变量

于 2011-05-11T11:00:39.383 回答
0

在第一个例子some中是一个局部变量。

在第二个中,some是一种方法self。为什么?因为attr_accessor :some是一样的:

def some= (val)
  @some = val
end

def some
  return @some
end

因此,您已经为实例变量创建了 getter 和 setter 方法@some(它是 object 的实例变量Test,因为每个类也是 class 的对象Class)。

于 2011-05-11T11:29:15.583 回答
0

没有方法覆盖和局部变量的示例 1

class Foo
  def initialize
    @foo = 'foo'
  end

  def print_foo
    print @foo
    print self.foo
    print foo
  end
end

@foo、self.foo 和 foo 将在实例方法中访问实例变量 @foo:

Foo.new.print_foo #=> foofoofoo

带有方法覆盖的示例 2

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 将访问实例变量,但 self.foo 和 foo 将调用 foo 覆盖方法:

Foo.new.print_foo #=> foobarbar

带有方法覆盖和局部变量的示例 3

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 访问实例变量,self.foo 访问覆盖方法,foo 访问局部变量:

Foo.new.print_foo #=> foobarbaz

于 2013-12-28T05:02:34.453 回答
0

在第一种方法中

def set_some
  puts self.inspect
  some = 'some_data'
end

some 是一个局部变量。它与 @some 是一个实例变量(在这种情况下是一个类实例变量)不同,所以当方法结束时该值会消失。

如果您想调用 setter 方法 some 或将 @some 设置为某事,请执行此操作

@some = 'some_data'

或者

self.some = 'some_data'

在第二种方法中

def get_some
  puts self.inspect
  self.some
end

你调用一些方法。它返回实例变量@some.. 并且因为此时@some 没有值.. 返回nil..

于 2012-01-09T04:54:20.577 回答