Как получить доступ к функциям переменной экземпляра класса в другом классе?

#ruby #irb

Вопрос:

Возьмем, к примеру, это:

 class Inner
    attr_accessor :id, :number
    def initialize(id, number)
      @id                    = id
      @number                = number
    end
    def id()
      return @id   "_" @number
    end
end

class Outer
    attr_accessor :id, :inner, :another
    def initialize(id, inner, another)
      @id                    = id
      @inner                 = inner # instance variable for class Inner object
      @another               = another
    end
    def id()
      return "Outer id:n"
        @id   "nInner : "   @inner.id()  "nAnother: "   @another   "n"
    end
end
 

Когда я вызываю функцию id () «Внешнего» объекта, вывод останавливается на «nInner : «. Как мне это обойти? Спасибо.

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

1. Вы уверены, что » вывод заканчивается на «nInner : «»? Я бы поспорил, что вывод теперь останавливается на «Внешнем идентификаторе:» (потому что вы возвращаетесь из метода в этой строке, а следующий никогда не оценивается)

2. Я думаю, что вам может не хватать a в возврате метода внутреннего идентификатора -> return @id "_" @number

3. @Talkaboutnostalgia : Поместите скобки вокруг возвращаемого выражения.

4. @KonstantinStrukov На самом деле, то, что вы сказали, происходит. Кроме того, некоторым классам, таким как «Внутренний», удается вернуть запрошенную строку идентификатора, в то время как другие этого не делают. Я не могу найти разницы между ними.

Ответ №1:

Вы должны добавить в строку 8 a , а также привести целое значение к строке с to_s

 return @id.to_s   "_"   @number.to_s
 

В строке 20 не должно быть разрыва строки, просто поместите все в конце return концов в одну строку. Существует также та же проблема, что и в строке 8. Вы должны привести целое число с .to_s к строке или поместить "#{}" их вокруг них.

 return "Outer id:n"   "#{@id}"   "nInner : "   "#{@inner.id}"  "nAnother: "   "#{@another}"  "n"
 

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

1. Спасибо вам за вашу помощь. До сих пор это все еще не работает. Я выясню, сколько деталей я могу добавить к этому вопросу, как только поговорю с коллегами.

Ответ №2:

Перепишите код для более идиоматичного ruby:

 class Inner
  attr_accessor :id, :number

  def initialize(id, number)
    @id = id
    @number = number
  end

  def to_s
    "#{id}_#{number}"
  end
end

class Outer
  attr_accessor :id, :inner, :another
  def initialize(id, inner, another)
    @id = id
    @inner = inner # instance variable for class Inner object
    @another = another
  end

  def to_s
    <<~STR
      Outer id:#{id}
      Inner : #{inner}
      Another: #{another}
    STR
   # Or something like
   # [
   #   "Outer id:#{id}", 
   #   "Inner : #{inner}", 
   #   "Another: #{another}",
   # ].join("n")   "n"
  end
end
 

Соответствующий стилистический справочник

  1. Предпочтительнее "#{var}" '' var '' для интерполяции строк автоматически приводить переменные в виде строк.
  2. Не используйте явное return без необходимости.
  3. Предпочитайте heredoc для многострочных строк (или других шаблонов).
  4. Не определяйте, а attr_acessor затем переопределяйте метод в классе. Как правило, я бы избегал определения геттера, который не возвращает сохраненную переменную. Похоже, вам нужно «строковое» представление класса, что обычно делается с to_s помощью метода.
  5. Предпочитайте методы экземпляра, а не ивары.**

** Это, вероятно, более личное предпочтение, но я нахожу код с ivars менее рефакторируемым, чем код, использующий методы доступа (поскольку код работает одинаково, независимо от того, является ли он аргументом метода, методом экземпляра или локальной переменной)

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

1. Спасибо вам за вашу помощь. До сих пор это все еще не работает. Я выясню, сколько деталей я могу добавить к этому вопросу, как только поговорю с коллегами.