親クラスの同名メソッドを呼ぶsuperについてです。
例えば以下のような場合
class User def login(acount, password) ~ログイン処理~ end end class AdminUser < User def login(password) ~ログイン処理~ ~固有の処理~ end end
AdminUserクラスではログインメソッドの中で、親クラスであるUserとログイン処理を共有しています。
同じ処理をなんども書きたくないので、親クラスのログインメソッドを呼びたい。そんなときに使うのがsuperです。
スポンサーリンク
class AdminUser < User def login(password) super('admin', password) ~固有の処理~ end end
便利なsuperですが、実はsuperはメソッドではなく、Rubyのキーワードになっており、引数のように見えているのはオプションなのです。
superはかっこがある場合、ない場合で挙動が変わるので、メソッドだと思って使っていると予期せぬ不具合が出てくるかもしれません。
superのふるまいを3つ書いておきたいと思います。
- 引数あり
super(account, password)
のように使うと、accountとpasswordをそのまま親クラスのメソッドに渡します。
もっとも基本的な使い方です。
また、メソッドと同じようにかっこを省略して書くことができます。
super account, password
- かっこなし・引数なし
super
とだけ書くとどうなるでしょう。
class AdminUser < User def login(account, password) super ~固有の処理~ end end
このときは、呼び出し元のメソッド(AdminUserのloginメソッド)の引数(accountとpassword)をそのまま親クラスのメソッドに渡します。
なので、もしAdminUserのloginメソッドの引数が1つや3つ以上だった場合には、「ArgumentError: wrong number of arguments (3 for 2)」のようなエラーになります。
- かっこのみ
3つ目は、かっこのみの場合です。
class AdminUser < User def login(account, password) super() ~固有の処理~ end end
この場合は、引数を一つも渡さずにメソッドを実行します。
この書き方は、例えば親クラスが引数なしの場合に使います。
上述の通り、かっこ・引数なしの場合だと、呼び出し元の引数を渡してしまうので、ArgumentErrorになってしまいます。
superを使うときは、引数の渡し方を把握し、あいまいな書き方をしないようにしましょう。
次に、superで呼び出されるメソッドの探索についてです。
いやいや、親クラスのメソッドだろうと思うかもしれませんが(僕はそう思っていました)、実は継承階層全体、すなわちモジュールを含めた継承を順にたどって通常のメソッドと同様の探索を行っていきます。
module Account def login(account, password) ~何か処理~ end end class User def login(account, password) ~何か処理~ end end class AdminUser < User include(Account) def login(account, password) super ~何か処理~ end end
このような場合、うっかりUserのloginメソッドが呼ばれるかと思いきや、Accountモジュールのloginメソッドが呼ばれるのです。
メソッド探索の話は以下の記事を参照してください。
- 作者: Peter J. Jones,arton,長尾高弘
- 出版社/メーカー: 翔泳社
- 発売日: 2015/01/09
- メディア: 大型本
- この商品を含むブログ (13件) を見る
Ruby on Rails 5アプリケーションプログラミング
- 作者: 山田祥寛
- 出版社/メーカー: 技術評論社
- 発売日: 2017/04/14
- メディア: 大型本
- この商品を含むブログを見る
プロを目指す人のためのRuby入門 言語仕様からテスト駆動開発・デバッグ技法まで (Software Design plusシリーズ)
- 作者: 伊藤淳一
- 出版社/メーカー: 技術評論社
- 発売日: 2017/11/25
- メディア: 大型本
- この商品を含むブログを見る