传递哈希值而不是方法参数

rma*_*ski 78 ruby oop coding-style

我看到在Ruby(和动态类型语言,通常)中,一种非常常见的做法是传递散列,而不是声明具体的方法参数.例如,不是使用参数声明一个方法,而是像这样调用它:

def my_method(width, height, show_border)
my_method(400, 50, false)
Run Code Online (Sandbox Code Playgroud)

你可以这样做:

def my_method(options)
my_method({"width" => 400, "height" => 50, "show_border" => false})
Run Code Online (Sandbox Code Playgroud)

我想知道你对它的看法.这是好事还是坏事,我们应该这样做吗?在什么情况下使用这种做法是有效的,它有什么危险的情况?

MBO*_*MBO 40

Ruby有隐式哈希参数,所以你也可以写

def my_method(options = {}) 

my_method(:width => 400, :height => 50, :show_border => false)
Run Code Online (Sandbox Code Playgroud)

并且使用Ruby 1.9和新的哈希语法,它可以

my_method( width: 400, height: 50, show_border: false )
Run Code Online (Sandbox Code Playgroud)

当一个函数需要超过3-4个参数时,更容易看出哪个是什么,而不计算相应的位置.


ben*_*sky 27

这两种方法都有各自的优点和缺点,当您使用选项哈希替换标准参数时,您在定义方法的代码中会失去清晰度,但是在使用该方法时会因为使用选项哈希创建的伪命名参数而变得清晰.

我的一般规则是,如果你有一个方法(超过3或4个)或许多可选参数的许多参数,那么使用选项哈希否则使用标准参数.但是,在使用选项哈希时,始终在方法定义中包含描述可能参数的注释非常重要.


sar*_*dne 7

我会说,如果你是:

  1. 拥有6个以上的方法参数
  2. 传递具有一些必需的选项,一些是可选的,一些是默认值

你很可能想要使用哈希.如果不在文档中查找,就可以更容易地查看参数的含义.

对于那些说你很难确定方法采用什么选项的人来说,这只意味着代码记录很差.使用YARD,您可以使用@option标记指定选项:

##
# Create a box.
#
# @param [Hash] options The options hash.
# @option options [Numeric] :width The width of the box.
# @option options [Numeric] :height The height of the box.
# @option options [Boolean] :show_border (false) Whether to show a
#   border or not.
def create_box(options={})
  options[:show_border] ||= false
end
Run Code Online (Sandbox Code Playgroud)

但在那个具体的例子中,有这么几个简单的参数,所以我想我会这样做:

##
# Create a box.
#
# @param [Numeric] width The width of the box.
# @param [Numeric] height The height of the box.
# @param [Boolean] show_border Whether to show a border or not.
def create_box(width, height, show_border=false)
end
Run Code Online (Sandbox Code Playgroud)