Почему числа не поддерживают .dup?

>> a = 5
=> 5
>> b = "hello, world!"
=> "hello, world!"
>> b.dup
=> "hello, world!"
>> a.dup
TypeError: can't dup Fixnum
    from (irb):4:in `dup'
    from (irb):4

Я понимаю, что Ruby сделает копию каждым разом, когда Вы присваиваете целое число новой переменной, но почему делает Numeric#dup повысить ошибку?

Не был бы эта абстракция повреждения, так как все объекты, как должны ожидать, ответят на .dup правильно?

Перезапись dup метод решит проблему, насколько я могу сказать:

>> class Numeric
>>   def dup()
>>     self
>>   end
>> end

Это имеет оборотную сторону, которую я не вижу? Почему это не встроено в Ruby?

7
задан Jeffrey Aylesworth 26 December 2009 в 19:28
поделиться

2 ответа

Большинство объектов в Рубине передаются по ссылке и могут быть отброшены. Eg:

s = "Hello"
t = s      # s & t reference to the same string
t.upcase!  # modifying either one will affect the other
s # ==> "HELLO"

Несколько объектов в Ruby являются немедленными. Они передаются по значению, может быть только одно из этих значений и поэтому не могут быть обработаны. Это любые (маленькие) целые числа, true, false, символы и nil. На 64-битных системах многие флоты также являются непосредственными в Ruby 2.0.

В этом (нелепым) примере любая "42" будет содержать одну и ту же переменную экземпляра.

class Fixnum
  attr_accessor :name
  alias_method :original_to_s, :to_s
  def to_s
    name || original_to_s
  end
end
42.name = "The Answer"
puts *41..43  # =>  41, The Answer, 43

Так как вы обычно ожидаете, что something.dup.name = "новое имя" не повлияет ни на какой другой объект, кроме копии, полученной с помощью dup, Ruby решает не определять dup на непосредственных числах.

Ваш вопрос сложнее, чем кажется на первый взгляд. Было некоторое обсуждение по поводу рубинового ядра о том, как это можно сделать проще. Также, другие типы числовых объектов (плавающие, бинумы, нормированные и комплексные числа) нельзя дублировать, хотя они и не являются мгновенными.

Обратите внимание, что ActiveSupport (часть рельсов) предоставляет метод дублируемый? на всех объектах

.
15
ответ дан 6 December 2019 в 10:50
поделиться

Проблема с функцией dup(), которую вы определили, заключается в том, что она не возвращает копию объекта, а возвращает сам объект. Это не то, что должна делать процедура dup().

Я не знаю Руби, но возможная причина, по которой dup не определено для чисел, заключается в том, что число является базовым типом и, таким образом, делая что-то вроде:

>> a = 5
>> b = a

автоматически присваивает значение 5 переменной b, в отличие от того, чтобы b и a указывали на одно и то же значение в памяти.

3
ответ дан 6 December 2019 в 10:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: