Talk about nostalgia
Talk about nostalgia

Reputation: 11

How do I access functions of an instance variable of a class, within another class?

Take this for example:

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

When I call the id() function of an "Outer" object, the output stops at "\nInner : ". How do I get around this? Thank you.

Upvotes: 0

Views: 73

Answers (2)

melcher
melcher

Reputation: 1601

Rewrite of the code for more idiomatic 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

Relevant styleguide

  1. Prefer "#{var}" over '' + var + '' for string interpolation to automatically cast variables as strings.
  2. Don't use explicit return unless needed.
  3. Prefer heredoc for multi-line strings (or other patterns).
  4. Don't define an attr_acessor then redefine the method in the class. Generally I'd avoid defining a getter that doesn't return the stored variable. It looks like you want to a "stringified" representation of the class, which is commonly done with a to_s method.
  5. Prefer instance methods over ivars.**

** This is probably more personal preference, but I find code with ivars as less refactorable than code that uses the accessor methods (since the code works the same whether it's a method argument or instance method or local variable)

Upvotes: 0

nwnoll
nwnoll

Reputation: 136

You should add on line 8 a + and also cast the integer value to a string with to_s

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

On line 20 shouldn't be a line break, just put everything after return all on one line. There is also the same issue as it was on line 8. You have to cast the integer with .to_s to a string or put "#{}" around them.

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

Upvotes: 1

Related Questions