モジュールのクラス。
成果物
情報源
Module
特異メソッド
constants nesting new used_modules
インスタンスメソッド
< <= <=> === > >= alias_method ancestors attr attr_accessor attr_reader attr_writer autoload autoload? class_eval class_variable_defined? class_variables const_defined? const_get const_missing const_set const_source_location constants define_method freeze include include? included_modules inspect instance_method instance_methods method_defined? module_eval name prepend private_class_method private_instance_methods private_method_defined? protected_instance_methods protected_method_defined? public_class_method public_instance_method public_instance_methods public_method_defined? remove_class_variable remove_method to_s undef_method
privateメソッド
append_features class_exec class_variable_get class_variable_set deprecate_constant extend_object extended included method_added method_removed method_undefined module_exec module_function prepend_features prepended private private_constant protected public public_constant refine remove_const ruby2_keywords singleton_class? using
constants
このメソッドを呼び出した時点で参照可能な定数名の配列を返します。
class C FOO = 1 end p C::FOO #=> 1 FOOは参照可能 p Module.constants #=> [...] 内にFOOがない p Module.constants.include? :FOO #=> false p Module::constants.include? :FOO #=> false
いやいや、何でFOO
がないんだよ。constants
メソッドを呼び出す前にちゃんと参照できているはずなのに。使えねー。
と思って定義内でやってみたらFOO
があった。
class C FOO = 1 p Module.constants.include? :FOO #=> true end
どゆこと? 特異メソッドだから?
nesting
このメソッドを呼び出した時点でのクラス/モジュールのネスト情報を配列に入れて返します。
module Foo module Bar module Baz p Module.nesting #=> [Foo::Bar::Baz, Foo::Bar, Foo] end end end p Module.nesting #=> []
やはり定義外だと空になる。constants
と同じで定義内でのみ有効らしい。
new
名前の付いていないモジュールを新しく生成して返します。
ブロックが与えられると生成したモジュールをブロックに渡し、モジュールのコンテキストでブロックを実行します。
mod = Module.new mod.module_eval {|m| # ... } mod
そんなことができたのか。でも使わなそう。
最初に名前が必要になったときに名前が決定します。モジュールの名前は、そのモジュールが代入されている定数名のいずれかです。
m = Module.new p m # => #<Module 0lx40198a54> p m.name # => nil # まだ名前は未定 Foo = m # m.name # ここで m.name を呼べば m の名前は "Foo" に確定する Bar = m p m.name # "Foo" か "Bar" のどちらかに決まる
私の環境ではFoo
になった。というか、なんでどちらかなの? 曖昧なので罠になりそう。
used_modules
現在のスコープで using されているすべてのモジュールを配列で返します。配列内のモジュールの順番は未定義です。
module A refine Object do end end module B refine Object do end end using A using B p Module.used_modules #=> [B, A]
まずusing
ってなんだよ。refine
ってなんだよ。
さっぱりわからん。
refine
は以下の用途らしい。
既存の機能を局所的に修正したい場合などに用いる事ができます。
でも、なんでそんなことをしたがるのかよくわからん。ややこしくなるばかりでは?
ancestors
クラス、モジュールのスーパークラスとインクルードしているモジュールを優先順位順に配列に格納して返します。
継承リスト。同一名メソッドを呼び出すときのレシーバを決定する。先頭ほど優先度が高い。
attr
, attr_accessor
, attr_reader
, attr_writer
メソッド | ゲッター | セッター |
---|---|---|
attr |
⭕ | ❌ |
attr_reader |
⭕ | ❌ |
attr_writer |
❌ | ⭕ |
attr_accessor |
⭕ | ⭕ |
attr
の第二引数にtrue
を渡してセッターも加えることができるが、非推奨。
class C attr :name, :age end
class C attr_reader :name, :age end
class C attr_writer :name, :age end
class C attr_accessor :name, :age end
定義されるゲッターは以下。
def name @name end
定義されるセッターは以下。
def name=(val) @name = val end
これこそClassクラスのメソッドかと思っていたんだが。Moduleクラスのメソッドということは、module
内でも同じように定義できるはず。でも、ModuleはClassと違ってインスタンス化できない。ほかのクラスにMixinしないと使えない。なので基本的にModuleでは使わずClassで使うのだろう。だったらなんでModuleクラスに定義されているのか疑問。ModuleクラスはClassクラスのスーパークラスらしいけど、どうせModuleで使わないならClassクラスで定義すればよかったのでは? なのにModuleクラスで定義されているということは、Moduleでもattr
したいときがあるってことだと思う。
module
でもattr
できるはず。と思ってやってみたら、エラーになった。
module A attr_accessor :name end class B include A end b = B.new p b.name #=> nil b.name = 'ytyaru' B.b.name #=> undefined method `b' for B:Class (NoMethodError)
なんでや。
所感
他にもメタいメソッドが色々あるが、今回はここまで。
対象環境
- Raspbierry pi 4 Model B
- Raspberry Pi OS buster 10.0 2020-08-20 ※
- bash 5.0.3(1)-release
- Ruby 3.0.2
$ uname -a Linux raspberrypi 5.10.52-v7l+ #1441 SMP Tue Aug 3 18:11:56 BST 2021 armv7l GNU/Linux