在Ruby中帮助lambdas

时间:2009-12-31 20:47:58

标签: ruby lambda

我是Ruby的新手,我正在尝试将sort_by lambda传递给格式方法,如下所示:

sort_by_methods = [ lambda {|l, r| compare_by_gender_then_last_name(l, r)}, 
                    lambda {|l, r| compare_by_something_else(l, r)}, 
                    lambda {|l, r| compare_by_another(l, r)}]

formatted_output = ""
sort_by_methods.each do |sort_by|
   formatted_output << formatter.format(students) { sort_by }
end

格式方法代码类似于:

def format(students, &sort_by)
   sorted_students = students.sort { |l, r| sort_by.call(l, r) } // error from this line
   sorted_students.each { |s| result << s.to_s << "\n" }
end

出于某种原因,我收到了关于上述格式方法代码(students.sort .....)中的行的翻译投诉: “在sort': undefined method&gt;' for#(NoMethodError)“

我做错了什么?我假设我已经搞乱了传递lambdas的语法,但无法弄清楚如何。

感谢。

2 个答案:

答案 0 :(得分:3)

问题出在这一行:

formatted_output << formatter.format(students) { sort_by }
使用不接受任何参数的块调用

format(),并返回+ sort_by +块。这就是为什么以后sort_by.call(l,r)会不及格。该块不接受任何参数。

如果你改变它,它应该有效:

formatted_output << formatter.format(students, &sort_by)

特别&amp;语法表示sort_by是一个块,它以{}表示法传递。

答案 1 :(得分:2)

首先,如果这不起作用,我道歉。我没有方便的Ruby解释器。

将lambda作为参数传递可能更好:

def format(students, sort_method)
    sorted_students = students.sort { |l, r| sort_method.call(l,r) }
    sorted_students.each { |s| result << s.to_s << "\n" }
end

否则,您将不得不向块添加参数,然后屈服于该块。电话会是这样的:

formatted_output << formatter.format(students) { |l, r| sort_by(l, r) }

定义如下:

def format(students)
    sorted_students = students.sort { |l, r| yield(l, r) }
    sorted_students.each { |s| result << s.to_s << "\n" }
end

第一个解决方案对我来说似乎更清晰。第二个使用隐式块。显式块会使它更清晰。