web-dev-qa-db-ja.com

Ruby 2の名前付きパラメーター

Ruby 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 I mustでデフォルト値を設定する)で名前付きパラメーターを使用するのは非常に面白いです。

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

私はそれがなぜ起こっているのか、そしてほぼどのように機能するのかを知っています。

しかし、私は好奇心が強いですmust名前付きパラメーターを使用する場合、パラメーターにデフォルト値を使用しますか?

そして、誰が私にこれらの2つの違いは何ですか教えてもらえますか?

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

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

まず、最後に投稿した例は誤解を招く恐れがあります。私は、振る舞いが以前のものと似ていることに全く同意しません。最後の例では、引数hashを最初のオプションのパラメーターとして渡しますが、これは別のものです!

デフォルト値が必要ない場合は、nilを使用できます。

適切な記事を読みたい場合は、「 Ruby 2キーワード引数 」を参照してください。

18
phoet

更新された質問に対する答えは、明確な例で説明できると思います。以下の例では、オプションのパラメーターが明示的な順序であります。

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'

2つのアプローチがパラメーターなしで提供される場合は似ていることは事実ですが、ユーザーがメソッドにパラメーターを提供する場合は異なります。名前付きパラメーターを使用すると、呼び出し元は提供されるパラメーターを指定できます。具体的には、最後の例(アドレスのみを提供する)は最初の例では完全には達成できません。メソッドに両方のパラメーターを指定するだけで、同様の結果を得ることができます。これにより、名前付きパラメーターアプローチがより柔軟になります。

34
AndyV

名前付きパラメーターを使用するための価格としてデフォルト値を要求するのは奇妙であり、明らかにRubyメンテナーは私たちに同意する!! Ruby 2.1は- 2.1.0-preview1からデフォルト値の要件を削除

13
Josh Diehl

Ruby 2.1. 以降、名前付きパラメーターのデフォルト値を設定する必要がなくなりました。パラメーターのデフォルト値を省略すると、呼び出し元はそれを提供する必要があります。

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"
11
trliner

これは他のすべての答えにもありますが、このエッセンスを抽出したいと思います。

4種類のパラメーターがあります。

             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、他の人が述べたように新しいです。

5
Chris Cox
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
2
aaandre

例によるRuby 2.0. 」によると、デフォルトが必要です:

Ruby 2.0.0では、キーワード引数にデフォルトを設定するか、最後に** extraでキャプチャする必要があります。

次のような名前付きパラメーターを定義できます

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

パラメータの1つを渡さない場合、Rubyはundefined local variable or method

0
Clemens Helm