Nazwane parametry w Ruby 2
Nie do końca rozumiem, jak działają nazwane parametry w Rubim 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)
Jest traktowany jak haszysz. I to jest bardzo zabawne, ponieważ aby użyć nazwanych parametrów w Rubim 2.0 i musi ustawić dla nich domyślne wartości:
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
Które bardzo podobne do zachowania, które miało wcześniej Ruby z wartościami domyślnych parametrów:
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
Wiem, dlaczego tak się dzieje i prawie jak to działa.
Ale jestem tylko ciekaw, musi używam domyślnego wartości parametrów Jeśli używam nazwanych parametrów?
Czy ktoś może mi powiedzieć, jaka jest różnica między tymi dwoma?def test1(var1="default value123")
#.......
end
def test1(var1:"default value123")
#.......
end
8 answers
Po pierwsze, ostatni przykład, który opublikowałeś, wprowadza w błąd. Całkowicie się nie Zgadzam, że zachowanie jest podobne do poprzedniego. Ostatni przykład przekazuje parametr hash jako pierwszy opcjonalny parametr, co jest zupełnie inną rzeczą!
Jeśli nie chcesz mieć wartości domyślnej, możesz po prostu użyć nil
.
Jeśli chcesz przeczytać dobry writeup, zobacz " argumenty słowa kluczowego Ruby 2 ".
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-30 18:56:38
Myślę, że odpowiedź na twoje zaktualizowane pytanie można wyjaśnić wyraźnymi przykładami. W poniższym przykładzie masz opcjonalne parametry w jawnej kolejności:
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'
Podejście nazwanych parametrów jest inne. Nadal pozwala na podanie wartości domyślnych, ale pozwala wywoływaczowi określić, który z parametrów ma być podany:
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'
Chociaż prawdą jest, że oba podejścia są podobne, gdy nie mają parametrów, różnią się, gdy użytkownik zapewnia parametry metody. Za pomocą nazwanych parametrów wywołujący może określić, który parametr jest dostarczany. W szczególności, ostatni przykład (podanie tylko adresu) nie jest do końca osiągalny w pierwszym przykładzie; można uzyskać podobne wyniki tylko poprzez podanie obu parametrów do metody. To sprawia, że podejście nazwanych parametrów jest znacznie bardziej elastyczne.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-09 17:41:41
Zgadzam się z Tobą, że dziwnie jest wymagać wartości domyślnych jako ceny za używanie nazwanych parametrów i widocznie opiekunowie Ruby zgadzają się z nami! Ruby 2.1 usunie wymóg wartości domyślnej z 2.1.0-preview1 .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-11 03:09:37
Począwszy od Ruby 2.1.0, nie musisz już ustawiać domyślnych wartości dla nazwanych parametrów. Jeśli pominiesz domyślną wartość parametru, wywołujący będzie musiał ją podać.
def concatenate(val1: 'default', val2:)
"#{val1} #{val2}"
end
concatenate(val2: 'argument')
#=> "default argument"
concatenate(val1: 'change')
#=> ArgumentError: missing keyword: val2
Podane:
def test1(var1="default value123")
var1
end
def test2(var1:"default value123")
var1
end
Zachowają się tak samo, gdy nie podadzą argumentu:
test1
#=> "default value123"
test2
#=> "default value123"
Ale zachowają się znacznie inaczej, gdy argument zostanie przekazany:
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"
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-09 17:40:21
To jest obecne we wszystkich innych odpowiedziach, ale chcę wyodrębnić tę esencję.
Istnieją cztery rodzaje parametrów:
Required Optional
Positional | def PR(a) | def PO(a=1) |
Keyword | def KR(a:) | def KO(a:1) |
Podczas definiowania funkcji argumenty pozycyjne są podawane przed argumentami słów kluczowych, a argumenty wymagane przed argumentami opcjonalnymi.
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]
Edit: wymagany argument słowa kluczowego (bez wartości domyślnej) JEST NOWY od Ruby 2.1.0, jak wspominali inni.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-10 21:17:08
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.
Możesz zdefiniować wartość domyślną i nazwę parametru, a następnie wywołać metodę tak, jak byś ją wywołał, gdybyś miał parametry "nazwane" oparte na haszu, ale bez potrzeby definiowania wartości domyślnych w swojej metodzie.
Potrzebowałbyś tego w swojej metodzie dla każdego "nazwanego parametru", jeśli używałeś hasha.
b = options_hash[:b] || 2
Jak w:
def test(a = 1, options_hash)
b = options_hash[:b] || 2
c = options_hash[:c] || 3
p [a,b,c]
end
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-12 18:35:39
Zgodnie z "Ruby 2.0.0 by Example " musisz mieć domyślne wartości:
W Rubim 2.0.0, argumenty słów kluczowych muszą mieć domyślne wartości lub muszą być przechwycone przez **extra na końcu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-09 17:42:47
Możesz zdefiniować nazwane parametry jak
def test(var1: var1, var2: var2, var3: var3)
puts "#{var1} #{var2} #{var3}"
end
Jeśli nie podasz jednego z parametrów, to Ruby będzie narzekać na undefined local variable or method
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-08 08:53:55