Как передать переменную экземпляра / средства доступа в ruby другому классу и получить данные, сохраненные в соответствующей переменной?

#ruby-on-rails #ruby

#ruby-on-rails #ruby

Вопрос:

Ссылаясь на приведенный ниже код, есть ли способ, которым я могу передать переменную row из class A в class B#kick и получить сохраненные данные?

 class A
  attr_accessor :row

  def fetch
    B.new.kick(self.row)
    puts row.inspect
  end
end

class B
  def kick(x)
    x = [3,4]
  end
end

@test = A.new.fetch
expect(@test.row).to eql([3,4])
  

Текущая операционная система => nil

Однако, если я передам self и назначу, это сработает, но я не хочу использовать этот подход: Рабочий код

 class A
  attr_accessor :row

  def fetch
    B.new.kick(self)
    puts row.inspect
  end
end

class B
  def kick(x)
    x.row = [3,4]
  end
end

@test = A.new.fetch
#=> [3, 4]
  

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

1. Это ожидаемо, потому что случай 1 — это значение, а случай 2 — ссылка. Вы можете получить доступ к методам объекта, только ссылаясь на объект.

Ответ №1:

Краткая версия:
x = [3, 4] создаст новый экземпляр массива и сохранит в x переменной, где row по-прежнему будет ссылаться на исходное значение (или никакого значения nil ).

Другим подходом может быть kick метод возврата значения «kicked».

 class A
  def fetch
    @row = B.new.kick
    puts row.inspect
  end
end

class B
  def kick(x)
    [3,4]
  end
end
  

Если вы хотите следовать принципу объектно-ориентированного программирования «Скажи, не спрашивай», вы можете попробовать подход шаблона посетителя.

 class A
  def fetch
    B.new.kick(self)
    puts row.inspect
  end

  def save(row)
    @row = row
  end
end

class B
  def kick(x)
    x.save([3,4])
  end
end
  

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

1. Да, это работает нормально, но мой вариант использования примерно такой: что, если B.new.kick возникнет ошибка, я не получу никаких данных. Мой вариант использования заключается в том, что я хочу сохранить данные в массиве во время выполнения, даже если метод kick вызывает исключение, в котором у меня есть данные.

2. @SantoshMohanty, вы все равно не получите никаких данных, если в kick методе будет выдана ошибка.

3. @SantoshMohanty: если ваша версия B#kick выдает ошибку, программа также завершит работу.