Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 具有可选的第一个散列参数和关键字参数的奇数方法行为_Ruby_Hash_Optional Parameters_Keyword Argument - Fatal编程技术网

Ruby 具有可选的第一个散列参数和关键字参数的奇数方法行为

Ruby 具有可选的第一个散列参数和关键字参数的奇数方法行为,ruby,hash,optional-parameters,keyword-argument,Ruby,Hash,Optional Parameters,Keyword Argument,我有以下方法: def test(first_param = nil, keyword_arg: nil) puts "first_param: #{first_param}" puts "keyword_arg: #{keyword_arg}" end 以下所有调用都会执行我希望他们执行的操作: test(:something) #=> first_param: something # keyword_arg: test(nil, keyword_arg: :keywor

我有以下方法:

def test(first_param = nil, keyword_arg: nil)
  puts "first_param: #{first_param}"
  puts "keyword_arg: #{keyword_arg}"
end
以下所有调用都会执行我希望他们执行的操作:

test(:something)
#=> first_param: something
#   keyword_arg:

test(nil, keyword_arg: :keyword_arg)
#=> first_param:
#   keyword_arg: keyword_arg

test({ first_param: :is_a_hash }, keyword_arg: :is_still_working)
#=> first_param: {:first_param=>:is_a_hash}
#   keyword_arg: is_still_working
但是省略可选的
关键字_arg
并将哈希作为第一个参数传递给我会出现错误:

test(first_param: :is_a_hash)
#=> test.rb:1:in `test': unknown keyword: first_param (ArgumentError)
#           from test.rb:12:in `<main>'
这应该将
first_param
设置为
{keyword_arg::should_be_first_param}
,在我看来,留下
keyword_arg
为零

这是解析器错误还是预期行为?在ruby 2.3.0和2.2.4上测试


编辑:将第一个参数设置为强制参数,所有操作都与我期望的一样:

def test_mandatory(first_param, keyword_arg: nil)
  puts "first_param: #{first_param}"
  puts "keyword_arg: #{keyword_arg}"
end

test_mandatory(first_param: :is_a_hash)
#=> first_param: {:first_param=>:is_a_hash}
#   keyword_arg:

test_mandatory(keyword_arg: :should_be_first_param)
#=> first_param: {:keyword_arg=>:should_be_first_param}
#   keyword_arg:
我希望使参数成为可选参数不会改变参数的解析方式


我打开了一个,然后开发人员可以弄清楚它是打算这样做,还是kword args的副作用。

这是根据:

这种行为可能令人惊讶,但却是故意的

它归结为首先优先填充关键字参数 而不是填充未命名的参数。它实际上是唯一的 可能的方式。除其他事项外,请考虑以下事项 例如:

def foo(*rest, bar: 42)
end
如果我们不首先对命名的参数进行优先级排序,那么就没有了 在本例中,指定条形图值的方法

所以Ruby检查:

  • 在填充所有必需的未命名参数之后
  • 如果剩下的最后一个参数是类似散列的
  • 所有的钥匙都是符号
  • 调用的方法使用关键字参数
=>然后该参数用于关键字参数

请注意,键是符号的要求。这可以产生更多的收益 如果使用非符号的键传递哈希,则会令人惊讶:

def foo(a = nil, b: nil)
  p a, b
end
foo(:b  => 42) # => nil, 42
foo('b' => 42) # => {"b" => 42}, nil

“这应该将
first_-param
设置为
{keyword_-arg::should_-be_-first_-param}
,让
关键字_-arg
在我看来为零。”--为什么?你不认为它是不明确的吗?我只给这个方法一个参数。当它不是散列时,它设置第一个参数(
测试(:某物)
)。但是,如果参数是散列,它不会设置
first_param
,而是将散列解释为关键字参数。为什么行为取决于参数的类型?这是不合逻辑的(至少对我来说)。
def foo(a = nil, b: nil)
  p a, b
end
foo(:b  => 42) # => nil, 42
foo('b' => 42) # => {"b" => 42}, nil