# Method\_missing question

**URL:** <https://www.ruby-forum.com/t/method-missing-question/79454>\
**Category:** Ruby\
**Created:** [December 15, 2006, 10:02am UTC](https://www.ruby-forum.com/t/method-missing-question/79454 "2006-12-15T10:02:20Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![splattael](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/858c86/32.png) [@splattael](https://www.ruby-forum.com/u/splattael)\
**Post date:** [December 15, 2006, 10:02am UTC](https://www.ruby-forum.com/t/method-missing-question/79454/1 "2006-12-15T10:02:20Z")

</div>

Hello,

I am using method\_missing to build a structure (similar to a tree) like  
this:

P.book do  
P.title  
P.price  
end

class P  
def self.method\_missing(method\_name, \*args, &block)  
#add a node with name ‘method\_name.to\_s’ to the tree etc.  
end  
end

Now, the problem is I would like to write the above example like this:

book do  
title  
price  
end

i.e. without the Ps.  
P’s sole purpose is to define method\_missing - I did not want to  
override Object.method\_missing since I would like to release this code  
to the wild and I think it could collide with my potential future user’s  
Object.method\_missing.

I have then experimented with modules (mimicking namespace  
functionality) but that still did not provide the possibility to omit  
the class name. I would need something equivalent to include - you can  
omit the module name if you include the module - but with classes.

I have no idea if this is possible in Ruby, but is there something like  
run this code in a different context or something?

TIA,  
Peter

\_\_  
[http://www.rubyrailways.com](http://www.rubyrailways.com)

---

<div class="post-metadata">

**Author:** ![splattael](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/858c86/32.png) [@splattael](https://www.ruby-forum.com/u/splattael)\
**Post date:** [December 15, 2006, 10:16am UTC](https://www.ruby-forum.com/t/method-missing-question/79454/2 "2006-12-15T10:16:26Z")

</div>

On 12/15/06, Peter S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> class P  
> end  
> omit the module name if you include the module - but with classes.
> 
> I have no idea if this is possible in Ruby, but is there something like  
> run this code in a different context or something?

actually, there is - it is called script and you can find it described  
here:  
[http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/100429](http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/100429)

---

<div class="post-metadata">

**Author:** ![splattael](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/858c86/32.png) [@splattael](https://www.ruby-forum.com/u/splattael)\
**Post date:** [December 16, 2006, 3:21am UTC](https://www.ruby-forum.com/t/method-missing-question/79454/3 "2006-12-16T03:21:02Z")

</div>

On 12/15/06, Peter S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> to the wild and I think it could collide with my potential future user’s  
> Object.method\_missing.
> 
> I have then experimented with modules (mimicking namespace  
> functionality) but that still did not provide the possibility to omit  
> the class name. I would need something equivalent to include - you can  
> omit the module name if you include the module - but with classes.
> 
> I have no idea if this is possible in Ruby, but is there something like  
> run this code in a different context or something?

Hi Peter,

This sort of thing probably already exists somewhere, but I don’t know  
what it’s called. (The ‘script’ that Michael mentioned looks like  
something else to me… ?)

So anyway, here’s a starting point. The trick is to use instance\_eval  
to change the value of ‘self’ within the block.

class Node

# Rename all existing methods to start with ‘\_\_’, so they’re not

# likely to collide with your attribute names. We’ll leave some

# methods alone, since they’re necessary for some basic operations.

methods = (instance\_methods + private\_instance\_methods)  
methods = methods - %w’ **send**  **id** initialize inspect’  
methods.each{|m| alias\_method(“\_\_#{m}”, m); undef\_method(m)}

def method\_missing(\*args, &block)  
key, val = \*args  
if block  
args.length == 1 or  
raise ArgumentError, “value and block given”  
node = Node.new  
\_\_instance\_variable\_set(“@#{key}”, node)  
node.\_\_instance\_eval(&block)  
return node  
else  
args.length \<= 2 or  
raise ArgumentError, “too many arguments”  
if args.length \> 1  
\_\_instance\_variable\_set(“@#{key}”, val)  
end  
return \_\_instance\_variable\_get(“@#{key}”)  
end  
end  
end

### Usage

node = Node.new  
node.root do  
a 1  
b 2  
c do  
d 3  
e 4  
end  
end  
p node.root.c.d #=\> 3  
p node.root.c #=\> #\<Node:0xb7dd55c4 @d=3, @e=4\>  
p node #=\> #\<Node:0xb7ddb8ac @root=#Node:...\>

---

<div class="post-metadata">

**Author:** ![splattael](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/858c86/32.png) [@splattael](https://www.ruby-forum.com/u/splattael)\
**Post date:** [December 17, 2006, 8:37am UTC](https://www.ruby-forum.com/t/method-missing-question/79454/4 "2006-12-17T08:37:55Z")

</div>

> So anyway, here’s a starting point. The trick is to use instance\_eval  
> to change the value of ‘self’ within the block.

More straightforward to grab the block, make it a method of the current  
object, then call that method?

require ‘pp’

class ReadableThing  
def book &block  
ugly\_call\_to\_get\_the\_eigenclass = class \<\< self; self; end  
ugly\_call\_to\_get\_the\_eigenclass.send :define\_method,  
:\_\_\_secret\_method,  
block  
send :\_\_\_secret\_method  
end

def title  
pp ‘a title’  
end  
end

r = ReadableThing.new

r.book do  
puts “self is: #{self.inspect}\n”  
title  
end

C:\rx\rv\bin\>ruby r.rb  
self is: #ReadableThing:0x28e40fc  
“a title”

It does leave a reference to the block lying around - you’d probably  
want to  
clean that up for production code.

– James M.

---

<div class="post-metadata">

**Author:** ![splattael](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/858c86/32.png) [@splattael](https://www.ruby-forum.com/u/splattael)\
**Post date:** [December 16, 2006, 11:15pm UTC](https://www.ruby-forum.com/t/method-missing-question/79454/5 "2006-12-16T23:15:11Z")

</div>

George O. wrote:

> On 12/15/06, Peter S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> 
> > Now, the problem is I would like to write the above example like this:
> > 
> > book do  
> > title  
> > price  
> > end  
> > …  
> > This sort of thing probably already exists somewhere, but I don’t know  
> > what it’s called. (The ‘script’ that Michael mentioned looks like  
> > something else to me… ?)

Yes, “script” is something else. It’s for loading an external “script”  
inside of a module, to confine it to a namespace. It’s like “load(…,  
true)”, but you can access the anonymous module.

It has nothing to do with defining a special syntax like the OP wanted.
