2014-04-01 47 views
0

我很新的Ruby编程,我花了很多时间在这个程序,但我来到一个点,我不明白我错了, m得到,简单的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 

我已经尝试过用

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

这将是很高兴知道什么在行148.无论如何,看起来像你试图连接一个数组与字符串... – aldux

+0

如果你能提供帮助和可能的解决方案,那将是非常好的,记住我不能改变测试部分。 –

+0

这是两个不同的问题,你想如何解决后者? – DiegoSalazar

回答

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 + " "}), "")}" 

这将解决您的错误,如果你有任何问题,我会尽量回答他们的意见。

编码愉快!

+0

感谢您的解决方案,没有工作,我得到:大写:[#,@ right =# >,@right =#>,“day”,“!”] –

+1

我敢打赌你不会再犯错, 对?这看起来像是有效的,但不是你想要的输出。你必须自己去努力;) – DiegoSalazar

+1

我知道你急着做家庭作业,但在你弄乱lambda函数之前弄清楚基本知识是个好主意...... – aldux

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]。然而,由于无论在它的左批发,而不考虑它的推杆它的< <运营商争夺,你得到[1,2,3,[4,5,6]

如果你在扔:

puts x[3].class #=> Array 

Ruby会告诉你你的变量是什么类,提醒你代码中的问题。这是一种非常方便的调试技术,可以在出现这些“转换”错误时正常工作。

相关问题