Можно ли переопределить 0 в рубине?
На самом деле я не собираюсь использовать это ни в чем, если это действительно работает, но возможно ли переопределить 0, чтобы он действовал как 1 в Ruby, а 1 - как 0? Где на самом деле FixNum хранит свое значение?
2 ответа
Нет, я так не думаю. Я был бы очень удивлен, если бы тебе удалось. Если вы начнете переопределять методы / операторы Fixnum, вы можете приблизиться к этому (например, переопределить +, чтобы 1+5 => 5, 0+5 => 6 и т. Д.), Но вы не получите полную замену литерала '0' на значение 1. По крайней мере, маршаллинг для native показал бы действительное значение 0 Fixnum(0).
Если честно, я не совсем уверен, сможете ли вы переопределить основные операции, такие как +
оп на Fixnum. Это может сломать так много вещей..
Насколько я помню из источника 1.8.3, простые целые и двойные числа хранятся прямо в "значении" и копируются вокруг *). Не существует единственного значения "0", "1" или "1000". Нет дополнительной разыменования, которая позволила бы вам поменять все значения одним выстрелом. Я сомневаюсь, что это изменилось в 1.9, и я сомневаюсь, что кто-то получил какое-то странное представление об этом в 2.0. Но я на самом деле не знаю. Тем не менее, это было бы странно. Нет платформы, которую я знаю, интерны целые и плавающие. Строки, иногда литералы массивов, но числа?
Так что, извините, нет #define true false
шутки:)
-
*) разъяснение от Йорг W Mittag (спасибо, это именно то, что я имел в виду):
(..) Fixnums не имеют места в памяти, их значение указателя является "магическим" (в том смысле, что это не может произойти в Ruby-программе) и обрабатывается специально системой времени выполнения. Читайте о "представлении тегированного указателя", например, здесь.
Назначение не псевдоним объектов Fixnum. Фактически существует только один экземпляр объекта Fixnum для любого заданного целочисленного значения, поэтому, например, вы не можете добавить одноэлементный метод к Fixnum. Любая попытка добавить одноэлементный метод к объекту Fixnum вызовет TypeError. Источник
Это в значительной степени означает, что вы не можете редактировать Fixnum и, следовательно, не переопределять 0
или же 1
в родном рубине.
Хотя эти Fixnum также являются объектами, они имеют уникальные идентификаторы объектов, которые четко ссылаются на них где-то в памяти. См. BasicObject#__id__
Если вы можете найти место в памяти, где 0
а также 1
объекты и переключать их, вы должны иметь эффективную коммутацию 0
а также 1
Поведение в ruby, как и сейчас, будет ссылаться на другой объект.
Итак, чтобы ответить на ваш вопрос: никакое переопределение Fixnums невозможно в Ruby, хотя переключение их поведения должно быть возможным.