0

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.

4
  • 2
    Are you sure 'output stops at "\nInner : "' ? I'd bet output now stops at "Outer id:" (because you return from the method on this line and the next one is never evaluated) Commented Sep 2, 2021 at 22:18
  • 1
    I think you may be missing a + in the Inner's id method's return -> return @id + "_" + @number Commented Sep 2, 2021 at 22:32
  • @Talkaboutnostalgia : Place parenthesis around the expression to be returned. Commented Sep 3, 2021 at 6:49
  • @KonstantinStrukov Actually, what you said is happening. And also, some classes like "Inner" manage to return the requested ID string, while others don't. I'm not able to find a difference between them. Commented Sep 8, 2021 at 19:06

2 Answers 2

1

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"
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for your help. So far, it's still not working. I'll find out how much detail I can add to the question once I speak to coworkers.
0

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)

1 Comment

Thank you for your help. So far, it's still not working. I'll find out how much detail I can add to the question once I speak to coworkers.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.