Archive for the ‘api design’ Category

blocks parameters list and metaprogramming

I have been playing with a Aquarium, the new AOP framework in Ruby. A point advice is create for example :

before :type=>A, :method=>:foo do |execution_point, *args|
  self.some_method() # call a class method from A
  other_method()     # call other class method from A
  # call a method from the caller object
  execution_point.context.advised_object.bar()  
end 

The DSL is nice but i found the access to the caller object is a tedious. I prefer something like this :

before :type=>A, :method=>:foo do |execution_point,this , *args|
  self.some_method() # call a class method from A
  other_method()     # call other class method from A
  # call a method from the caller object
  this.bar()  
end 

Dean Wampier think thats would be great if the user could specify combinations
like these:

|join_point, the_self, *method_args|
|join_point|
|the_self|
|the_self, *method_args|
|join_point, the_self|
|join_point, *method_args|

But the point is that the advices is create in the “definition time class” using some code generation at
runtime. How can i know the arity of the argument list.

module Kernel  
  def before (name, &block) 
    define_method(name){ 
      if block.arity == 1
        yield :only_one
      elsif  block.arity == 2
        yield :one,:two
      elsif block.arity == -2
        yield :one, :a , :splater, :argument
      end
    }
  end
end

class A  
  before :foo do |first|   
    puts first
  end
end

a = A.new 
a.foo

class A
  before :foo do |first , second|
    puts second
  end
end

a2 = A.new 
a2.foo

class A
  before :foo do |first , *splat_arg| 
    puts splat_arg
  end
end

a3 = A.new 
a3.foo

Thats great, the block can be acceded because its a Proc class. Now we can predict the number of parameter of that the user has write and create a more friendly DSL.

Follow

Get every new post delivered to your Inbox.