Kernel.xxx interferes with method_missing

  • Thread starter Alexey Petrushin
  • Start date
A

Alexey Petrushin

Hello!

I'm using method_missing to create DSL, the problem is that Kernel.xxx
methods are interferes with it.
How this issue can be solved?

It seems that one solution is to explicitly define all global methods
(p, select, ...) on the target class for method_missing.

But i hope there is more elegant solution :). Maybe some trick with
sandboxes?

CODE:
class Parameters # < BlankSlate
attr_reader :result

def initialize &block
@result = {}
instance_eval &block
end

def method_missing m, *p
@result[m] = *p
end
end

describe do
it do
hash = Parameters.new do
one 1
select1 'Select' # <= Problem here, it calls Kernel.select
end.result

hash.should == {:eek:ne => 1, :select1 => 'Select'}
end
end
 
G

Gregory Brown

Hello!

I'm using method_missing to create DSL, the problem is that Kernel.xxx
methods are interferes with it.
How this issue can be solved?

It seems that one solution is to explicitly define all global methods
(p, select, ...) on the target class for method_missing.

But i hope there is more elegant solution :). Maybe some trick with
sandboxes?

On Ruby 1.9, use BasicObject. On Ruby 1.8, use Jim Weirich's
BlankSlate object. I recently ran into an issue with blankslate
though where it was incorrectly revealing methods, so you might want
to use my patched version:

http://pastie.org/377487.txt

Take this with a shaker of salt though, I mainly modified the example
to show off certain dynamic programming techniques in my book[0], and
not necessarily to make it robust. I have emailed Jim about these
changes, but he hasn't gotten back to me yet.

-greg
 
G

Gregory Brown

Whoops...

On Mon, Feb 2, 2009 at 12:56 PM, Gregory Brown
Take this with a shaker of salt though, I mainly modified the example
to show off certain dynamic programming techniques in my book[0], and
not necessarily to make it robust. I have emailed Jim about these
changes, but he hasn't gotten back to me yet.

[0] http://rubybestpractices.com

Sorry for the shameless plug, but it's directly relevant to the OP's
questions since I cover these topics in the book, and it will be under
a creative commons license 9 months after it hits the shelves.

-greg
 
A

Alexey Petrushin

Possible solution, a hack with redefining all global methods.

class ExtraBlankSlate < BlankSlate
CUSTOM_UNDEFINE = [:p, :select, :puts]

undefine = Kernel.instance_methods + Object.instance_methods +
CUSTOM_UNDEFINE
BlankSlate.instance_methods.each{|m| undefine.delete m}

undefine.each do |m|
script = %{\
def #{m} *p, &b
method_missing :#{m}, *p, &b
end}
class_eval script, __FILE__, __LINE__
end
end
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top