Feature #5454

keyword arguments

Added by Yusuke Endoh over 2 years ago. Updated over 2 years ago.

[ruby-dev:44602]
Status:Rejected
Priority:Normal
Assignee:Koichi Sasada
Category:-
Target version:-

Description

遠藤です。

キーワード引数を実装してみました。

$ cat t.rb
def foo(str: "foo", num: 424242)
p [str, num]
end
foo(str: "bar")

$ ./ruby t.rb
["bar", 424242]

細かいことはまだ気にしていませんが、キーワード引数が 2.0 に入る
ことはかなり確定的なので、とりあえず trunk に入れて考えるという
のはどうでしょうか。

一応私の環境では make check は通ります (キーワード引数のテスト
は書いてないですが) 。パーサに conflict はないです。
既存のベンチマークを見ると、一部気になる項目もありますが (vm1_
rescue とか) 、全体的には特に速度劣化しないようです。

以下は未検討・未実装の細かいことです。

  • 残りのキーワード引数を受け取る方法が必要?

    def foo(str: "foo", num: 424242, **h)
    p h
    end
    foo(str: "bar", check: true) #=> { :check => true }

  • nil が渡されたらやはり nil になるべき?

    def foo(str: "foo")
    p str
    end
    foo(str: nil) #=> nil ? (今は手抜きで "foo")

  • rest なしで知らないキーワードが来たら例外・警告を発して
    欲しい?

    def foo(str: "foo", num: 424242)
    end
    foo(check: true) #=> ArgumentError?

  • Hash のように振る舞うオブジェクトもキーワード引数として
    解釈すべき? (現在は速度重視で T_HASH だけ見ている)

  • 引数の順番はこれでよいか?

    def foo(
    a, b, c, # mandatory arguments
    opt = 1, # optional arguments
    rest, # rest argument
    x, y, z, # post mandatory arguments
    k1: 1, k2:2, # keyword arguments
    *
    kh, # keyword rest argument
    &blk # block argument
    )

  • 他いろいろ

benchmark results:
name ruby 1.9.4dev (2011-10-16 trunk 33471) [i686-linux] ruby 1.9.4dev (2011-10-16 trunk 33471) [i686-linux] average difference
appanswer 0.259 0.131 -0.127
app
erb 2.699 2.681 -0.018
appfactorial 5.236 5.320 0.084
app
fib 1.576 1.731 0.154
appmandelbrot 4.324 3.911 -0.413
app
pentomino 40.882 40.768 -0.114
appraise 0.966 0.982 0.017
app
strconcat 3.143 3.102 -0.041
apptak 2.192 2.140 -0.052
app
tarai 1.682 1.748 0.066
appuri 1.870 1.767 -0.103
io
filecreate 2.589 2.570 -0.019
io
fileread 6.169 5.838 -0.330
io
filewrite 1.966 1.976 0.010
io
select 3.066 3.111 0.044
ioselect2 3.647 3.623 -0.025
io
select3 0.051 0.051 0.000
loopfor 3.302 3.219 -0.082
loop
generator 1.111 1.102 -0.009
looptimes 2.959 2.960 0.001
loop
whileloop 1.437 1.422 -0.016
loopwhileloop2 0.298 0.297 -0.001
so
ackermann 1.862 1.816 -0.046
soarray 3.317 3.473 0.155
so
binarytrees 0.891 0.900 0.009
so
concatenate 9.538 8.696 -0.842
socountwords 0.412 0.407 -0.005
soexception 2.185 2.177 -0.008
so
fannkuch 3.338 3.334 -0.004
sofasta 5.182 5.061 -0.121
so
knucleotide 3.425 3.324 -0.101
so
lists 2.239 2.312 0.073
somandelbrot 11.479 10.660 -0.820
so
matrix 2.206 2.177 -0.030
someteorcontest 11.479 11.634 0.155
sonbody 8.006 7.925 -0.081
so
nestedloop 2.768 2.614 -0.154
so
nsieve 6.163 6.184 0.021
sonsievebits 6.618 6.850 0.231
soobject 1.807 1.899 0.091
so
partialsums 11.057 10.537 -0.520
so
pidigits 2.944 3.011 0.066
sorandom 1.962 1.992 0.031
so
reversecomplement 3.136 3.036 -0.099
so
sieve 2.224 2.203 -0.021
sospectralnorm 7.981 7.591 -0.390
vm1
block* 3.790 5.112 1.306
vm1const* 0.756 0.757 -0.015
vm1
ensure* 0.487 0.601 0.099
vm1ivar* 1.634 1.863 0.213
vm1
ivarset* 1.625 1.661 0.021
vm1
length* 1.312 1.366 0.038
vm1neq* 1.152 0.979 -0.189
vm1
not* 0.589 0.589 -0.015
vm1rescue* 0.133 0.750 0.601
vm1
simplereturn* 2.467 3.601 1.119
vm1swap* 1.199 1.716 0.502
vm2
array* 1.644 1.643 -0.001
vm2case* 0.324 0.348 0.023
vm2
definedmethod* 8.829 9.003 0.173
vm2
eval* 39.557 37.726 -1.832
vm2method* 5.255 4.113 -1.142
vm2
mutex* 3.043 3.175 0.131
vm2polymethod* 6.044 5.340 -0.705
vm2polymethodov* 0.493 0.675 0.181
vm2
proc* 1.297 1.391 0.093
vm2regexp* 2.419 2.557 0.137
vm2
send* 0.662 0.903 0.241
vm2super* 1.107 1.016 -0.093
vm2
unif1* 0.688 0.816 0.127
vm2zsuper* 1.210 1.068 -0.143
vm3
clearmethodcache 0.785 0.770 -0.014
vm3gc 2.487 2.453 -0.033
vm
threadalivecheck1 0.389 0.422 0.033
vmthreadcreatejoin 6.064 6.181 0.118
vm
threadmutex1 2.349 2.546 0.197
vm
threadmutex2 10.123 7.755 -2.368
vm
threadmutex3 4.428 5.390 0.962
vm
threadpass 0.692 0.754 0.063
vm
threadpassflood 0.167 0.170 0.003

