红宝石的设计理念令人惊叹。所以我做了1 + 2
并获得3
。我设法做到了:1.+(2) # => 3
。
虽然很酷,但我还想在class
方法上测试+
方法。
+.class
=> SyntaxError: (irb):14: syntax error, unexpected '.'
+.class
^
然后:
+().class
=> NoMethodError: undefined method `+@' for NilClass:Class
虽然:
+(2).class
NoMethodError: undefined method `+@' for Fixnum:Class
为什么+(2).class
是一个fixnum而不是整数?我使用+(2.to_i).class
再次尝试,+(2).class
显示相同的错误。
但回到关键问题:我如何找到+
方法的类?
答案 0 :(得分:4)
1 + 2
在+
上调用1
方法,2
作为参数,与1.+(2)
相同。
但是,由于优先级,+(2).class
实际上首先调用(2).class
,返回Class
的实例,然后调用不存在的+@
方法,这是一元加号仅适用于Numeric
的方法。您可以通过键入(+(2)).class
来测试此问题,Fixnum
会按预期返回+().class
。这也是()
错误的来源,因为nil
返回nil
,而NilClass
的类是+@
,它也没有+
。我有一个+@
方法。
tl; dr:因为优先级导致+
最后评估为Method
。
任何对象上的+
方法都属于类method
,与任何对象上的任何其他方法一样。但是,键入1.method(:+)
会调用该方法而不是返回它,因为Matz在梦中看到一种返回方法而不是调用它们的编程语言并没有运行。您可以通过使用方法名称调用1.method(:+).class
方法返回给您的方法,如下所示:{{1}}。然后你可以让方法对象告诉你它的类是什么:{{1}}。
答案 1 :(得分:3)
如何找到+方法的类?
1.method(:+).owner # => Fixnum
'1'.method(:+).owner # => String
正如上面的输出清楚地告诉您,当您执行1 + 2
或1.+(2)
时,正在调用Fixnum#+
方法。类似的方式您可以写'1' + '2'
或'1'.+('2')
。正在调用String#+
方法。
答案 2 :(得分:2)
简单:)
试试:
m = 1.method("+")
m.class
答案 3 :(得分:1)
方法不是Ruby中的对象,因此它们没有类。您可以使用反射来获取表示方法的代理对象,但在这种情况下,类将是Method
或UnboundMethod
,具体取决于方法是否绑定到接收方对象。