我正在阅读一本关于Ruby的书,我收到一个奇怪的错误,如果有人能为我解决这个问题会很高兴。
我正在寻找Ruby中的集合(非常基础)
file:song_list.rb
class Song
attr_accessor :name
attr_accessor :artist
attr_accessor :duration
def initialize(name, artist, duration)
@name = name
@artist = artist
@duration = duration
end
def to_s
"SongIs - #{@name} - #{@artist} - #{@duration}"
end
end
class SongList
def initialize
@songs = Array.new
end
def append(song)
@songs.push(song)
end
def delete_first
@songs.shift
end
def delete_last
@songs.pop
end
def [](index)
@songs[index]
end
end
然后我写了一个测试:test_unit.rb
require_relative 'song_list'
require 'test/unit'
class TestSongList < Test::Unit::TestCase
def test_delete
list = SongList.new
s1 = Song.new('title1', 'artist1', 1)
s2 = Song.new('title2', 'artist2', 2)
s3 = Song.new('title3', 'artist3', 3)
s4 = Song.new('title4', 'artist4', 3)
list.append(s1).append(s2).append(s3).append(s4)
assert_equal(s1, list[0])
assert_equal(s2, list[1]);
assert_equal(s3, list[2]);
assert_equal(s4, list[3]);
assert_nil(list[9])
assert_equal(s1, list.delete_first)
assert_equal(s2, list.delete_first)
assert_equal(s4, list.delete_last)
assert_equal(s3, list.delete_last)
assert_nil(list.delete_last)
end
end
现在,当我运行第二个文件ruby test_unit.rb
时,出现错误。错误说我还没有在RubyList类中定义函数append
。
但我有,不是吗?这是错误。
Run options:
# Running tests:
[1/1] TestSongList#test_delete = 0.00 s
1) Error:
test_delete(TestSongList):
NoMethodError: undefined method `append' for #<Array:0x9f52b30>
test_unit.rb:11:in `test_delete'
/home/ziyan/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/minitest/unit.rb:1301:in `run'
/home/ziyan/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/test/unit/testcase.rb:17:in `run'
/home/ziyan/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/minitest/unit.rb:919:in `block in _run_suite'
/home/ziyan/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/minitest/unit.rb:912:in `map'
/home/ziyan/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/minitest/unit.rb:912:in `_run_suite'
/home/ziyan/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/test/unit.rb:657:in `block in _run_suites'
/home/ziyan/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/test/unit.rb:655:in `each'
/home/ziyan/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/test/unit.rb:655:in `_run_suites'
/home/ziyan/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/minitest/unit.rb:867:in `_run_anything'
/home/ziyan/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/minitest/unit.rb:1060:in `run_tests'
/home/ziyan/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/minitest/unit.rb:1047:in `block in _run'
/home/ziyan/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/minitest/unit.rb:1046:in `each'
/home/ziyan/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/minitest/unit.rb:1046:in `_run'
/home/ziyan/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/minitest/unit.rb:1035:in `run'
/home/ziyan/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/test/unit.rb:21:in `run'
/home/ziyan/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/test/unit.rb:774:in `run'
/home/ziyan/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/test/unit.rb:366:in `block (2 levels) in autorun'
/home/ziyan/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/test/unit.rb:27:in `run_once'
/home/ziyan/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/test/unit.rb:365:in `block in autorun'
Finished tests in 0.004259s, 234.8127 tests/s, 0.0000 assertions/s.
1 tests, 0 assertions, 0 failures, 1 errors, 0 skips
如果你能告诉我为什么会这样,我会很高兴。
答案 0 :(得分:6)
您已在append
上定义SongList
,但尚未在Array
上对其进行定义。您的append
来电是问题所在:
list.append(s1).append(s2).append(s3).append(s4)
如果您想链接这样的方法调用,则需要将SongList#append
方法调整为:
def append(song)
@songs.push(song)
self
end
同样适合您的其他方法。或者,将初始呼叫更改为:
list.append(s1)
list.append(s2)
list.append(s3)
list.append(s4)
或使用循环:
[s1, s2, s3, s4].each{|s| list.append(s)}
错误的原因是因为没有显式return
调用的ruby方法将返回方法最后一行的值。在您的情况下,这是@songs.push(song)
,@songs
是一个数组,Array#push
返回一个数组,因此您的append
方法返回一个数组。链中的第二个调用尝试在第一个调用返回的数组上调用append
并触发异常。