🖥

Ruby | クラスに言語要素的メソッドを実装する ( メタプログラミングRuby )

2023/08/26に公開

課題

こういう attr_accesor みたいなものは、自分で作れるのだろうか?

class Programming
  attr_accesor :ruby
end

回答

作れる。
実はすごく簡単で、クラスメソッドを定義するだけで良い。

class Programming
  def self.flexible(language)
    puts "#{language} is so Flexible!"
  end

  flexible :ruby # ruby is so Flexible!
end

だがこの書き方だと、順番を反対にすると動かない。

class Programming
  flexible :ruby # undefined method `flexible' for Programming:Class (NoMethodError)

  def self.flexible(language)
    puts "#{language} is so Flexible!"
  end
end

クラスの先頭で使いたい

継承を使うとクラスの先頭で書ける。

class Flexible
  def self.flexible(language)
    puts "#{language} is so Flexible!"
  end
end

class Programming < Flexible
  flexible :ruby # ruby is so Flexible!
end

オープンクラスで二回同じクラスを開いてみても、同じようなことが出来る。

class Programming
  def self.flexible(language)
    puts "#{language} is so Flexible!"
  end
end

class Programming
  flexible :ruby # ruby is so Flexible!
end

ちなみに

既存の言語要素的メソッドも上書きできたりする。

class Programming
  def self.attr_accessor(language)
    puts "Hacked accessor! can not set #{language}"
  end
  
  attr_accessor :ruby # Hacked accessor! can not set ruby
end

programming = Programming.new
programming.language = :ruby # undefined method `language=' for #<Programming:0x007f8a6b170f28> (NoMethodError)

環境

  • ruby 2.3.1

参考

  • メタプログラミングRuby 第二版

チャットメンバー募集

何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ

Twitter

https://twitter.com/YumaInaura

公開日時

2017-03-18

Discussion