読者です 読者をやめる 読者になる 読者になる

まずDSLの勉強を…

ruby

青木さんのruby添削などでDSLの実装例が載っているが、限りなくシンプルなものを…、ということで以下のサイトを見つけた。後で読みます。

読んでみた()。といっても英語はほとんど読んでない。読むの遅いし眠いので。

# The guts of life force within Dwemthy's Array
class Creature

  # Get a metaclass for this class
  def self.metaclass
    class << self
      self
    end
  end

  # Advanced metaprogramming code for nice, clean traits
  def self.traits( *arr )
    return @traits if arr.empty?

    # 1. Set up accessors for each variable
    attr_accessor *arr

    # 2. Add a new class method to for each trait.
    arr.each do |a|
      metaclass.instance_eval do
        define_method( a ) do |val|
          @traits ||= {}
          @traits[a] = val
        end
      end
    end

    # 3. For each monster, the `initialize' method
    #    should use the default number for each trait.
    class_eval do
      define_method( :initialize ) do
        self.class.traits.each do |k,v|
          instance_variable_set("@#{k}", v)
        end
      end
    end

  end

  # Creature attributes are read-only
  traits :life, :strength, :charisma, :weapon
end

こうしておいて

irb(main):001:0> require 'creature'
=> true
irb(main):002:0> class Dragon < Creature
irb(main):003:1>   life 1340      # tough scales
irb(main):004:1>   strength 451   # bristling veins
irb(main):005:1>   charisma 1020  # toothy smile
irb(main):006:1>   weapon 939     # fire breath
irb(main):007:1> end
=> 939
irb(main):008:0> drgn = Dragon.new
=> #
irb(main):009:0> drgn.life = 567
=> 567
irb(main):010:0> p drgn
#
=> nil
irb(main):011:0> drgn['weapon']=888
NoMethodError: undefined method `=' for #
        from (irb):11
        from :0
irb(main):012:0> drgn[:weapon]=888
NoMethodError: undefined method `=' for #
        from (irb):12
        from :0
irb(main):013:0> drgn[weapon]=888
NameError: undefined local variable or method `weapon' for main:Object
        from (irb):13
        from :0
irb(main):014:0> drgn(weapon)=888
SyntaxError: compile error
(irb):14: syntax error, unexpected '=', expecting $end
drgn(weapon)=888
             ^
        from (irb):14
        from :0
irb(main):015:0> drgn.weapon(888)
ArgumentError: wrong number of arguments (1 for 0)
        from (irb):15:in `weapon'
        from (irb):15
        from :0
irb(main):016:0> class Slime < Creature
irb(main):017:1>   life 5       # tough scales
irb(main):018:1>   strength 4   # bristling veins
irb(main):019:1>   charisma 12  # toothy smile
irb(main):020:1>   weapon 3     # fire breath
irb(main):021:1> end
=> 3
irb(main):022:0> slime = Slime.new
=> #
irb(main):023:0> slime.charisma() = 26
SyntaxError: compile error
(irb):23: syntax error, unexpected '=', expecting $end
slime.charisma() = 26
                  ^
        from (irb):23
        from :0
irb(main):024:0>

今日の実験ここまで、いろいろと考えるのは後日。
とりあえず意味がわかってないのは以下のコード。

  # Get a metaclass for this class
  def self.metaclass
    class << self
      self
    end
  end