【发布时间】:2011-01-02 17:29:13
【问题描述】:
在为方法使用命名参数时,我发现自己经常在 Ruby 中编写我认为不必要的代码。
以下面的代码为例:
def my_method(args)
orange = args[:orange]
lemon = args[:lemon]
grapefruit = args[:grapefruit]
# code that uses
# orange, lemon & grapefruit in this format which is way prettier & concise than
# args[:orange] args[:lemon] args[:grapefruit]
puts "my_method variables: #{orange}, #{lemon}, #{grapefruit}"
end
my_method :orange => "Orange", :grapefruit => "Grapefruit"
我真正不喜欢这段代码的地方在于,我不得不接受 args 并将值传递到局部变量中,这违反了 DRY 原则,而且通常会占用我的方法中的空间。如果我不使用局部变量,而只使用 args[:symbol] 语法引用所有变量,那么代码就会变得有些难以辨认。
我已尝试为此制定解决方案,但一直碰壁,因为我不知道如何在方法范围内使用 eval 或使用任何其他技术来定义局部变量。这是下面的许多尝试之一,这会导致错误
def my_method_with_eval(args)
method_binding = binding
%w{ orange lemon grapefruit}.each { |variable| eval "#{variable} = args[:#{variable}]", method_binding; }
# code that uses
# orange, lemon & grapefruit in this format which is way prettier & concise than
# args[:orange] args[:lemon] args[:grapefruit]
puts "my_method_with_eval variables: #{orange}, #{lemon}, #{grapefruit}"
end
my_method_with_eval :orange => "Orange", :grapefruit => "Grapefruit"
运行该代码时,我只是得到
NameError: undefined local variable or method ‘orange’ for main:Object method my_method_with_eval in named_args_to_local_vars at line at top level in named_args_to_local_vars at line 9
任何人都知道如何以某种方式简化它,这样我就不必使用大量的 var=args[:var] 代码来启动我的命名参数方法?
【问题讨论】:
-
听起来你真正想要的是命名参数。这些存在于 Ruby 2.0 中。