Object#extend
module MyModule
def my_method; 'hello'; end
end
を使いたいときに
class MyClass
class << self
include MyModule
….
end
end
↓
class MyClass
extend MyModule
….
end
これでもMyClassの特異メソッドとしてmy_methodを呼べる。
( MyClass.my_method #=> 'hello' )
falseの時なにか決まったものを返すとき、三項演算子じゃなくていいよ!的な
class MyClass
def initialize
@hoge = false
end
def hoge?
@hoge || false
end
end
irb(main):009:0> MyClass.new
=> #<MyClass:0x007ff499890fe0 @hoge=false>
irb(main):010:0> a = MyClass.new
=> #<MyClass:0x007ff49987a8d0 @hoge=false>
irb(main):011:0> a.hoge?
=> false
って感じでいける。or演算子やから当たり前やけど、こう書けてなかったな、、っていう自分のレベルの低さを感じたのでメモ
alias :m(新しいメソッド名) :my_method(古いメソッド名)
★アラウンドエイリアス
module Kernel
alias gem_original_require require
def require(path)
gem_original_require path
rescue LoadError => load_error
if load_error.message =~ /#{Regexp.escape path}\z/ and
spec = Gem.searcher.find(path) then
Gem.activate(spec.name, "= #{spec.version}")
gem_original_require path
else
raise load_error
end
end
end
エイリアスは元のメソッドを変更するのではなく、新しいメソッドを定義して元のメソッドの名前をつける。
なので元のものをラップして新しいのに飛ばすようなことができてアラウンドエイリアスと呼ぶ。
クラスマクロ
クラスマクロはクラス定義の中で使えるクラスメソッド
class Book
def self.deprecate(old_method, new_method)
..
end
deprecate :GetTitle, :title
end
attr_accessorとかがそう。
module CheckedAttributes
def self.included(base)
base.extend ClassMethods # baseにはincludeしたクラスが入ってくるのでそれにたいしてClassMethodsを渡してる。
# こうすることで渡ってきたクラスのクラスメソッドにClassMethodsを設定できる
end
module ClassMethods
def attr_checked(attribute, &validation)
define_method "#{attribute}=" do |value|
raise 'Invalid attribute' unless validation.call(value)
instance_variable_set("@#{attribute}", value)
end
define_method attribute do
instance_variable_get "@#{attribute}"
end
end
end
end
これで
class Person
include CheckedAttributes
attr_checked :age do |v|
v >= 18
end
end
とかできるようになるわけ。