简单的Ruby编程,得到错误,不明白为什么,

时间:2014-04-01 21:30:58

标签: ruby tree

我在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", "!"]

2 个答案:

答案 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;错误。