Ruby attr_访问器在哪里定义?

Ruby attr_访问器在哪里定义?,ruby,Ruby,目前正在使用的lex()方法开发ruby迷你程序。然而,当前属性访问器被定义为一个标识符。。。我想是因为这是一种方法 在哪里定义了属性存取器?如果我知道它是在哪里定义的,我可以很容易地为类似它的方法创建异常。它是在模块中定义的 编辑: 为了让答案更完整,它是模块类的私有方法,这意味着你不能用接收器调用它,需要打开类才能使用它(或者使用一些类似发送或评估)的技巧: 不能将其作为MyClassOrModule.attr\u访问器调用。正如您在下面的评论中已经发现的那样,Module.private\

目前正在使用的
lex()
方法开发ruby迷你程序。然而,当前属性访问器被定义为一个标识符。。。我想是因为这是一种方法


在哪里定义了属性存取器?如果我知道它是在哪里定义的,我可以很容易地为类似它的方法创建异常。

它是在
模块中定义的

编辑: 为了让答案更完整,它是
模块
类的私有方法,这意味着你不能用接收器调用它,需要打开类才能使用它(或者使用一些类似
发送
评估
)的技巧:


不能将其作为
MyClassOrModule.attr\u访问器调用
。正如您在下面的评论中已经发现的那样,
Module.private\u instance\u方法将显示它的存在。

是的,
attr\u访问器
是在类
Module
()中定义的,但是首先如何查找它呢?不得不问别人,或者谷歌搜索,并不是一种非常有效的方式

我们可以利用这种方法

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

m = [1,2,3].method(:[])
  #=> #<Method: Array#[]
m
的确定使用该方法

或者,我们可以写作

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

啊哈!它在
Numeric
中定义,它是
整数
浮点
基本原理
复数
的超类

请注意,在计算
m
时,显示的消息包括,
“整数(数值)”
。甚至在计算
m.owner
之前,这就告诉我们所有者是
数字的。相反,在查找
Array#[]
的所有者时,消息只是
“Array”
。与往常一样,Ruby在所有者不是
方法
的接收者的类或
实例_方法
的接收者的类时,附加说明了所有者

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

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

m = Class.instance_method(:attr_accessor)
  #=> #<UnboundMethod: Class(Module)#attr_accessor>
m.owner
  #=> Module
m=Class.instance\u方法(:attr\u访问器)
#=> #
m、 所有者
#=>模块
最后一个原因是每个类(它是
class
的实例)的方法都是
class
的实例方法


1如果忘记了实例方法
owner
是在哪里定义的,请记住它是在方法上定义的,这些方法是类
method

为什么
Module.methods.include?:属性存取器#=>假
?啊。。。它在
模块中。私有\u实例\u方法
似乎相反。是的,当你回答时,只是键入它是私有的。:)较新版本的Ruby更善于识别哪些方法是公共的,哪些是私有的。旧的方法会将该方法列为存在,但当您调用它时,您会发现您不能。请注意,
Module.methods
并没有提供在
Module
中定义的方法,而是提供了
Module
响应的方法,即在
Module
的类中定义的方法,不在
模块
本身中。现在,在这种特殊情况下,这实际上会意外地起作用,因为
模块
的类是
,它是
模块
的子类,因此
模块
响应
模块
中定义的所有方法。当然,在这里,这仍然不起作用,因为
attr\u accessor
是私有的。这只是一个方法名,虽然是一个常见的名称,但处理它不应该有任何特殊的语法要求。不过,很多Ruby语法高亮软件都把它看作是特殊的,这也许就是为什么你的lexer会这样做的原因。@tadman哦,不,这就是问题所在。lexer没有把它当作特殊的,因此我的迷你们变成了
A类;属性存取器:b;结束
进入
A类;x1:b;结束
,这实际上是行不通的。所以我需要修改它,使
attr\u accessor
和所有其他“特殊方法”不缩小方法名称。这似乎是一种不好的缩小方法,因为
attr\u accessor
非常重要,不能忽略。Ruby不一定是尝试缩小方法名称的最佳方法,我甚至不确定您为什么要这样做。如果你不特别小心的话,你会遇到很多复杂的语法规则。许多代码也是非常动态的,这破坏了大多数缩小的努力,JavaScript(例如Angular)在重命名具有特定和重要名称的函数参数和变量时试图防止这一问题的笨拙方法。
attr\u accessor
确实非常重要,因此在本例中防止了缩小,方法名也是如此。事实上,我已经遇到了一些问题,但我正在逐步解决这些问题。嗨,卡里,谢谢你的详细回复。顺便说一下,
Class.new.methods.include(:attr\u accessor)
返回
false
,而不是
true
。或者至少在我的ruby版本中是这样的
ruby 2.4.1p111(2017-03-22修订版58053)[x64-mingw32]
我记得在这里发布之前自己测试过这个。
m = 3.method(:zero?)
  #=> #<Method: Integer(Numeric)#zero?>
m = Integer.instance_method(:zero?)
  #=> #<UnboundMethod: Integer(Numeric)#zero?>
m.owner
  #=> Numeric
m = Class.method(:attr_accessor)
  #=> #<Method: Class.attr_accessor>
m.owner
  #=> Module
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