这行Ruby代码在做什么?

What is this line of Ruby code doing?

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
class << self idiom in Ruby

我想知道这段代码在做什么。 我并不低估这一行。 我知道attr_accessor是什么。

1
2
3
4
5
class User
  class << self; attr_accessor :base_uri end
  ....
....
...


您将看到Ruby中经常使用的class << self。理解它的作用的最简单方法是将其视为(几乎)等同于此:

1
2
3
class Abc
   self.attr_accessor ...
end

这跟基本相同:

1
Abc.class.attr_accessor ...

但是你真的不能做到这两点,因为:

1
2
> Abc.class.attr_accessor :blah
NoMethodError: private method `attr_accessor' called for Class:Class

因此,要解决它,你必须做:

1
> Abc.class.send(:attr_accessor, :blah)

要么:

1
2
3
class Abc
  self.send(:attr_accessor, :blah)
end

这就是<< self构造的用武之地,因为它允许您访问这些私有方法。您基本上是在"自我空间"中直接操作。

同样当你看到:

1
2
3
4
5
6
class Abc
   class << self
     def foo
     end
   end
end

这跟说:

1
2
3
4
class Abc
   def self.foo
   end
end

这将定义一个类方法,就像你的问题中的代码将定义一个类级别的attr_accessor。

编辑

至于一种不太复杂的方式 - Ruby默认情况下没有一个能够创建类级别attr_accessors的方法。这就是你必须使用<< self技巧的原因。

但是Rails确实定义了一种类似的方法,而不必使用<< self。在Rails中你有cattr_accessor

1
2
3
4
5
6
7
class Abc
   cattr_accessor :blah
end

Abc.blah = 123
Abc.blah
>> 123

这允许在类上下文中定义一个实例变量。

看代码:

1
2
3
4
5
6
class User
  class << self; attr_accessor :base_uri end
  @base_uri ="aaa";
end

p User.base_uri # will output"aaa"