使用成语时,例如:

def func(*args)
  # some code
end

*args是什么意思?在谷歌上搜索这个特定的问题相当困难,我什么也找不到.

似乎所有的论点都出现在args[0]中,所以我发现自己在写防御代码,比如:

my_var = args[0].delete(:var_name) if args[0]

但我相信我错过了一个更好的方法.

推荐答案

*splat(或星号)运算符.在方法的上下文中,它指定一个可变长度的参数列表.在您的例子中,传递给func的所有参数都将被放入一个名为args的数组中.也可以在可变长度参数之前指定特定参数,如下所示:

def func2(arg1, arg2, *other_args)
  # ...
end

假设我们称这种方法为:

func2(1, 2, 3, 4, 5)

如果您现在在func2范围内判断arg1arg2other_args,您将得到以下结果:

def func2(arg1, arg2, *other_args)
  p arg1.inspect       # => 1
  p arg2.inspect       # => 2
  p other_args.inspect # => [3, 4, 5]
end

在你的例子中,你似乎把一个散列作为参数传递给你的func,在这种情况下,正如你所观察到的,args[0]将包含散列.

资源:


Update based on OP's comments

如果要将散列作为参数传递,则不应使用splat运算符.Ruby允许在方法调用中省略方括号including those that specify a Hash(注意,请继续阅读).因此:

my_func arg1, arg2, :html_arg => value, :html_arg2 => value2

相当于

my_func(arg1, arg2, {:html_arg => value, :html_arg2 => value2})

当Ruby在参数列表中看到=>运算符时,它知道将参数作为散列,即使没有明确的{...}符号(注意,这只适用于散列参数是最后一个的情况!).

如果要收集此散列,不需要做任何特殊的操作(尽管可能需要在方法定义中指定一个空散列作为默认值):

def my_func(arg1, arg2, html_args = {})
  # ...
end

Ruby相关问答推荐

Ruby ERB 类给出未定义的局部变量或方法,但 erb 解析良好

环绕分隔线,保留第一列,最小最终长度

在 Ruby 中,如何编写一个可以与 &:symbol 一起使用的简单方法?

ruby:rubocop 抱怨将 if else 转换为 case 语句

Ruby 的 .() 运算符是如何工作的?

.nil?、.blank? 之间的区别?和.empty?

我可以在 Ruby 的 heredoc 中访问变量吗?

如何修改 Ruby gem

在 Ruby 中导出环境变量

使用 Ruby MiniTest 之前/之后的套件

将 2 元素数组的数组转换为哈希,其中重复键附加附加值

Ruby 运算符优先级表

与 String 相比,在 Ruby 中使用 StringIO 有哪些优势?

Ruby 将标题发布到 slug

如何使用密码保护我的 /sidekiq 路由(即需要对 Sidekiq::Web 工具进行身份验证)?

如何在 Ruby 中编写复杂的多行 if 条件?

如何在没有警告的情况下重新定义 Ruby 常量?

为什么 Ruby 文档中的方法前面有一个井号?

将整个文本文件作为单个字符串读取的合理方法是什么?

Ruby 中的 to_s 与 to_str(以及 to_i/to_a/to_h 与 to_int/to_ary/to_hash)