-->

在Ruby中2命名参数(Named parameters in Ruby 2)

2019-07-21 05:51发布

如何命名为红宝石2.0工作参数,我不完全理解。

def test(var1, var2, var3)
  puts "#{var1} #{var2} #{var3}"
end

test(var3:"var3-new", var1: 1111, var2: 2222) #wrong number of arguments (1 for 3) (ArgumentError)

它像对待哈希值。 它很有趣,因为在Ruby中2.0使用命名参数我必须为他们设置的默认值:

def test(var1: "var1", var2: "var2", var3: "var3")
  puts "#{var1} #{var2} #{var3}"
end

test(var3:"var3-new", var1: 1111, var2: 2222) # ok => 1111 2222 var3-new

这非常类似于它与Ruby的默认参数值之前所具有的行为:

def test(var1="var1", var2="var2", var3="var3")
  puts "#{var1} #{var2} #{var3}"
end

test(var3:"var3-new", var1: 1111, var2: 2222) # ok but ... {:var3=>"var3-new", :var1=>1111, :var2=>2222} var2 var3

我知道这是为什么发生,几乎它是如何工作。

但我只是好奇,我必须使用参数的缺省值,如果我用命名的参数?

而且,有谁能够告诉我什么是这两个,然后有什么区别?

def test1(var1="default value123")
  #.......
end

def test1(var1:"default value123")
  #.......
end

Answer 1:

首先,您发布的最后一个例子是一种误导。 我完全不同意的行为类似于之前的一个。 最后一个例子传递参数散列为这是一个不同的事情第一个可选参数!

如果你不希望有一个默认值,你可以使用nil

如果你想读好书面记录,请参阅“ 红宝石2关键参数 ”。



Answer 2:

我认为这回答了你的问题,更新可以明确的例子来说明。 在下面你的例子有一个明确的顺序可选参数:

def show_name_and_address(name="Someone", address="Somewhere")
  puts "#{name}, #{address}"
end

show_name_and_address
#=> 'Someone, Somewhere'

show_name_and_address('Andy')
#=> 'Andy, Somewhere'

命名参数的方法是不同的。 它还允许你提供的默认值,但它允许调用者确定的参数,如果有的话,为客户提供:

def show_name_and_address(name: "Someone", address: "Somewhere")
  puts "#{name}, #{address}"
end

show_name_and_address
#=> 'Someone, Somewhere'

show_name_and_address(name: 'Andy')
#=> 'Andy, Somewhere'

show_name_and_address(address: 'USA')
#=> 'Someone, USA'

虽然这是真的,当不带参数提供的两种方法是相似的,它们之间的区别,当用户提供参数的方法。 随着命名参数调用方可以指定被提供了参数。 具体而言,最后一个例子(只提供的地址)没有在第一实施例相当实现; 你只能通过提供两个参数的方法得到了类似的结果。 这使得命名参数接近灵活得多。



Answer 3:

我同意你的看法,它的怪异要求默认值的价格使用命名参数,看样子Ruby的维护者同意我们在一起! 红宝石2.1将删除缺省值要求为2.1.0-preview1的 。



Answer 4:

作为红宝石2.1.0 ,你再也不用为命名的参数设置默认值。 如果省略默认值参数,调用者将被要求提供它。

def concatenate(val1: 'default', val2:)
  "#{val1} #{val2}"
end

concatenate(val2: 'argument')
#=> "default argument"

concatenate(val1: 'change')
#=> ArgumentError: missing keyword: val2

鉴于:

def test1(var1="default value123")
  var1
end

def test2(var1:"default value123")
  var1
end

他们会表现在不传递参数以同样的方式:

test1
#=> "default value123"

test2
#=> "default value123"

但是,他们会表现在参数传递多少不同:

test1("something else")
#=> "something else"

test2("something else")
#=> ArgumentError: wrong number of arguments (1 for 0)


test1(var1: "something else")
#=> {:var1=>"something else"}

test2(var1: "something else")
#=> "something else"


Answer 5:

这是存在于所有其他的答案,但我想这个提取精华。

有四种类型的参数:

             Required     Optional
Positional | def PR(a)  | def PO(a=1) |
Keyword    | def KR(a:) | def KO(a:1) |

当定义一个函数,位置参数被关键字参数之前指定的,和可选的那些之前必需的参数。

irb(main):006:0> def argtest(a,b=2,c:,d:4)
irb(main):007:1> p [a,b,c,d]
irb(main):008:1> end
=> :argtest

irb(main):009:0> argtest(1,c: 3)
=> [1, 2, 3, 4]

irb(main):010:0> argtest(1,20,c: 3,d: 40)
=> [1, 20, 3, 40]

编辑:所需要的关键字参数(没有默认值)作为新的Ruby 2.1.0,如其他人所说。



Answer 6:

def test(a = 1, b: 2, c: 3)
  p [a,b,c]
end

test #=> [1,2,3]
test 10 #=> [10,2,3]
test c:30 #=> [1,2,30] <- this is where named parameters become handy. 

您可以定义默认值和参数的名称,然后调用该方法只需要调用它,如果你有基于散列的“命名”参数,但无需在你的方法来定义默认的方式。

如果你使用的是哈希您需要这在你的方法对每个“命名参数”。

b = options_hash[:b] || 2

如:

  def test(a = 1, options_hash)
    b = options_hash[:b] || 2
    c = options_hash[:c] || 3
    p [a,b,c]
  end


Answer 7:

据“ 通过实例的Ruby 2.0.0 ”你必须有默认值:

在Ruby 2.0.0,关键字参数必须有默认值,否则必须由**额外末被捕获。



Answer 8:

您可以定义命名的参数,如

def test(var1: var1, var2: var2, var3: var3)
  puts "#{var1} #{var2} #{var3}"
end

如果没有传递的参数之一,那么红宝石会抱怨一个undefined local variable or method



文章来源: Named parameters in Ruby 2
标签: ruby ruby-2.0