vmthreadpipe 2.437 2.540 0.103

average total difference is -3.4518661499023438

Yusuke Endoh mame@tsg.ne.jp

0001-remove-NEW_LAMBDA-hack.patch Magnifier (1.51 KB) Yusuke Endoh, 10/18/2011 01:21 AM

0002-use-struct-rb_args_info-instead-of-NODEs.patch Magnifier (9.33 KB) Yusuke Endoh, 10/18/2011 01:21 AM

0003-implement-a-parser-part-for-basic-keyword-arguments.patch Magnifier (23.2 KB) Yusuke Endoh, 10/18/2011 01:21 AM

0004-rough-implementation-of-keyword-arguments.patch Magnifier (5.43 KB) Yusuke Endoh, 10/18/2011 01:21 AM

0005-temporal-fix-for-ripper-test.patch Magnifier (717 Bytes) Yusuke Endoh, 10/18/2011 01:21 AM

keyword-argument-patch-20111023.zip (11.6 KB) Yusuke Endoh, 10/23/2011 02:52 PM


Related issues

Related to ruby-trunk - Feature #227: rb_scan_args() for keyword arguments Closed

History

#1 Updated by Yukihiro Matsumoto over 2 years ago

|細かいことはまだ気にしていませんが、キーワード引数が 2.0 に入る
|ことはかなり確定的なので、とりあえず trunk に入れて考えるという
|のはどうでしょうか。

賛成です。trunkに入れちゃっていいのかな。そういう機能の入っ
ていない1.9ブランチが欲しい人は急いで切ったほうがいいと思い
ますよ。

|以下は未実装・懸案です。
|
| - 残りのキーワード引数を受け取る方法が必要か
|
| def foo(str: "foo", num: 424242, **h)
| p h
| end
| foo(str: "bar", check: true) #=> { :check => true }

メソッドの移譲のために必要だと思います。

| - nil が渡されたらやはり nil になるべき?
|
| def foo(str: "foo")
| p str
| end
| foo(str: nil) #=> nil ? (今は手抜きで "foo")

nilになるべきでしょう。

