1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Rake, Itamae, Rspec, Thor の DSL 評価の方式

Posted at

自分で DSL 処理を描きたくなった時に、どうやるのが良いのかあまり自明じゃなかったので、DSL っぽいことができる有名な ruby のフレームワークに対して、それぞれがどのように DSL を評価しているのかを調べてみた際の、メモ。

Rake

rake/lib/rake/dsl_definition.rb
# self はトップレベルオブジェクト、つまり main
self.extend Rake::DSL

main オブジェクトに対する特異メソッドとして、もろもろの DSL メソッドを追加する方式。

Itamae

itamae/lib/itamae/recipe.rb
    def load(vars = {})
      context = EvalContext.new(self, vars)
      context.instance_eval(File.read(path), path, 1)
    end

File を read しながら、評価用オブジェクト上で instance_eval する方式。

Rspec

rspec-core/lib/rspec/core/dsl.rb
      # @private
      def self.expose_example_group_alias_globally(method_name)
        change_global_dsl do
          remove_method(method_name) if method_defined?(method_name)
          define_method(method_name) { |*a, &b| ::RSpec.__send__(method_name, *a, &b) }
        end
      end

      # @private
      def self.change_global_dsl(&changes)
        (class << top_level; self; end).class_exec(&changes)
        Module.class_exec(&changes)
      end
    end
  end
end

# Capture main without an eval.
::RSpec::Core::DSL.top_level = self

main オブジェクトの特異クラスに対して define_method などを行っている

Thor

class CLI < Thor
  desc 'foo', 'foooo'
  def foo
    puts :foo
  end
end

クラスを継承させるスタイル。

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?