我在Ruby编程方面非常新,我花了很多时间在这个程序上,但我发现我不理解我得到的错误,
如果您可以帮助找到错误并可能修复它,那将会很棒。
谢谢。
Here is the complete description of program and actual code:
错误:
C:/Users/Amir-i7/Dropbox/CS431/hwk9/hwk9.rb:148:in `+': no implicit conversion of Array into String (TypeError)
from C:/Users/Amir-i7/Dropbox/CS431/hwk9/hwk9.rb:148:in `test_tree'
from C:/Users/Amir-i7/Dropbox/CS431/hwk9/hwk9.rb:152:in `<main>'
代码:
module TreeEnum
def any? f
s = false
self.iterate(f).each do |child|
s = s || child.iterate(f) end
s
end
def inject(f,c)
z = lambda {|data| f.call(data,c)}
iterate z
end
end
class Leaf
def initialize s
@data = s
end
def concatAll
@data
end
def firstAlphabetical
@data
end
def iterate(itr)
itr.call(@data)
end
end
class BinaryNode
include TreeEnum
def initialize (left, right)
@left = left
@right = right
end
def concatAll
@left.concatAll + @right.concatAll
end
# not part of the homework
def BinaryNode.firstAlphabetical (s1, s2)
if s1.casecmp(s2) < 0 then s1 else s2 end
end
def firstAlphabetical
s1 = @left.firstAlphabetical
s2 = @right.firstAlphabetical
if s1.casecmp(s2) < 0 then s1 else s2 end
end
def iterate itr
@left.iterate itr
@right.iterate itr
end
def BinaryNode.concatAll tree
s = "";
tree.iterate(lambda { |data| s = s + data })
s
end
end
class NaryNode
include TreeEnum
def initialize childArray
@childArray = childArray.clone
end
def iterate itr
# use the "each" method of array to pass "itr" to the iterate method of each element in @childArray
@childArray.each do |child|
child.iterate itr
end
end
def concatAll
# use the "inject" method of array to concatenate the strings of each node in @childArray
s = ""
@childArray.each do |child|
s = s + child.concatAll
end
s
end
def firstAlphabetical
# use the "inject" method of array to retrieve the smallest string of the nodes in @childArray
@childArray.inject(@childArray[0]) {|first, node| if first.firstAlphabetical.casecmp(node.firstAlphabetical) < 0 then first.firstAlphabetical else node.firstAlphabetical end}
end
end
class String
def iterate itr
itr.call(self)
end
def concatAll
self
end
def firstAlphabetical
self
end
end
def test_print t2
puts "t2.concatAll: " + t2.concatAll.to_s
puts
puts "t2.firstAlphabetical: " + t2.firstAlphabetical.to_s
puts
puts "t2.iterate(lambda { |s| puts s }):"
t2.iterate(lambda { |s| puts s })
end
def test_tree
l0 = Leaf.new "What "
l1 = Leaf.new "a "
l2 = Leaf.new "great "
l3 = Leaf.new "day"
l4 = Leaf.new "!"
t0 = BinaryNode.new(l0,l1)
t1 = BinaryNode.new(t0,l2)
t2 = NaryNode.new([t1,l3,l4])
test_print t2
puts "\nThe following works after question 2\n\n"
t2 = NaryNode.new([t1, "day", "!"])
test_print t2
puts "\nThe following works after question 3\n\n"
puts "any word starting with `great': " + t2.any?(lambda {|x| x.start_with?("great")}).to_s
puts
puts "capitalize: " + t2.inject((lambda {|acc, elm| acc + elm.capitalize + " "}), "")
end
test_tree
我已经尝试用
替换第148行puts "capitalize: " + t2.inject((lambda {|acc, elm| acc + elm.capitalize + " "}), "").to_s
但我明白了:
capitalize: [#<BinaryNode:0x00000002ce5958 @left=#<BinaryNode:0x00000002ce5980 @left=#<Leaf:0x00000002ce5ae8 @data="What ">, @right=#<Leaf:0x00000002ce5a98 @data="a ">>, @right=#<Leaf:0x00000002ce5a48 @data="great ">>, "day", "!"]
答案 0 :(得分:2)
问题出在第148行:
puts "capitalize: " + t2.inject((lambda {|acc, elm| acc + elm.capitalize + " "}), "")
您正在尝试使用字符串连接数组,并且使用+
会抛出错误,除非您像这样调用数组上的to_s
:
puts "capitalize: " + t2.inject((lambda {|acc, elm| acc + elm.capitalize + " "}), "").to_s
否则你可以使用Ruby的字符串插值(隐式地对对象调用to_s
):
puts "capitalize: #{t2.inject((lambda {|acc, elm| acc + elm.capitalize + " "}), "")}"
这将解决您的错误,如果您还有其他问题,我会尝试在评论中回答这些问题。
快乐的编码!
答案 1 :(得分:1)
我相信diego.greyrobot回答了有关您遇到的特定错误的问题:您应该确保您运行方法的变量属于您的方法可以接受的类。我有一些额外的建议,以便您更容易找到您的变量返回的类。
有时很难知道变量的类是什么。例如:
x = [1, 2, 3]
y = [4, 5, 6]
x << y #=> [1, 2, 3, [4, 5, 6]]
z = x[1] + x[3]
在上面的示例中,您可能会认为x将变为[1,2,3,4,5,6]。但是,由于&lt;&lt;操作员抓住它上面的任何东西而不考虑它放在哪里,你得到[1,2,3,[4,5,6]]
如果你投入:
puts x[3].class #=> Array
Ruby会告诉你变量是什么类,提醒你代码中的问题。这是一种方便的调试技术,当你得到那些&#34;转换&#34;错误。