Hatena::Grouprubyist

Rubyをラクガク(正規表現編) RSSフィード

2009-01-17

[]module関数 module関数 - Rubyをラクガク(正規表現編) を含むブックマーク はてなブックマーク - module関数 - Rubyをラクガク(正規表現編) module関数 - Rubyをラクガク(正規表現編) のブックマークコメント

moduleがネストされている場合、内側のmoduleから外側のmoduleのメソッドを呼び出したい。というのも、外側のモジュールに、内側のモジュールから呼び出す共通メソッドを定義したいから。

module A
  def hoge
    puts "hoge"
  end
  module B
    def foo
      puts "foo"
      hoge
    end
  end
end

class Bar
  include A::B
  def bar
    foo
  end
end

Bar.new.bar
foo
test2.rb:8:in `foo': undefined local variable or method `hoge' for #<Bar:0xb7d3f6f0> (NameError)
        from test2.rb:16:in `bar'
        from test2.rb:20

やはり普通には見えないのか。外側のモジュールでself.hogeとしてモジュール関数にしておいて、Bの方でA.hogeとして呼び出せばいける。

module A
  def self.hoge
    puts "hoge"
  end
  module B
    def foo
      puts "foo"
      A.hoge
    end
  end
end

class Bar
  include A::B
  def bar
    foo
  end
end

Bar.new.bar
foo
hoge

[]内側のmoduleから外側のmoduleを参照する 内側のmoduleから外側のmoduleを参照する - Rubyをラクガク(正規表現編) を含むブックマーク はてなブックマーク - 内側のmoduleから外側のmoduleを参照する - Rubyをラクガク(正規表現編) 内側のmoduleから外側のmoduleを参照する - Rubyをラクガク(正規表現編) のブックマークコメント

X::A::Bというモジュールがあり、BからAのモジュール関数を呼び出す際、A.hogeとかで呼び出すことができる。

module X
  module A
    def self.hoge      puts "hoge"
    end

    module B
      def foo
        puts "foo"
        A.hoge
      end
    end
  end
end

class Bar
  include X::A::B
  def bar
    foo
  end
end

Bar.new.bar
foo
hoge

AlinaAlina2012/05/23 07:08Good to see a tealnt at work. I can't match that.

ihcbltmihcbltm2012/05/23 15:32qqA7x6 <a href="http://cpmdrzpftdlo.com/">cpmdrzpftdlo</a>

idpojnidpojn2012/05/23 20:17gVtmZ3 , [url=http://ekgfbutynahu.com/]ekgfbutynahu[/url], [link=http://ouztulkatrjb.com/]ouztulkatrjb[/link], http://rupvlmoxyebi.com/

fhznmvafhznmva2012/05/26 20:21v36pvv , [url=http://vjrcdckwwxyy.com/]vjrcdckwwxyy[/url], [link=http://rrtsszjhifre.com/]rrtsszjhifre[/link], http://hpxpaxrcgvaz.com/

2008-01-061年振りくらいのエントリ

[]self.included self.included - Rubyをラクガク(正規表現編) を含むブックマーク はてなブックマーク - self.included - Rubyをラクガク(正規表現編) self.included - Rubyをラクガク(正規表現編) のブックマークコメント

moduleのメソッドとしてself.includedというメソッドを定義しておくと、そのmoduleがincludeされた時に呼ばれる。って知らなかった。

masayuki% irb                                                                                       [~]
irb(main):001:0> module Hoge
irb(main):002:1> def self.included(base)
irb(main):003:2> puts "included by #{base}."
irb(main):004:2> end
irb(main):005:1> end
=> nil
irb(main):006:0> class Foo
irb(main):007:1> include Hoge
irb(main):008:1> end
included by Foo.
=> Foo

2007-01-21moduleのメソッド

[]moduleのメソッド moduleのメソッド - Rubyをラクガク(正規表現編) を含むブックマーク はてなブックマーク - moduleのメソッド - Rubyをラクガク(正規表現編) moduleのメソッド - Rubyをラクガク(正規表現編) のブックマークコメント

久々のエントリ

moduleのinitializeで初期化を行うとしたら、そのmoduleインクルードするクラスによって初期化ができたりできなかったりしたので、サンプルコードを書いてみた。

module Hoge
	def initialize()
		puts 'Hoge initialized.'
	end
end

class Foo
	include Hoge
end

class Bar
	include Hoge

	def initialize()
		puts 'Bar initialized'
	end
end

Foo.new
Bar.new
Hoge initialized.
Bar initialized

インクルードするクラスでinitializeメソッドを書いちゃうと、moduleのinitializeメソッドは呼ばれないのか。initializeみたいに、インクルードするクラスで通常実装しちゃうようなメソッドは、module側に書かないってことかなぁ。

インクルードするクラス側でちゃんとsuperを呼び出してあげれば動く

class Bar
	include Hoge

	def initialize()
		super
		puts 'Bar initialized'
	end
end
Hoge initialized.
Hoge initialized.
Bar initialized

けど、インクルードしたmoduleのinitializeは必ず呼び出さないと、module側でちゃんと必要な初期化がなされているか保証できないのって、イマイチな気がするけど。特にJavaコンストラクタと比較すると。

2006-07-03defined?

[]defined? defined? - Rubyをラクガク(正規表現編) を含むブックマーク はてなブックマーク - defined? - Rubyをラクガク(正規表現編) defined? - Rubyをラクガク(正規表現編) のブックマークコメント

定義されていないメソッド、undef されたメソッド、 Module#remove_method により削除されたメソッドのいずれに対しても defined? は偽を返します。

Rubyリファレンスマニュアル

undefでメソッドの定義を除去した場合。

class Foo
        def bar
                puts "called Foo#bar."
        end
end

class Bar < Foo
        def bar
                puts "called Bar#bar."
        end
end

bar=Bar.new
p defined? bar.bar

class Bar
        undef :bar
end

p defined? bar.bar
"method"
nil

Module#remove_methodでメソッドの定義を除去した場合。

class Foo
        def bar
                puts "called Foo#bar."
        end
end

class Bar < Foo
        def bar
                puts "called Bar#bar."
        end
end

bar=Bar.new
p defined? bar.bar

class Bar
        remove_method(:bar)
end

p defined? bar.bar
"method"
"method"

あれ?Foo#barが呼ばれちゃったかな?

じゃあFoo#barの定義もremove_methodで除去してみる。

class Foo
        def bar
                puts "called Foo#bar."
        end
end

class Bar < Foo
        def bar
                puts "called Bar#bar."
        end
end

bar=Bar.new
p defined? bar.bar

class Bar
        remove_method(:bar)
end

p defined? bar.bar

class Foo
        remove_method(:bar)
end

p defined? bar.bar
"method"
"method"
nil

nilってことは偽か。ということは、昨日のundefとModule#remove_methodの結果と似たようなカンジで、undefされると継承元にそのメソッドが定義されているかどうか問わずdefined?は偽で、Module#remove_methodされた場合は継承元で同名のメソッド定義があればdefined?は真、そうでなければ偽。

2006-07-02undef

[]undef undef - Rubyをラクガク(正規表現編) を含むブックマーク はてなブックマーク - undef - Rubyをラクガク(正規表現編) undef - Rubyをラクガク(正規表現編) のブックマークコメント

class Foo
        def bar
                puts "called Foo#bar."
        end
end

class Bar < Foo
        def bar
                puts "called Bar#bar."
        end
end

bar=Bar.new
bar.bar rescue p $!

class Bar
        undef :bar
end

bar.bar rescue p $!
called Bar#bar.
#<NoMethodError: undefined method `bar' for #<Bar:0x401c2890>>

Bar#barをundef後にbar.barを実行すると、Foo#barが呼ばれるかと思いきやNameErrorになる。

undef のより正確な動作は、メソッド名とメソッド定義との関係を取り除き、そのメソッド名を特殊な定義と関連づけます。この状態のメソッドの呼び出しは例えスーパークラスに同名のメソッドがあっても例外 NameError を発生させます。 (一方、メソッド Module#remove_method は、関係を取り除くだけです。この違いは重要です)。

Rubyリファレンスマニュアル

class Foo
        def bar
                puts "called Foo#bar."
        end
end

class Bar < Foo
        def bar
                puts "called Bar#bar."
        end
end

bar=Bar.new
bar.bar rescue p $!

class Bar
        remove_method(:bar)
end

bar.bar rescue p $!
called Bar#bar.
called Foo#bar.

こっちはちゃんとFoo#barが呼ばれる。