| - rest なしで知らないキーワードが来たら例外・警告を発して
| 欲しい?
|
| def foo(str: "foo", num: 424242)
| end
| foo(check: true) #=> ArgumentError?

ここは議論の余地があるところですね。現時点では、**で受け取ら
ない限り例外にするべきだと考えていますが、実際にいろいろな局
面で使ってみると意見が変わるかもしれません。

| - Hash のように振る舞うオブジェクトもキーワード引数として
| 解釈すべき? (現在は速度重視で T_HASH だけ見ている)

とりあえずtohashを使ってください。新設のtokwのようなメソッ
ドを使うべきなのかもしれませんが。

| - 引数の順番はよいか
|
| def foo(
| a, b, c, # mandatory arguments
| opt = 1, # optional arguments
| rest, # rest argument
| x, y, z, # post mandatory arguments
| k1: 1, k2:2, # keyword arguments
| *
kh, # keyword rest argument
| &blk # block argument
| )

これで良いと思います。

                            まつもと ゆきひろ /:|)

#2 Updated by Anonymous over 2 years ago

This looks very interesting! Would someone be willing to translate to english? I've only got a vague idea of what is being discussed.

--

Evan Phoenix // evan@phx.io

#3 Updated by Anonymous over 2 years ago

Hi,

2011年10月18日8:13 Evan Phoenix evan@phx.io:

This looks very interesting! Would someone be willing to translate to english? I've only got a vague idea of what is being discussed.

I and NaHi translated the mails.

http://ruby-dev.info/posts/44602

--
yhara (Yutaka HARA)

#4 Updated by Yukihiro Matsumoto over 2 years ago

Hi,

I should have posted in English at first.
Thank you guys for translation.

                        matz.

In message "Re: Re: [Ruby 2.0 - Feature #5454] keyword arguments"
on Tue, 18 Oct 2011 11:56:29 +0900, Yutaka Hara yutaka.hara@gmail.com writes:
|
|Hi,
|
|2011年10月18日8:13 Evan Phoenix evan@phx.io:
|> This looks very interesting! Would someone be willing to translate to english? I've only got a vague idea of what is being discussed.
|>
|I and NaHi translated the mails.
|
|http://ruby-dev.info/posts/44602
|
|--
|yhara (Yutaka HARA)

#5 Updated by Anonymous over 2 years ago

Do I need to learn Ruby first to learn Rails?

Loving Ruby and want to learn it.

Thanks

2011/10/18 Yukihiro Matsumoto matz@ruby-lang.org

Hi,

I should have posted in English at first.
Thank you guys for translation.

                                                   matz.

In message "Re: Re: [Ruby 2.0 - Feature #5454] keyword
arguments"
on Tue, 18 Oct 2011 11:56:29 +0900, Yutaka Hara yutaka.hara@gmail.com
writes:
|
|Hi,
|
|2011年10月18日8:13 Evan Phoenix evan@phx.io:
|> This looks very interesting! Would someone be willing to translate to
english? I've only got a vague idea of what is being discussed.
|>
|I and NaHi translated the mails.
|
|http://ruby-dev.info/posts/44602
|
|--
|yhara (Yutaka HARA)

#6 Updated by Anonymous over 2 years ago

Thanks for the translation!

I've got a question about the proposal that will help me understand how it would be implemented.

Given a method:

def foo(name, age)
p [name, age]
end

And then code that calls this method:

arg = { :name => "Evan", :age => 32 }
foo(arg)

Would this print out ["Evan", 32]?

If so, this seems like a very big change that a lot of code written against 1.9 will not work with.

Also, the example code in the proposal uses a form to call foo like this:

foo(name: "Evan", age: 32)

This reuses the 1.8/1.9 behavior of the implicit hash parameter. Does this mean that the implementation creates a hash on the caller side, which is then pulled apart by the called method? If so, these seems just like my first example, and would end up breaking a lot of code.

Because 1.9 introduces the new hash syntax, which programmers have begun using with the implicit hash parameter, I don't think that the syntax can be used again for keyword arguments without introducing an incompatible change.

So, I'd like to suggest an alternative to this which uses a different (and thusly unambiguous) syntax:

