2014-04-01 66 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會告訴你你的變量是什麼類,提醒你代碼中的問題。這是一種非常方便的調試技術,可以在出現這些「轉換」錯誤時正常工作。

相關問題