问题
I've got a small program meant to be run in IRB. It ultimately outputs something that looks like an array, though technically isn't an array. (The class inherits from array.) The problem is, when I do an instance of this class, e.g. example = Awesome.new(1,2,3), and I write "puts example", IRB's default behavior is to put each element of example onto it's own line.
So instead of
[1,2,3]
(which is what I want), IRB pops out this.
1
2
3
Is there a smart way to override the puts method for this special class? I tried this, but it didn't work.
def puts
self.to_a
end
Any idea what I'm doing wrong?
Update: So I tried this, but no success.
def to_s
return self
end
So when I'm in IRB and I just type "example", I get the behavior I'm looking for (i.e. [1, 2, 3]. So I figured I could just to return self, but I'm still messing up something, apparently. What am I not understanding?
回答1:
def puts(o)
if o.is_a? Array
super(o.to_s)
else
super(o)
end
end
puts [1,2,3] # => [1, 2, 3]
or just use p
:
p [1, 2, 3] # => [1, 2, 3]
回答2:
You should override to_s
and it will be handled automatically, just remember to return a string from to_s
and it will work as a charm.
Example snippet..
class Obj
def initialize(a,b)
@val1 = a
@val2 = b
end
def to_s
"val1: #@val1\n" +
"val2: #@val2\n"
end
end
puts Obj.new(123,321);
val1: 123
val2: 321
回答3:
You probably would be better off implementing to_ary
method for your Array-like class. This method will be called by puts
to obtain all the elements. I posted a snippet from one of my projects below
require 'forwardable'
class Path
extend Forwardable
def_delegators :@list, :<<, :count, :include?, :last, :each_with_index, :map
def initialize(list = [])
@list = list
end
def to_ary
self.map.each_with_index{ |e, i| "#{e}, step: #{i}" }
end
end
来源:https://stackoverflow.com/questions/11463873/ruby-overriding-the-puts-method