foo(name="Evan", age=32)

I know that this is valid ruby code in 1.9, but it is extremely rare, much much more rare than the implicit hash parameter. Thusly it is safer and will not break 1.9 code.

This form also allows for an implementation of keyword parameters that don't require creating a Hash object, which makes the code faster and more useful.

If a truly new syntax must be introduced to be 100% backward compatible, I'd suggest:

foo(name := "Evan", age := 32)

:= is already known in computing as a bind operator, and thus it is suited well to this task.

Thank you for considering my proposal.

  • Evan

    Evan Phoenix // evan@phx.io

    On Monday, October 17, 2011 at 9:08 PM, Yukihiro Matsumoto wrote:

    Hi,

    I should have posted in English at first.
    Thank you guys for translation.

    matz.

    In message "Re: Re: [Ruby 2.0 - Feature #5454] keyword arguments"
    on Tue, 18 Oct 2011 11:56:29 +0900, Yutaka Hara writes:
    |
    |Hi,
    |
    |2011年10月18日8:13 Evan Phoenix :
    |> This looks very interesting! Would someone be willing to translate to english? I've only got a vague idea of what is being discussed.
    |>
    |I and NaHi translated the mails.
    |
    |http://ruby-dev.info/posts/44602
    |
    |--
    |yhara (Yutaka HARA)

#7 Updated by Konstantin Haase over 2 years ago

Please ask such question at the Rails mailing list, the ruby-talk mailing list, or Stack Overflow. The core list is about developing Ruby, not developing in Ruby.

Konstantin

On Oct 17, 2011, at 22:14 , Praveer Dikshit wrote:

Do I need to learn Ruby first to learn Rails?

Loving Ruby and want to learn it.

Thanks

2011/10/18 Yukihiro Matsumoto matz@ruby-lang.org
Hi,

I should have posted in English at first.
Thank you guys for translation.

                                                   matz.

In message "Re: Re: [Ruby 2.0 - Feature #5454] keyword arguments"
on Tue, 18 Oct 2011 11:56:29 +0900, Yutaka Hara yutaka.hara@gmail.com writes:
|
|Hi,
|
|2011年10月18日8:13 Evan Phoenix evan@phx.io:
|> This looks very interesting! Would someone be willing to translate to english? I've only got a vague idea of what is being discussed.
|>
|I and NaHi translated the mails.
|
|http://ruby-dev.info/posts/44602
|
|--
|yhara (Yutaka HARA)

#8 Updated by Konstantin Haase over 2 years ago

From the current patch it seems to me that this would raise an ArgumentError, as it does now. Neither name nor age are "keyword arguments". There is no way to define keyword arguments without a default.

Also, these are really named arguments in a Python sense, not keyword arguments in a Smalltalk sense.

@Matz:

def foo(bar: 42) bar end
foo bar: nil

The above should return nil IMHO, since this is also what I'd expect if it would be an options hash.

Konstantin

On Oct 17, 2011, at 22:27 , Evan Phoenix wrote:

Thanks for the translation!

I've got a question about the proposal that will help me understand how it would be implemented.

Given a method:

def foo(name, age)
p [name, age]
end

And then code that calls this method:

arg = { :name => "Evan", :age => 32 }
foo(arg)

Would this print out ["Evan", 32]?

If so, this seems like a very big change that a lot of code written against 1.9 will not work with.

Also, the example code in the proposal uses a form to call foo like this:

foo(name: "Evan", age: 32)

This reuses the 1.8/1.9 behavior of the implicit hash parameter. Does this mean that the implementation creates a hash on the caller side, which is then pulled apart by the called method? If so, these seems just like my first example, and would end up breaking a lot of code.

Because 1.9 introduces the new hash syntax, which programmers have begun using with the implicit hash parameter, I don't think that the syntax can be used again for keyword arguments without introducing an incompatible change.

So, I'd like to suggest an alternative to this which uses a different (and thusly unambiguous) syntax:

foo(name="Evan", age=32)

I know that this is valid ruby code in 1.9, but it is extremely rare, much much more rare than the implicit hash parameter. Thusly it is safer and will not break 1.9 code.

