Help us understand the problem. What is going on with this article?

Ruby 引数を扱うメソッド

Ruby 引数を扱うメソッド

※この記事は初心者の私がチェリー本で学習するにあたって新しく知ったことや考えたことアウトプットするための場として書いています。
この記事は以下の情報を参考にして記述し、一部引用しています。
プロを目指す人のためのRuby入門

この記事の目的

引数を扱うメソッドのルールとどんな時に使えるかを理解するため


基本的な引数を扱うメソッド

irb(main):001:0> def greeting(country)
irb(main):002:1> if country == 'japan'
irb(main):003:2> 'konnitiwa'
irb(main):004:2> else
irb(main):005:2> 'hello'
irb(main):006:2> end
irb(main):007:1> end
=> :greeting
irb(main):008:0> greeting
Traceback (most recent call last):
        3: from /Users/hiwillowz/.rbenv/versions/2.5.1/bin/irb:11:in `<main>'
        2: from (irb):8
        1: from (irb):1:in `greeting'
ArgumentError (wrong number of arguments (given 0, expected 1))
irb(main):009:0> greeting('japan')
=> "konnitiwa"
irb(main):010:0> greeting('usa')
=> "hello"

デフォルトで引数()を設定せずにメソッドだけ呼び出すとエラーが出ます。
ただArgumentErrorは引数に関するエラーという原因がすぐわかるのでそんなに深刻なエラーでは無いと思います。

irb(main):023:0> def greeting(country = 'japan')
irb(main):024:1> country == 'japan'? 'konnitiwa':'hello';
irb(main):025:1> end
=> :greeting
irb(main):021:0> greeting
=> "konnitiwa"
irb(main):022:0> greeting('england')
=> "hello"

下から二番目の行ですね、デフォルトで引数を設定したためgreetingだけでもエラーにならずに返り値がでてきてます。
ちなみに三項演算子を使って先程のコードをリファクタリングしています。


可変長引数

可変長?パッと見よくわからないですけれど、個数に制限の無い引数のことを可変長引数と言い、この可変長引数を使う時は*を引数の前につける必要があるらしいです。

irb(main):049:0> def greeting(*names)
irb(main):050:1> "#{names.join('&')}\,Hello!"
irb(main):051:1> end
=> :greeting

irb(main):052:0> greeting('Mr_Johnson')
=> "Mr_Johnson,Hello!"

irb(main):053:0> greeting('Mr_Johnson','Miss_Smith')
=> "Mr_Johnson&Miss_Smith,Hello!"

コードを書いてもよくわからないけど、とりあえず今は個数に制限が無いのとメソッドや配列と一緒に使うってことを覚えとく。


メソッドのキーワード引数とハッシュ

こちらも複数の引数を設定するものですが、可変長引数が配列や展開する場合に使うのに対してキーワード引数は真偽値などの処理を行う複数の引数を設定するもの?ですかね(ふわっとしかわからない...)

irb(main):065:0> def dinner(main, drink, desert)
irb(main):066:1> if drink
irb(main):067:2> end
irb(main):068:1> if desert
irb(main):069:2> end
irb(main):070:1> end
=> :dinner

irb(main):071:0> dinner('cheken', true, true)
=> nil

irb(main):072:0> dinner('fish')
Traceback (most recent call last):
        3: from /Users/hiwillowz/.rbenv/versions/2.5.1/bin/irb:11:in `<main>'
        2: from (irb):72
        1: from (irb):65:in `dinner'
ArgumentError (wrong number of arguments (given 1, expected 3))

2行目のdinner('cheken', true, true)何に対してのtrueなのかメソッドを見直さないといけないのでとても読みにくいです。
引数を指定しないとデフォルトの値を設定していないのでArgumentErrorが出ましたね。

irb(main):073:0> def dinner(main, drink: true, desert: false)
irb(main):074:1> if drink
irb(main):075:2> end
irb(main):076:1> if desert
irb(main):077:2> end;end
=> :dinner

irb(main):078:0> dinner('fish')
=> nil

irb(main):084:0> params = {drink: false, desert: false}
=> {:drink=>false, :desert=>false}
irb(main):085:0> dinner('water', params)
=> nil

第2、第3引数をハッシュで指定することで読みやすくなったのとデフォルト値を設定したので読みやすくなりました。
後はキーワード引数と一致するハッシュであればメソッドの引数として渡すことが出来る。


ハッシュを使った疑似キーワード引数

def dinner(main, options = {})
irb(main):097:1> drink = options[:drink]
irb(main):098:1> desert = options[:desert]
irb(main):099:1> if drink
irb(main):100:2> end
irb(main):101:1> if desert
irb(main):102:2> end
irb(main):103:1> end
=> :dinner

irb(main):104:0> dinner('fish')
=> nil

irb(main):105:0> dinner('meet', salad: true)
=> nil

キーワード引数にハッシュを置いてメソッド内で引数を設定するのが擬似キーワード引数?、とりあえずメソッド内で設定されてないキーワードを渡してもエラーがでないので、普通のキーワード引数を使った方が無難。


任意のキーワードを受け取る引数

irb(main):107:0> def dinner(main, drink: true, desert: true, **others)
irb(main):108:1> puts others
irb(main):109:1> if drink
irb(main):110:2> end
irb(main):111:1> if desert
irb(main):112:2> end
irb(main):113:1> end
=> :dinner

irb(main):114:0> dinner('cheken', drink: true, desert: false, soup: true)
{:soup=>true}
=> nil

irb(main):116:0> dinner('fish')
{}
=> nil

キーワード引数を使うメソッドに無いキーワードを渡す時に**をつけた引数を最後に用意することで、**引数にはキーワード引数で指定されていないキーワードがハッシュとして格納されるというもの。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away