質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Q&A

2回答

1085閲覧

Rubyのデフォルト引数によるArgumentErrorの仕様について

TomoProg

総合スコア19

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

0グッド

0クリップ

投稿2020/03/15 14:34

編集2020/03/15 14:37

はじめまして。
TomoProgです。

あるRubyのソースを読んでいた際にデフォルト引数で気になる仕様を見つけたため、
なぜこのような仕様なのか、詳しい方がおられればご教授いただきたいと思い質問させていただきました。

気になるデフォルト引数の挙動

あるRubyのソースでデフォルト値が設定されている引数の後に、デフォルト値がない引数があるメソッドを見つけました。

ruby

1def method1(a, b=9, c) 2 [a, b, c] 3end 4 5method1(1, 2) #=> [1, 9, 2]

このメソッドを引数2つで呼び出した場合、2つ目に指定した値が第3引数に入り、第2引数はデフォルト値になるという挙動自体は分かったのですが、そもそもなぜこれがArgumentErrorにならないのでしょうか?

method1は引数を3つ受け取るメソッドのため、ArgumentErrorにならないとおかしいように思うのです。

Rubyはそういう仕様だと言われればそれまでなのですが、なぜこのような仕様にしたのか詳しい方がおられればご教授願いたいです。

補足情報(FW/ツールのバージョンなど)

shell

1ruby -v 2ruby 2.6.5p114 (2019-10-01 revision 67812) [x86_64-darwin19]

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

method1は引数を3つ受け取るメソッドのため、

デフォルト値のある引数というのは、省略してもいいということなので、3引数のメソッドでも3未満の個数の引数で呼べます。これはRubyに限らず。

という当たり前の回答でいいのでしょうか?
当たり前すぎて質問意図と違うような気もしますが、質問文を読む限りそうとしか言えない。

投稿2020/03/15 14:45

otn

総合スコア85901

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TomoProg

2020/03/15 22:53

回答ありがとうございます。 >デフォルト値のある引数というのは、省略してもいいということなので、3引数のメソッドでも3未満の個数の引数で呼べます。これはRubyに限らず。 その理論で行くと、例えば以下のようなコードを書いた場合に`[99, 1, 999]`ではなくシンタックスエラーになる意味が分からなくなってくるんですよね・・・。 ```Ruby def method1(a=99, b, c=999) [a, b, c] end method1(1) #=> [99, 1, 999] になるのでは? ``` ```shell syntax error, unexpected '=', expecting ')' def method1(a=99, b, c=999) ``` 質問したいことが曖昧だったと思います。 Rubyではなぜ質問文のようなメソッド定義ができるのだろうかという疑問でした。 例えばPythonではRubyとは違い、質問文のようなコードを書くとシンタックスエラーとなり、実行すらできないのです。 ```Python def method1(a, b=9, c): return [a, b, c] ``` ```shell File "Main.py", line 3 def method1(a, b=9, c): ^ SyntaxError: non-default argument follows default argument ``` Pythonのようにシンタックスエラーになってくれれば、method1を引数2つで呼び出すことができないので違和感がないのですが、Rubyでは質問文のようなメソッド定義が可能なため、なぜPythonと違い、このような定義ができるようになっているのかをご存知であれば教えていただきたいと思っています。
otn

2020/03/16 01:02

質問文が間違っていたということですね。 > def method1(a=99, b, c=999) これは、引数が2つの時に a,b なのか b,c なのか決定できないので、エラーです。
guest

0

method1は引数を3つ受け取るメソッドのため、ArgumentErrorにならないとおかしいように思うのです。

逆に聞きますが、そのような仕様だった場合にデフォルト引数はどのような場面で有効になるのでしょうか。

引数が足りないからこそ、デフォルト引数が使われます。

投稿2020/03/15 22:52

maisumakun

総合スコア146018

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TomoProg

2020/03/15 23:53

回答ありがとうございます。 例えば、以下のようなメソッド定義であればデフォルト引数が有効になるのはわかるのです。 def method1(a, b, c=9) [a, b, c] end method1(1, 2) #=> [1, 2, 9] ただ、今回の質問文のように、デフォルト値が設定されている引数の次にデフォルト値が設定されていないメソッドの場合にデフォルト値が設定されていない引数を省略できることに違和感を感じています。 Pythonで質問文と同じようなメソッドを定義した場合、シンタックスエラーとなりそもそも実行できないのですが、Rubyではなぜ質問文のような定義ができるようになっているのだろうか?何か理由があるのだろうか?というのを疑問に思っています。 こちらの質問が分かりにくく申し訳ないです。
maisumakun

2020/03/16 01:10

Rubyではないですが、先頭の引数が省略可能になるメソッドを見かけたことがあります。Rubyでもそのような実装が可能、ということです。
TomoProg

2020/03/16 03:44

返信ありがとうございます。 そういう言語もあるんですね。 改めて提示頂いたドキュメントを眺めてみましたが、まとまった箇所にあれば良いとの記述を見つけられず、どこかに書いてあるのであれば詳しく教えていただけませんか? あとドキュメントに以下のような記述を見つけ、ますます混乱してきました…。 以下引用です。 ————— 仮引数にデフォルト式が与えられた場合、メソッド呼び出しで実引数を省略したときのデフォルト値になります。ただし実引数との対応を取るため、i番目の引数にデフォルト値を指定したならば、 i+1番目以降でも全てデフォルト値を指定するか、可変長引数を利用しなければなりません(詳細は後述)。 ————— 「i+1番目以降でも全てデフォルト値を指定するか」という記述があり、今回のメソッド定義はそれに矛盾しているように思うのです。
maisumakun

2020/03/16 03:57 編集

> あとドキュメントに以下のような記述を見つけ、ますます混乱してきました…。 これはおそらく古い記述が残っているだけかと思います。
maisumakun

2020/03/16 03:56

> まとまった箇所にあれば良いとの記述を見つけられず、どこかに書いてあるのであれば詳しく教えていただけませんか? 以下の記述を端的にまとめたものです。 > メソッド定義において、仮引数はその種類毎に以下の順序でしか指定することはできません。いずれも省略することは可能です。 ・デフォルト式のない引数(複数指定可) ・デフォルト式のある引数(複数指定可) ・* を伴う引数(1つだけ指定可) ・デフォルト式のない引数(複数指定可) ・キーワード引数(複数指定可) ・** を伴う引数(1つだけ指定可) ・& を伴う引数(1つだけ指定可)
TomoProg

2020/03/16 15:31

るりまのリポジトリにissueが上がっていました。 https://github.com/rurema/doctree/issues/2033 どうやらRuby1.8までは質問文のような定義はできなかったようですが、1.9以降でできるようになったようですね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問