【问题标题】:Is it possible to redefine 0 in ruby?是否可以在 ruby​​ 中重新定义 0?
【发布时间】:2014-09-24 20:36:56
【问题描述】:

如果它确实有效,我实际上不会在任何事情上使用它,但是是否可以重新定义 0 以在 Ruby 中充当 1,而将 1 重新定义为 0? FixNum 的实际价值在哪里?

【问题讨论】:

  • 我很确定解析器会处理数字文字,因为你不能def 0

标签: ruby monkeypatching fixnum


【解决方案1】:

不,我不这么认为。如果你能做到,我会非常惊讶。如果您开始覆盖 Fixnum 的方法/运算符,您可能会接近它(即覆盖 + 以便 1+5 => 5、0+5 => 6 等),但您不会完全替换文字 '0'值 1。至少编组为原生会暴露 Fixnum(0) 的真正 0 值。

说实话,我不确定你是否可以覆盖像 + 这样的核心操作在 Fixnum 上的操作。这可能会破坏很多东西..

据我所记得的 1.8.3 源代码,简单的整数和双精度数都保存在一个“值”内,并在 *) 周围复制。没有单数的“0”、“1”或“1000”值。没有额外的取消引用可以让您一次性交换所有值。我怀疑它在 1.9 中发生了变化,我怀疑有人在 2.0 中对此有任何奇怪的想法。但我其实不知道。不过,那会很奇怪。没有平台我知道实习生整数和浮点数.. 字符串,有时是数组文字,但数字?

所以,抱歉,没有 #define true false 笑话 :)

--

*) 来自 Jörg W Mittag 的澄清(谢谢,这正是我所指的):

(..) Fixnums 在内存中没有位置,它们的指针值是“神奇的”(因为它不可能出现在 Ruby 程序中)并由运行时系统进行特殊处理。阅读“标记指针表示”,e.g. here

【讨论】:

    【解决方案2】:

    Assignment 不对 Fixnum 对象起别名。对于任何给定的整数值,实际上只有一个 Fixnum 对象实例,因此,例如,您不能将单例方法添加到 Fixnum。任何将单例方法添加到 Fixnum 对象的尝试都会引发 TypeError。 Source

    这几乎意味着您无法编辑 Fixnum,因此无法在原生 ruby​​ 中重新定义 01

    虽然这些 Fixnum 也是对象,但它们具有唯一的对象 ID,可以清楚地在内存中的某个位置引用它们。见BasicObject#__id__

    如果您可以找到 01 对象所在的内存空间并切换它们,那么您应该在 ruby​​ 中有效地切换 01 行为,因为现在任何一个都将引用另一个对象。

    所以回答你的问题:在 Ruby 中不可能重新定义 Fixnums,但应该可以切换它们的行为。

    【讨论】:

    • 实际上,在 MRI、YARV、Rubinius、MRuby、MacRuby 和其他可能的情况下,Fixnums 在内存中没有位置,它们的指针值是“神奇的”(因为它不可能发生在 Ruby 程序中)并由运行时系统进行特殊处理。阅读“标记指针表示”,例如here.
    • @JörgWMittag:谢谢,这比我想出的“在‘价值’内部”更好地描述了机制。我允许自己将您的评论纳入文本中,希望您不要介意。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-01-30
    • 1970-01-01
    • 2010-12-14
    • 2014-04-05
    • 2011-06-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多