Class Blockenspiel::Builder
In: lib/blockenspiel/builder.rb
Parent: Object

Dynamically construct a target

These methods are available in a block passed to Blockenspiel#invoke and can be used to dynamically define what methods are available from a block. See Blockenspiel#invoke for more information.

Methods

Included Modules

::Blockenspiel::DSL

Public Instance methods

Declare a DSL method.

This call creates a method that can be called from the DSL block. Provide a name for the method, a block defining the method‘s implementation, and an optional hash of options.

By default, a method of the same name is also made available to parameterless blocks. To change the name of the parameterless method, provide its name as the value of the :dsl_method option. To disable this method for parameterless blocks, set the :dsl_method option to false.

The :mixin option is a deprecated alias for :dsl_method.

Warning about the return keyword

Because you are implementing your method using a block, remember the distinction between Proc.new and lambda. Invoking return from the former does not return from the block, but returns from the surrounding method scope. Since normal blocks passed to methods are of the former type, be very careful about using the return keyword:

 add_method(:foo) do |param|
   puts "foo called with parameter "+param.inspect
   return "a return value"   # DOESN'T WORK LIKE YOU EXPECT!
 end

To return a value from the method you are creating, set the evaluation value at the end of the block:

 add_method(:foo) do |param|
   puts "foo called with parameter "+param.inspect
   "a return value"    # Returns from method foo
 end

If you must use the return keyword, create your block as a lambda as in this example:

 code = lambda do |param|
   puts "foo called with parameter "+param.inspect
   return "a return value"   # Returns from method foo
 end
 add_method(:foo, &code)

Accepting a block argument

If you want your method to take a block, you have several options depending on your Ruby version. If you are running the standard Matz Ruby interpreter (MRI) version 1.8.7 or later (including 1.9.x), or a compatible interpreter such as JRuby 1.5 or later, you can use the standard "&" block argument notation to receive the block. Note that you must call the passed block using the call method since Ruby doesn‘t support invoking such a block with yield. For example, to create a method named "foo" that takes one parameter and a block, do this:

 add_method(:foo) do |param, &block|
   puts "foo called with parameter "+param.inspect
   puts "the block returned "+block.call.inspect
 end

In your DSL, you can then call:

 foo("hello"){ "a value" }

If you are using MRI 1.8.6, or another Ruby interpreter that doesn‘t fully support this syntax (such as JRuby versions older than 1.5), Blockenspiel provides an alternative in the form of the :block option. This option causes blocks provided by the caller to be included in the normal parameter list to your method, instead of as a block parameter. It can be set to :first or :last to prepend or append, respectively, the block (as a Proc object) to the parameter list. If the caller does not include a block when calling your DSL method, nil is prepended/appended. For example:

 add_method(:foo, :block => :last) do |param, block|
   puts "foo called with parameter "+param.inspect
   if block
     puts "the block returned "+block.call.inspect
   else
     puts "no block passed"
   end
 end

The :receive_block option is a deprecated alternative. Setting :receive_block => true is currently equivalent to setting :block => :last.

[Validate]