48

Ruby2.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

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

しかし、私は興味があります。名前付きパラメーターを使用する場合、パラメーターにデフォルト値を使用する必要がありますか?

そして、誰かがこれら2つの違いは何ですか?

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

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

9 に答える 9

64

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

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

于 2013-09-17T18:19:45.147 に答える
23

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

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

良い記事を読みたい場合は、「Ruby2のキーワード引数」を参照してください。

于 2013-03-09T10:27:56.340 に答える
14

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

于 2013-10-11T03:09:37.553 に答える
14

Ruby 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"
于 2015-05-30T04:08:15.473 に答える
10

これは他のすべての答えに存在しますが、私はこの本質を抽出したいと思います。

パラメータには次の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]

編集:他の人が言及しているように、必須のキーワード引数(デフォルト値なし)はRuby2.1.0の時点で新しいものです。

于 2016-09-10T21:10:59.357 に答える
2

「 Ruby2.0.0byExample」によると、デフォルトが必要です。

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

于 2013-03-09T10:57:50.267 に答える
2
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
于 2013-07-12T18:35:39.830 に答える
1

これは私を大いに助けたのでここに残しておきます。

あなたがこれを持っているとしましょう:

def foo(thing, to_print)
  if to_print
    puts thing
  end
end


# this works
foo("hi", true)
# hi
# => nil

したがって、次のように引数名を追加してみてください。

foo(thing: "hi", to_print: true)
# foo(thing: "hi", to_print: true)
# ArgumentError: wrong number of arguments (given 1, expected 2)
# from (pry):42:in `foo'

しかし、残念ながらそれはエラーです。

解決

:各引数の最後にaを追加するだけです。

def foo2(thing:, to_print:)
  if to_print
    puts thing
  end
end


foo2(thing: "hi", to_print: true)
# hi
# => nil

そしてそれは動作します!

于 2021-02-16T11:46:14.413 に答える
0

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

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

パラメータの1つを渡さないと、Rubyは。について文句を言いundefined local variable or methodます。

于 2013-07-08T08:53:55.663 に答える