结合隐式打字,我们经常会遇到这样的情况:
myVar= :asymbol
上述两行都创建一个新的符号对象,并将对象绑定到变量名myVar.
从语法上讲,怎么做?
我已经把它敲入了我的头,这个=操作符并不是解释器内置的魔术语法,而是实际上只是对象的句法糖.=(value)方法.
考虑到这一点,我最好的猜测是,当解释器看到我们正在尝试为一个未定义的变量名赋值时,它首先创建一个特殊类型的新对象,如未定义或null或者某些东西,然后传递: =该对象的消息,其中有效负载是我们尝试分配的值.
然而,在未实例化的对象上调用.class会抛出异常,因为Ruby认为我们正在尝试调用一个方法(其名称是您想要存在的变量的名称)
> obj.class > NameError: undefined variable or method 'obj' for main:Object
所以,据我所知,我无法通过实验弄清楚这一点.
边注:
在符号分配的情况下,我相信分配的值(AKA是实例化对象的object_id方法返回的值,在C级别为无符号长度VALUE变量的值的AKA)是表示某个表中的偏移量的数字(我相信这是Ruby如何实现符号对象的“即时价值”).
在其他情况下,该值可能是对象本身的直接编码,也可能是引用一个结构体来转换为指针的值.
无论如何,Ruby代表对象的方式,以及我们最终分配引用还是对象本身都不是我在此问的.
附加问题:
什么类是=继承的方法?我在Object或BasicObject的规格中找不到.
解决方法
记住变量就在这里,以便程序员可以通过名称而不是某种内部标识符或内存位置来引用对象.所以这里有一些“魔法”,=在做一个作业时是特别的,因为你可以在左边和右边做一些规则.
您可以将消息发送到某种东西(即方法调用)的唯一方法是,如果您以编译器了解的方式定义它. x = 1就足够了,这意味着x是指所讨论的Fixnum.
请注意,Ruby解释器将需要确定x是否指向变量或方法调用,因为x =可以是在对其进行评估的对象上下文中定义的方法.
例如:
class Example def x=(value) @x = value end def test # Equivalent to send(:x=,1) because x= is a method x = 1 # Is a variable definition because y= is not a method y = 2 # Is always a method call because self is referenced. self.x = 3 end end # Is a variable definition because x= is not defined in this context x = 4
你不能有一个:=消息,因为这意味着你可以用另一个替换一个对象,这是不允许的.一旦创建了一个对象,它就不能神奇地改变类型.为此,您需要创建一个不同对象的新实例.变量只显示改变类型,但实际上它们只是指向不同的对象.