This form also allows for an implementation of keyword parameters that don't require creating a Hash object, which makes the code faster and more useful.

If a truly new syntax must be introduced to be 100% backward compatible, I'd suggest:

foo(name := "Evan", age := 32)

:= is already known in computing as a bind operator, and thus it is suited well to this task.

Thank you for considering my proposal.

  • Evan

Evan Phoenix // evan@phx.io

On Monday, October 17, 2011 at 9:08 PM, Yukihiro Matsumoto wrote:

Hi,

I should have posted in English at first.
Thank you guys for translation.

matz.

In message "Re: Re: [Ruby 2.0 - Feature #5454] keyword arguments"
on Tue, 18 Oct 2011 11:56:29 +0900, Yutaka Hara writes:
|
|Hi,
|
|2011年10月18日8:13 Evan Phoenix :
|> This looks very interesting! Would someone be willing to translate to english? I've only got a vague idea of what is being discussed.
|>
|I and NaHi translated the mails.
|
|http://ruby-dev.info/posts/44602
|
|--
|yhara (Yutaka HARA)

#9 Updated by Anonymous over 2 years ago

See below.

--

Evan Phoenix // evan@phx.io

On Monday, October 17, 2011 at 10:33 PM, Haase, Konstantin wrote:

From the current patch it seems to me that this would raise an ArgumentError, as it does now. Neither name nor age are "keyword arguments". There is no way to define keyword arguments without a default.
Ah! Ok, so keyword arguments are completely separate than normal arguments. This feature would basically be "Hash restructuring", ie letting the VM know what keys in the Hash your interested in and having it pull them out for you.

That seems quite interesting, but less useful that being to invoke a method and bind a value to a normal argument via it's name.

  • Evan
    >
    > Also, these are really named arguments in a Python sense, not keyword arguments in a Smalltalk sense. >
    > @Matz: >
    > def foo(bar: 42) bar end > foo bar: nil >
    > The above should return nil IMHO, since this is also what I'd expect if it would be an options hash. >
    > Konstantin >
    > On Oct 17, 2011, at 22:27 , Evan Phoenix wrote: >
    > > Thanks for the translation! > >
    > > I've got a question about the proposal that will help me understand how it would be implemented. > >
    > > Given a method: > >
    > > def foo(name, age) > > p [name, age] > > end > >
    > > And then code that calls this method: > >
    > > arg = { :name => "Evan", :age => 32 } > > foo(arg) > >
    > > Would this print out ["Evan", 32]? > >
    > > If so, this seems like a very big change that a lot of code written against 1.9 will not work with. > >
    > > Also, the example code in the proposal uses a form to call foo like this: > >
    > > foo(name: "Evan", age: 32) > >
    > > This reuses the 1.8/1.9 behavior of the implicit hash parameter. Does this mean that the implementation creates a hash on the caller side, which is then pulled apart by the called method? If so, these seems just like my first example, and would end up breaking a lot of code. > >
    > >
    > > Because 1.9 introduces the new hash syntax, which programmers have begun using with the implicit hash parameter, I don't think that the syntax can be used again for keyword arguments without introducing an incompatible change. > >
    > > So, I'd like to suggest an alternative to this which uses a different (and thusly unambiguous) syntax: > >
    > > foo(name="Evan", age=32) > >
    > > I know that this is valid ruby code in 1.9, but it is extremely rare, much much more rare than the implicit hash parameter. Thusly it is safer and will not break 1.9 code. > >
    > > This form also allows for an implementation of keyword parameters that don't require creating a Hash object, which makes the code faster and more useful. > >
    > > If a truly new syntax must be introduced to be 100% backward compatible, I'd suggest: > >
    > > foo(name := "Evan", age := 32) > >
    > > := is already known in computing as a bind operator, and thus it is suited well to this task. > >
    > > Thank you for considering my proposal. > >
    > > - Evan > >
    > > --
    > > Evan Phoenix // evan@phx.io (mailto:evan@phx.io) > >
    > >
    > > On Monday, October 17, 2011 at 9:08 PM, Yukihiro Matsumoto wrote: > >
    > > > Hi, > > >
    > > > I should have posted in English at first. > > > Thank you guys for translation. > > >
    > > > matz. > > >
    > > > In message "Re: Re: [Ruby 2.0 - Feature #5454] keyword arguments" > > > on Tue, 18 Oct 2011 11:56:29 +0900, Yutaka Hara writes: > > > | > > > |Hi, > > > | > > > |2011年10月18日8:13 Evan Phoenix : > > > |> This looks very interesting! Would someone be willing to translate to english? I've only got a vague idea of what is being discussed. > > > |> > > > |I and NaHi translated the mails. > > > | > > > |http://ruby-dev.info/posts/44602 > > > | > > > |-- > > > |yhara (Yutaka HARA)

