【问题标题】:What is this line of Ruby code doing? [duplicate]这行 Ruby 代码在做什么? [复制]
【发布时间】:2013-01-15 02:41:47
【问题描述】:

可能重复:
class << self idiom in Ruby

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

class User
  class << self; attr_accessor :base_uri end
  ....
....
...

【问题讨论】:

标签: ruby


【解决方案1】:

您会看到class &lt;&lt; self 在Ruby 中经常使用。理解它的作用的最简单方法是将其视为(几乎)等价于:

class Abc
   self.attr_accessor ...
end

和这个基本一样:

Abc.class.attr_accessor ...

但你真的不能这样做,因为:

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

所以要绕过它,你必须这样做:

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

或者:

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

这就是&lt;&lt; self 构造的用武之地,因为它使您可以访问这些私有方法。您基本上是直接在“自我空间”中操作。

当你看到类似的:

class Abc
   class << self
     def foo
     end
   end
end

就是说:

class Abc
   def self.foo
   end
end

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

编辑

至于一种不太复杂的方法——默认情况下,Ruby 并没有能够创建类级 attr_accessors 的方法。这就是您必须使用&lt;&lt; self 技巧的原因。

但 Rails 确实定义了一个无需使用 &lt;&lt; self 即可执行类似操作的方法。在 Rails 中你有 cattr_accessor:

class Abc
   cattr_accessor :blah
end

Abc.blah = 123
Abc.blah
>> 123

【讨论】:

    【解决方案2】:

    这让我们在类上下文中定义一个实例变量。

    查看代码:

    class User
      class << self; attr_accessor :base_uri end
      @base_uri = "aaa";
    end
    
    p User.base_uri # will output "aaa"
    

    【讨论】:

    • 嗯?所以如果我不想像我发布的那样写它,有没有更简单的方法来写同样的东西?
    猜你喜欢
    • 1970-01-01
    • 2018-11-01
    • 2016-08-02
    • 2016-04-06
    • 2015-08-25
    • 2011-01-24
    • 1970-01-01
    • 2018-03-14
    • 2014-12-01
    相关资源
    最近更新 更多