LoginSignup
18
20

More than 5 years have passed since last update.

メタプログラミングRubyメモ

Posted at

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

とかできるようになるわけ。

18
20
0

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
  3. You can use dark theme
What you can do with signing up
18
20