次のコードを検討してください。
module ModName
def aux
puts 'aux'
end
end
に置き換えるmodule
とclass
、次のことができます。
ModName.new.aux
ただし、モジュールをインスタンス化することはできません。aux
モジュールのメソッドを呼び出す方法はありますか?
とは何かを考えてみてくださいaux
。どのオブジェクトに応答しaux
ますか? これはインスタンス メソッドです。つまり、ModName を含むクラスのインスタンスがそれに応答します。ModName モジュール自体は、そのようなクラスのインスタンスではありません。ModName をクラスとして定義した場合も、これは機能しません。インスタンスなしでインスタンス メソッドを呼び出すことはできません。
モジュールは、動作を追加するために他のクラスに混合できるクラスによく似ています。クラスがモジュールに混在すると、モジュールのすべてのインスタンス メソッドがクラスのインスタンス メソッドになります。これは、多重継承を実装する方法です。
各モジュールは名前空間を定義するため、名前空間の代替としても機能します。しかし、それは少し関係がありません。(ちなみに、クラスにも独自の名前空間がありますが、それをクラスにすることは、そのインスタンスを作成することを意味するため、その目的には概念的に間違っています。)
次の方法で実行できます。
module ModName
def aux
puts 'aux'
end
module_function :aux
end
そして、それを呼び出すだけです:
ModName.aux
あなたも言うことができます
module ModName
extend self
def aux
puts 'aux'
end
end
その後、通常どおりモジュールをインクルードできますが、ModName を介してメソッドを呼び出すこともできます。
モジュール定義は「これは...」と評価されます、なぜですか?
Rubyでは、すべてが式であり、ステートメントや宣言はありません。これは、すべてが値に評価されることを意味します。(ただし、これは必ずしも有用な値に評価されることを意味するわけではありません。たとえば、メソッドは、メソッド定義式と同じように、puts
常にに評価されます(Rubiniusでは、式が定義されているメソッドのオブジェクトに評価されます)。 。)nil
def
def
CompiledMethod
それで、すべてが値に評価される場合、モジュール定義式は何に評価されるべきですか?さて、いくつかの候補があります:それはnil
、メソッド定義式のように、と評価することができます。または、モジュールオブジェクト自体を評価することもできます。結局のところ、これが私たちが定義していることですよね?しかし実際には、Matzは3番目のオプションを選択しました。モジュール(およびクラス)定義式は、モジュール定義本体内の最後の式が評価するものに実際に評価されます。(これにより、モジュール定義本体内にnil
またはを最後の式として配置するだけで、他の2つの可能性を簡単にシミュレートできます。)self
あなたの場合、モジュール定義本体内の最後の式は割り当てです。しかし、割り当て?それは一体何を返しますか?それは声明ではありませんか?いいえ、Rubyではありません。すべてが式であり、代入も例外ではありません。代入式は、右側が評価するものに評価されます。ここで、代入式の右辺は文字列リテラルであり、文字列オブジェクトに評価されます。
したがって、モジュール定義式全体が文字列に評価されます'this is a const in module'
。
そしてもう少し...
module Y
def Y.a
puts "a"
end
def Y.b
c
end
def self.c
puts "b -- c"
end
end
呼び出し (「.new」なし):
Y.a #=> "a"
Y.b #=> "b -- c"
Y.c #=> "b -- c"
class Foo
include ModName
end
Foo.new.aux
# output: aux