attr_accessor在哪里定义?

时间:2018-07-27 19:43:27

标签: ruby

当前正在使用Ripperlex()方法开发红宝石矿机。但是目前attr_accessor被定义为标识符...我认为是因为它是一种方法。

attr_accessor在哪里定义?如果我知道它的定义位置,那么我可以轻松地为类似的方法设置异常。

2 个答案:

答案 0 :(得分:1)

它在Out-HostColored类中定义。 (Documentation Link)

编辑: 只是为了使答案更完整,它是Module类的 private 方法,这意味着您不能用接收方调用它,需要打开类才能使用它(或使用诸如Modulesend之类的黑客手段:

eval

您不能将其作为class MyClassOrModule attr_accessor :foobar end 来调用。正如您在下面的评论中已经发现的,MyClassOrModule.attr_accessor将显示它的存在。

答案 1 :(得分:0)

是的,attr_accessor是在类ModuleModule#attr_accessor)中定义的,但是如何首先找到它呢?不得不问一个人,或者也许是谷歌搜索,不是解决这个问题的非常有效的方法。

我们可以使用方法Method#owner 1

owner响应方法对象(类Method的实例),而不响应作为符号的方法名称。为什么?因为许多模块/类都具有具有相同符号名的方法。例如,StringArrayHash都有一个名为:[]的实例方法。因此,我们不能问Ruby :[]的定义位置。但是,我们可以问该方法在哪里

m = [1,2,3].method(:[])
  #=> #<Method: Array#[]
定义

,即

m.owner
  #=> Array

m的确定使用方法Object#method

或者,我们可以写

m = Array.instance_method(:[])
  #=> #<UnboundMethod: Array#[]>
m.owner
  #=> Array

这利用了方法Module#instance_mathod

请注意,在第一种情况下,方法:[]被绑定到Array [1,2,3]的实例,而在第二种情况下,:[]没有绑定到Array的任何特定实例,因此称为UnboundMethod。无论哪种方式,我们都可以看到Array#[]是在Array中定义的(即,它不是从祖先继承的)。

让我们考虑另一个例子。

我们知道3.zero? #=> false,但是在类Integer中找不到实例方法:zero?。那么,它在哪里?我们可以这样写:

m = 3.method(:zero?)
  #=> #<Method: Integer(Numeric)#zero?>

m = Integer.instance_method(:zero?)
  #=> #<UnboundMethod: Integer(Numeric)#zero?>

然后

m.owner
  #=> Numeric

啊哈!它是在NumericIntegerFloatRationale的超类Complex中定义的。

请注意,在计算m时,显示的消息包括"Integer(Numeric)"。甚至在计算m.owner之前,它就告诉我们所有者是Numeric。相比之下,在找到Array#[]的所有者时,消息只是"Array"。与往常一样,当所有者不是method的接收者的类或instance_method的接收者的类时,Ruby会在括号内给出所有者。

现在让我们找到类方法:attr_accessor的所有者。我们知道该方法可用于每个类(例如Class.new.methods.include?(:attr_accessor) #=> true),因此我们可以编写

m = Class.method(:attr_accessor)
  #=> #<Method: Class.attr_accessor>
m.owner
  #=> Module

因为Class本身是一个类,但是我们可以写,比如说,

m = Regexp.method(:attr_accessor)
  #=> #<Method: Regexp.attr_accessor>
m.owner
  #=> Module

甚至

m = Class.instance_method(:attr_accessor)
  #=> #<UnboundMethod: Class(Module)#attr_accessor>
m.owner
  #=> Module

最后一个原因是每个类(它是Class的实例)的方法都是Class的实例方法。

1如果忘记了实例方法owner的定义位置,只需记住它是在方法中定义的,这些方法是类Method的实例。