LoginSignup
0

posted at

updated at

「たのしいRuby」モジュールとMix-in

Rubyの本、買ってきた。「たのしいRuby」勉強しながらtwitterに投稿した文を加筆訂正してQiitaに投稿する。今回はモジュール。
Twitter、Green_helmet@bethlehem4099
Qiita、@dosaidon

参考文献

この記事は以下の情報を参考にして執筆しました。
-たのしいRuby、高橋征義、後藤裕蔵著、 まつもとゆきひろ監修、SBクリエイティブ株式会社、第6版2019年
-『たのしいRuby 第6版』サポートページ、ソースコード

つぎ、Module

Rubyの売り、モジュール。

mixin_sample.rb
module M
   def m_p
      p "m_p"
   end
   module_function:m_p
end

class A
    include M
    def a
        M.m_p
    end
end

class B
    include M
    def b
        M.m_p
    end
end

a=A.new
b=B.new
a.a
b.b
command_line
➜  ruby mixin_sample.rb
"m_p"
"m_p"

クラスに似ていてクラスでは無いRubyしか無い新しい概念。使うにはmodule_function:モジュール名を宣言しさらに、includeで取り込む必要がある。

モジュールは処理の部分だけをまとめる
モジュールはインスタンスを持つことができない
モジュールは継承できない

あと、例題は動くリストにしてほしい

名前空間

モジュールは名前空間を提供する。

モジュール名.メソッド名
モジュール名::定数名
name_space.rb
p Math.sqrt(2)
p Math::PI
commnad_line
➜  ruby name_space.rb
1.4142135623730951
3.141592653589793

独立した名前空間。はい。
Green_helmet@bethlehem4099·8月21日

モジュールを作る

hello_module.rb
module HelloModule
    Version=1.0
    def hello(name)
        puts "hello, #{name}!"
    end
    module_function:hello
end

puts HelloModule::Version
HelloModule.hello("Alice")
command_line
➜  ruby hello_module.rb
1.0
hello, Alice!

はい、なお定数は大文字始まり。

待って、module_function?module_methodじゃないの?
Moduleの中ではfunctionでClassの中ではmethodということ?

Green_helmet@bethlehem4099·8月23日

脱線、Moduleの中でClassを作りインスタンスを動かせるか?

class_in_module.rb
module M
    class HelloWorld10
        class << self
            def  hello(name)
                puts "#{name} said hello."
            end
        end
    end

    def m_p
       HelloWorld10.hello("John")
    end
    module_function:m_p
end
# mixin_include_question.rb
module M
   def m_p
      p "m_p"
   end
   module_function:m_p
end

class C
    include M
    def a
        M.m_p
    end
end

p C.include?(M)
p C.ancestors
p C.superclass

「モジュールをインクルードしたか?」
「祖先は?」
「スーパークラスは?」

➜  ruby mixin_include_question.rb
true
[C, M, Object, Kernel, BasicObject]
Object

はい。モジュールをincludeしており、先祖は[C, M, Object, Kernel, BasicObject]。スーパークラスはObjext。
モジュールの中でクラスを定義出来る。
Green_helmet@bethlehem4099·8月28日

つぎ、prepend

Green_helmet@bethlehem4099·8月30日

mixin_prepend.rb
module M
   def m_p
      p "m_p"
   end
   module_function:m_p
end

class C
    include M
    def a
        M.m_p
    end
end

class D
    prepend M
    def a
        M.m_p
    end
end

puts "include"
p C.include?(M)
p C.ancestors
p C.superclass
puts  "\nprepend"
p D.include?(M)
p D.ancestors
p D.superclass

Rubyist実行結果

include
true
[C, M, Object, Kernel, BasicObject]
Object

prepend
true
[M, D, Object, Kernel, BasicObject]
Object

Green_helmet@bethlehem4099·8月30日

includeとprepend

はい

Green_helmet@bethlehem4099·8月31日

メソッド検索のルール

はい

modue_edition.rb
module Edition
    def edition(n)
        "#{self}#{n}版"
    end
end
str = "たのしいRuby"
str.extend(Edition)
p str.edition(6)
command_line
➜  ruby module_edition.rb
"たのしいRuby 第6版"

extendメソッドでモジュールをオブジェクトに追加する

はい

Green_helmet@bethlehem4099·9月5日

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
0