prepend とメソッド探索
祖先チェーンを学びます。
「prepend とメソッド探索」はCoddyKit上の無料Ruby Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはRuby Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Ruby Academyコースには全4レッスンが含まれています。
祖先チェーン
メソッドを呼び出すと、Rubyは祖先チェーンと呼ばれるリストを検索します。最初に見つかった一致する定義が使われます。このチェーンを理解すると、ミックスインと継承がどのように連携するかが分かります。
class Animal; end
class Dog < Animal; end
p Dog.ancestorsメソッドの探索順序
Rubyはまずオブジェクトのクラスを検索し、次にそのクラスにインクルードされたモジュール、さらにスーパークラスという順に、メソッドが見つかるまでチェーンをたどって検索します。
module M
def hello; "from module"; end
end
class C
include M
def hello; "from class"; end
end
puts C.new.helloinclude はクラスの下に入る
includeされたモジュールは、チェーン内でクラスのすぐ下に置かれます。クラス自身のメソッドがモジュールのメソッドより優先されます。
module M; end
class C
include M
end
p C.ancestors # [C, M, Object, ...]prepend の登場
prependは、チェーン内でモジュールをクラスの上に挿入します。これにより、クラス自身のメソッドよりも前に、モジュールのメソッドが先に見つかります。
module M
def hello; "from module"; end
end
class C
prepend M
def hello; "from class"; end
end
puts C.new.helloチェーン内の prepend
祖先を調べて、prependによってモジュールがクラスの前に置かれていることを確認しましょう。
module M; end
class C
prepend M
end
p C.ancestors # [M, C, Object, ...]prepend したモジュールからの super
prependされたモジュールは先に実行されるため、superを呼び出して元のメソッドに到達し、クラスのメソッドをラップできます。動作の装飾に最適な方法です。
module Logged
def save
puts "before save"
result = super
puts "after save"
result
end
end
class Record
prepend Logged
def save
puts "saving record"
:ok
end
end
p Record.new.saveミックスインでの super
superは祖先チェーンに従います。インクルードされたモジュールから呼び出すとスーパークラスに到達し、prependされたモジュールから呼び出すとクラス自体に到達します。
module Polite
def greet; "Hi! " + super; end
end
class Person
prepend Polite
def greet; "I am here."; end
end
puts Person.new.greet編集せずにラップする
prependを使うと、元のクラスのコードを変更せずに既存のメソッドの前後へ動作を追加できます。モンキーパッチの、より明確な代替手段です。
module Timing
def compute(n)
puts "start"
super
end
end
class Calc
prepend Timing
def compute(n); n * n; end
end
puts Calc.new.compute(5)複数モジュールの順序
複数のモジュールをインクルードした場合、最後にインクルードしたモジュールがクラスに最も近い位置に置かれ、最初に検索されます。
module A; def who; "A"; end; end
module B; def who; "B"; end; end
class C
include A
include B
end
puts C.new.who # B wins (included last)
p C.ancestorsinclude と prepend のまとめ
並べて比較すると、次のようになります。
include M:チェーンは[Class, M, ...]となり、クラスのメソッドが優先されます。prepend M:チェーンは[M, Class, ...]となり、モジュールのメソッドが優先され、クラスへsuperできます。
module M; end
class Inc; include M; end
class Pre; prepend M; end
p Inc.ancestors
p Pre.ancestorsまとめ
メソッドの解決は祖先チェーンに従います。
- クラスのメソッドは、インクルードされたモジュールより優先されます。
- prependされたモジュールは、クラスより優先されます。
superはチェーンを1つ上にたどります。
module Cap
def name; super.capitalize; end
end
class User
prepend Cap
def name; "ada"; end
end
puts User.new.name確認
メソッドの解決についての理解度を確認しましょう。
振り返り
メソッドの解決について学びました。
- Rubyは祖先チェーンを上から下へ検索します。
includeはクラスの下に入り、prependはクラスの上に入ります。superはチェーンを上にたどり、次の定義に到達します。prependを使うと、メソッドをきれいにラップできます。
module Loud
def speak; super.upcase; end
end
class Bot
prepend Loud
def speak; "beep"; end
end
puts Bot.new.speakよくある質問
「prepend とメソッド探索」レッスンは無料ですか?
はい。「prepend とメソッド探索」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Ruby Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Ruby Academyコースには全4レッスンが含まれています。
「prepend とメソッド探索」で何を学びますか?
祖先チェーンを学びます。 ブラウザで直接実行するハンズオンコードでRuby Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Ruby Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのRuby Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。
「prepend とメソッド探索」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このRuby Academyレッスンでコードを書いて実行できますか?
はい。すべてのRuby Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- モジュールの定義
- include と extend
- Comparable と Enumerable
- prepend とメソッド探索