这行Ruby代码在做什么?

Boh*_*ohn 0 ruby

可能重复:
Ruby中的类<< self idiom

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

class User
  class << self; attr_accessor :base_uri end
  ....
....
...
Run Code Online (Sandbox Code Playgroud)

Cas*_*per 5

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

class Abc
   self.attr_accessor ...
end
Run Code Online (Sandbox Code Playgroud)

这跟基本相同:

Abc.class.attr_accessor ...
Run Code Online (Sandbox Code Playgroud)

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

> Abc.class.attr_accessor :blah
NoMethodError: private method `attr_accessor' called for Class:Class
Run Code Online (Sandbox Code Playgroud)

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

> Abc.class.send(:attr_accessor, :blah)
Run Code Online (Sandbox Code Playgroud)

要么:

class Abc
  self.send(:attr_accessor, :blah)
end 
Run Code Online (Sandbox Code Playgroud)

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

同样当你看到:

class Abc
   class << self
     def foo
     end
   end
end
Run Code Online (Sandbox Code Playgroud)

这跟说:

class Abc
   def self.foo
   end
end
Run Code Online (Sandbox Code Playgroud)

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

编辑

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

但Rails确实定义了一种方法,可以在不必使用的情况下执行类似的操作<< self.在Rails中你有cattr_accessor:

class Abc
   cattr_accessor :blah
end

Abc.blah = 123
Abc.blah
>> 123
Run Code Online (Sandbox Code Playgroud)