Как вы клонируете атрибуты объекта суперкласса в Ruby?

#ruby #subclass

#ruby #подкласс

Вопрос:

Допустим, у меня есть подкласс Sub класса Super и экземпляр Super с именем super . Как мне создать новый экземпляр Sub, который автоматически клонирует все свойства super (и включает дополнительные свойства Sub)? В качестве альтернативы, могу ли я создать новый экземпляр Super, а затем изменить его класс на Sub?

Подробнее:

Значение класса < Строка

 attr_accessor ...fields...

def initialize(name, ...fields...)
    ...sets fields...
    super(name)
end

def ...methods...
end
 

конец

class Extracted_Value

 attr_accessor ...more fields...

def initialize(???)
    ???
end
 

конец

У меня есть куча разных экземпляров Value , и для каждого из них бывают случаи, когда я могу успешно выполнить извлечение из высказывания, что означает создание нового Extracted_Value, который содержит информацию о том, как произошло извлечение, но все из Value должно быть клонировано.

Мой другой вариант — попытаться создать какой-то класс-оболочку вместо подкласса?

Комментарии:

1. Вы пробовали что-нибудь до сих пор? Также: каков ваш реальный вариант использования для этого?

2. Есть способы сделать это, но очень сложно узнать правильный способ, не зная, как / почему вы хотите это сделать.

Ответ №1:

 class A
 attr_accessor :a1, :a2

 def initialize param1, param2  
   @a1 = param1
   @a2 = param2
 end  
end

class B < A 
  attr_accessor :b1
end
 

Когда вы создаете экземпляр класса B, вы можете вызывать как a1, так и a2 из (супер) класса, а также вызывать b1 . Вы можете объединить в методе инициализации подкласса параметры, которые вы хотите установить и т.д…

 b = B.new "foo", 3
puts b.a1 # "foo"
puts b.a2 # 3
 

Надеюсь, это то, что вы хотели?

Комментарии:

1. Продолжая ваш пример: скажем, у нас уже есть a = A.новый «foo», 3 и мы вносим изменения в a с течением времени, например a.foo = «blah» Я хочу клонировать столько, сколько смогу, при создании b. Просто вызов инициализации A не сделает этого, он не будетне сохраняйте «бла»

Ответ №2:

Вы опасно приближаетесь к земле переменных класса, и все проблемы, с которыми вы сталкиваетесь, разделяют переменные между несколькими экземплярами объектов. Это почти всегда плохие новости.

Если у вас есть два объекта с одинаковыми свойствами, но разными значениями атрибутов, это должны быть два экземпляра одного и того же класса, который определяет свойства, а не два отдельных класса.

Вместо того, чтобы пытаться создать экземпляр другого класса, вы должны клонировать текущий экземпляр, чтобы получить новый экземпляр класса.

Поэтому ответ должен быть:

 sub = Sub.new 'foo', 3
sub_two = sub.clone
puts sub_two.a1 # 'foo'
 

Ключевым моментом является то, что при использовании clone новый экземпляр просто копирует атрибуты в новый экземпляр, но не разделяет атрибуты между двумя объектами. Итак, вы можете сделать это:

 sub.a1 = 'bar'
puts sub_two.a1 # 'foo'
puts sub.a1     # 'bar'
 

Комментарии:

1. Да, это отличное объяснение . Я думаю, что это вызывает параметры передачи по значению, не так ли?