我想基于Ruby数组为对象创建容器类。我想操纵这些容器中的多个容器,例如将2个连接在一起。如果我试试这个:
class Thing
attr_accessor :name
end
class Things
def initialize
@things = Array.new
end
def addone( a )
@things.push( a )
end
def append( list )
list.each { |i| addone( i ) }
end
end
item1 = Thing.new
item2 = Thing.new
item3 = Thing.new
item4 = Thing.new
item1.name = "Marty"
item2.name = "Fred"
item3.name = "Janice"
item4.name = "John"
list1 = Things.new
list1.addone( item1 )
list1.addone( item2 )
list2 = Things.new
list2.addone( item3 )
list2.addone( item4 )
list3 = Things.new
list3 = list2.append( list1 )
我收到错误:
在
append': undefined method
每个'对于#(NoMethodError)来自./test.rb:40:in`'
我尝试过不同的方法,比如创建一个看似想要的方法,但到目前为止还没有运气。有什么建议?并提前感谢!
答案 0 :(得分:2)
如果您希望能够将Things
添加到Things
,则您有两种能力:要么在Things
上实现迭代器方法,要么只是装饰包裹Array
:< / p>
def append(list)
case list
when Enumerable then list.each { |i| addone(i) }
when Things then list.instance_variable_get(:@things).each { |e| addone(i) }
else raise "Sorry, can’t add #{list}"
end
答案 1 :(得分:1)
我想应该有一个getter / setter方法:
attr_accessor :things
然后您应该更改addone
方法:
def append(list)
list.things.each { |i| addone( i ) } # iterate through array items, not Things instance object
self # return appended list object instead of unchanged provided argument – list1
end
list3.things
的输出:
=> [#<Context::Thing:0x00000001adea48 @name="Janice">,
#<Context::Thing:0x00000001ade9f8 @name="John">,
#<Context::Thing:0x00000001adea98 @name="Marty">,
#<Context::Thing:0x00000001adea70 @name="Fred">]
答案 2 :(得分:1)
考虑这种方法:
class Thing
attr_accessor :name
def initialize(name)
@name = name
end
end
class Things
def initialize(things = [])
@things = things
end
def push(thing)
@things.push(thing)
end
def append(other)
@things << other.to_a
end
def +(other)
Things.new(@things + other.to_a)
end
def to_a
@things
end
end
some_things = %w(Marty Fred Janice John).map { |name| Thing.new(name) }
things_1 = Things.new
some_things.first(2).each { |thing| things_1.push(thing) }
things_2 = Things.new
some_things.last(2).each { |thing| things_2.push(thing) }
things_1.append(things_2) # This actually appends to things_1 rather than creating a new object
new_things = things_1 + things_2 # Creates a new object
# => #<Things:0x007ff85a1aa770 @things=[
# #<Thing:0x007ff85a1aa928 @name="Marty">,
# #<Thing:0x007ff85a1aa900 @name="Fred">,
# #<Thing:0x007ff85a1aa8d8 @name="Janice">,
# #<Thing:0x007ff85a1aa8b0 @name="John">]>
备注:强>
+
。