#10 Updated by Joshua Ballanco over 2 years ago

On Tue, Oct 18, 2011 at 1:33 AM, Haase, Konstantin <
Konstantin.Haase@student.hpi.uni-potsdam.de> wrote:

Also, these are really named arguments in a Python sense, not keyword
arguments in a Smalltalk sense.

I just wanted to point out that MacRuby (in order to support compatibility
with Obj-C which uses Smalltalk style keyword arguments) already uses the
hash syntax for defining/calling methods, but the semantics are different
from what is being proposed here, if I understand correctly. To summarize:

 # Ruby 2.0 proposal:
 def foo(a: 1, b: 2, c: 3)
     puts [a, b, c]
 end
 foo(a: 'one', b: 'two', c: 'three') #=> ["one", "two", "three"]

 # Currently in MacRuby:
 def foo(a: first, b: second, c: third)
     puts [first, second, third]
 end
 foo(a: 'one', b: 'two', c: 'three') #=> ["one", "two", "three"]

With the current proposal for keyword arguments, I think MacRuby would not
be able to implement this feature.

#11 Updated by Yukihiro Matsumoto over 2 years ago

Hi,

In message "Re: Re: [Ruby 2.0 - Feature #5454] keyword arguments"
on Wed, 19 Oct 2011 00:14:13 +0900, Joshua Ballanco jballanc@gmail.com writes:

|With the current proposal for keyword arguments, I think MacRuby would not
|be able to implement this feature.

I know. But I have warned MacRuby guys for years.

                        matz.

#12 Updated by Yusuke Endoh over 2 years ago

Hello,

2011/10/19 Joshua Ballanco jballanc@gmail.com:

    # Ruby 2.0 proposal:
    def foo(a: 1, b: 2, c: 3)
        puts [a, b, c]
    end
    foo(a: 'one', b: 'two', c: 'three') #

#13 Updated by Yukihiro Matsumoto over 2 years ago

Hi,

In message "Re: Re: [Ruby 2.0 - Feature #5454] keyword arguments"
on Wed, 19 Oct 2011 00:31:44 +0900, Yusuke Endoh mame@tsg.ne.jp writes:

|Interesting. Matz, which do you prefer?

I prefer the former (keyword hash) way. MacRuby keyword arguments are
solely for bridging with Objective-C, so that they can translate

obj.foo(1, bar: 2)

into

[obj foo: 1 bar: 2]

in Objective-C.

                        matz.

#14 Updated by Yusuke Endoh over 2 years ago

Hello,

2011/10/19 Yukihiro Matsumoto matz@ruby-lang.org:

|With the current proposal for keyword arguments, I think MacRuby would not
|be able to implement this feature.

I know.  But I have warned MacRuby guys for years.

Okay, I see you prefer the current proposal.

Still, I guess MacRuby will serve as a useful reference
when we discuss this proposal, especially, the corner cases.

--
Yusuke Endoh mame@tsg.ne.jp

#15 Updated by Joshua Ballanco over 2 years ago

On Tue, Oct 18, 2011 at 11:31 AM, Yukihiro Matsumoto matz@ruby-lang.orgwrote:

Hi,

In message "Re: Re: [Ruby 2.0 - Feature #5454] keyword
arguments"
on Wed, 19 Oct 2011 00:14:13 +0900, Joshua Ballanco <
jballanc@gmail.com> writes:

|With the current proposal for keyword arguments, I think MacRuby would not
|be able to implement this feature.

I know. But I have warned MacRuby guys for years.

Heh, indeed. I just spoke briefly with lrz, and he's optimistic that we can
make it work. One question I have, though, would be if you intend to allow
variables as default values or only literals. For example, should this work:

 x = 30
 def foo(a: 1, b: 2, c: x)
     puts [a, b, c]
 end
 foo(a: 10, b: 20) #=>  [10, 20, 30]

?

#16 Updated by Yusuke Endoh over 2 years ago

Hello,

2011/10/19 Joshua Ballanco :

For example, should this work:
x = 30
def foo(a: 1, b: 2, c: x)
puts [a, b, c]
end
foo(a: 10, b: 20) #=> ¨Â±°²°³°> ?

Though the example will not work because x is in the different
variable scope, you can write any expression as a default value,
like:

def foo(str: File.read("/etc/passwd"))
p str
end
foo(str: "bar") #=> "bar"
foo #=> the contents of /etc/passwd

... currently it does not work correctly because of bug of my
implementation, though :-)
I'll update the patch tomorrow.

Yusuke Endoh

#17 Updated by Yusuke Endoh over 2 years ago

Hello,

I've updated the patch (keyword-argument-patch-20111023.zip).
It modifies the core much.
So I'd like to commit it after koichi's review.

The rough strategy of the implementation is to interpret:

def foo(str: "foo", num: 424242, **h)
...
end

as:

def foo(*r)
h = r.last.respondto?(:tohash) ? r.last.to_hash.dup : {}
str = h.key?(:str) ? h.delete(:str) : "foo"
num = h.key?(:num) ? h.delete(:num) : 424242
...
end

| - Do we need a way to receive all the keyword arguments?
|
| def foo(str: "foo", num: 424242, **h)
| p h
| end
| foo(str: "bar", check: true) #=> { :check => true }

It would be necessary for delegating arguments to another method.

Done.

$ ./ruby -e '
def foo(str: "foo", num: 4242, **h)
p h
end
foo(str: "bar", check: true)

'
{:check=>true}

| - When nil is passed explicitly, should the value be nil?
|
| def foo(str: "foo")
| p str
| end
| foo(str: nil) #=> nil ? (not implemented yet, "foo" is assigned now)

It should be nil.

Done.

$ ./ruby -e '
def foo(str: "foo", num: 4242)
p str
end
foo(str: nil)
'
nil

| - When unknown keyword is specified and there is no **rest,
| should we raise exception or warning?
|
| def foo(str: "foo", num: 424242)
| end
| foo(check: true) #=> ArgumentError?

There is a room for discussion. Currently I think it should raise an exception unless receiving with **rest, but I may change my opinion after using it in several situations in actual scripts.

Done.

$ ./ruby -e '
def foo(str: "foo", num: 4242)
end
foo(str: "bar", check: true)

'
-e:5:in `': unknown keyword (TypeError)

| - Should we accept an object behaves like Hash as keyword arguments?
| (Current implementation only checks T_HASH for speed)

Please use tohash for now. Maybe we should define new method, something like tokw.

Done.

$ ./ruby -e '
def foo(str: "foo", num: 4242)
p str
end
h = Object.new
def h.to_hash; { str: "bar" }; end
foo(h)
'
"bar"

| - Is order of arguments ok?
|
| def foo(
| a, b, c, # mandatory arguments
| opt = 1, # optional arguments
| rest, # rest argument
| x, y, z, # post mandatory arguments
| k1: 1, k2:2, # keyword arguments
| *
kh, # keyword rest argument
| &blk # block argument
| )

I think this order is OK.

Thanks!

Yusuke Endoh mame@tsg.ne.jp

#18 Updated by Yui NARUSE over 2 years ago

  • Project changed from CommonRuby to ruby-trunk
  • Target version deleted (next minor)

#19 Updated by Yusuke Endoh over 2 years ago

  • Status changed from Assigned to Rejected

すみません、メールがあちこちに言って議論が混乱しそうですね。
一度 close して立て直します。

Sorry for scattering the mails and confusing the discussion.
I close this once and I'll create a new ticket.

Yusuke Endoh mame@tsg.ne.jp

Also available in: Atom PDF