# Save me from the method\_missing

**URL:** <https://www.ruby-forum.com/t/save-me-from-the-method-missing/98575>\
**Category:** Ruby\
**Created:** [July 16, 2006, 6:07am UTC](https://www.ruby-forum.com/t/save-me-from-the-method-missing/98575 "2006-07-16T06:07:04Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [July 16, 2006, 6:07am UTC](https://www.ruby-forum.com/t/save-me-from-the-method-missing/98575/1 "2006-07-16T06:07:04Z")

</div>

I’m find the the whole method\_missing, privative clashing methods,  
except essential ones, call send otherwise . . . is just a pain. The  
whole thing is just to have that nice interface “obj.foo, obj.foo=x”.  
That might not seem like much but it really stand out in contrast:

obj[:a][:b][:c] -vs- obj.a.b.c

So, dang, if that’s all we want, some beauty in our code, and the whole  
method\_missing thing is just too problematic why not just have another  
means? Anuone having a look at Hpricot recently will note the  
x/:a/:b/:c notation. No bad, that almost as nice. Okay, step back …

I was thinking… soon we will become acustom to space significance  
with the new Hash notation

{ x: :a } != { x::a }

If we’re gogin to be dealing with space significance here anyway, why  
not go with it give us the ability to reusue ‘:’?

class X \< Hash

```
# parameter is always a symbol

def :(x)
  self[x]
end

def :=(x,y)
  self[x] = y
end

def x(n)
  n
end

```

end

x = X  
x:y = 4  
x:y #=\> 4  
x(:y) #=\> :y  
x :y #=\> :y

So then we can easily do

obj:a:b:c

That’s just about as nice. Of course the disadvantage is that it’s not  
very ducky --if you take my meaning. Of course, thinking about that,  
one might be inclined to ask, why not just have a special Dispatcher  
superclass?

class MyClass \< Dispatcher

```
# only two methods allowed

def .(x, *args, &blk)
  ...
end

def .=(x,y)
  ...
end

```

end

If only … then I wouldn’t be in so deep. Someone save me!

T.

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [July 16, 2006, 6:56am UTC](https://www.ruby-forum.com/t/save-me-from-the-method-missing/98575/2 "2006-07-16T06:56:05Z")

</div>

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

> x/:a/:b/:c notation. No bad, that almost as nice. Okay, step back …
> 
> ```
> def x(n)
> 
> ```
> 
> end
> 
> If only … then I wouldn’t be in so deep. Someone save me!

So what is it exactly that you’re trying to do? Are you creating a  
DSL, or something?

method\_missing can certainly have it’s problems and it needs to be  
used with care, but I’m certainly glad it’s there.

Phil

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [July 16, 2006, 12:43pm UTC](https://www.ruby-forum.com/t/save-me-from-the-method-missing/98575/3 "2006-07-16T12:43:03Z")

</div>

Phil T. wrote:

> So what is it exactly that you’re trying to do? Are you creating a  
> DSL, or something?

Basically, albiet a lower-level sort of one. It all goes back to  
Facet’s Annotations lib. Annotations work like this:

class X  
ann :x, :class =\> String, :default =\> 10, :foo =\> :bar  
end

X.ann.x.class #=\> String  
X.ann.x.default #=\> 10  
X.ann.x.foo #=\> :bar

X.ann.x.foo = :baz  
X.ann.x.foo #=\> :baz

X.ann.x =\> #\<Annotation(X#x) {:class =\> String, :default =\> 10, :foo  
=\> :baz}\>

Annotation class is a subclass of OpenObject, which is much like  
OpenStruct, but it dynamically prevents method visibility --hence my  
previous post on #private\_filter. And I need that to ensure no new  
methods pop up that would interfere with OpenObject’s functionality.  
For example:

o = OpenObject.new  
o.yep = 10  
o.yep #=\> 10

and then, someone else comes along:

class Object  
def yep ; “your sunk” ; end  
end

My method\_missing in OpenObject wouldn’t catch #yep anymore and she’d  
be sunk.

> method\_missing can certainly have it’s problems and it needs to be  
> used with care, but I’m certainly glad it’s there.

No doubt. No suggestion here of getting rid, or anything of the sort.  
Just looking for a sounder means for the above type of usecase.

T.

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [July 16, 2006, 9:08pm UTC](https://www.ruby-forum.com/t/save-me-from-the-method-missing/98575/4 "2006-07-16T21:08:01Z")

</div>

hi ara,

> removed\_email\_address@domain.invalid wrote:

good food for thought. thanks ara. …

> i use method\_missing too but, in this case, you’d have to provide an extremely  
> strong argument why an interface like this won’t suffice:

[snip]

> {:default=\>10, :class=\>String, :foo=\>:bar}
> 
> it’s simple and rather concise - adding only a char or so.

yea that’s a nice implemementation esspecially for it’s simplicity.  
while i _tend_ toward your opinion there are couple of problems. the  
big one is of course my end users really likes the dot notation. and i  
can understand, it certainly has a certain elegance and ease to it.  
unfortunately it’s a nightmare to code. btw, the notation X.ann(:x)  
does work already in what I have, but another thing is this use:

X.ann :a, :b, :c, :class =\> String

X.ann.a.class #=\> String  
X.ann.b.class #=\> String  
X.ann.c.class #=\> String

Also there’s a shortcut for setting the :class annotation.

X.ann :a, :b, :c, String

I imagine that still can be worked in to your impl, but it does starts  
to get a little thicker.

I should also note that it’s not just annotations, I use it lots else  
where too. I esspecially like using Facets’ OpenCascade on YAML load  
configs.

s = %{  
a:  
b:  
c: “abc”  
}

data = OpenCascade[YAML.load(s)]

data.x.y.z #=\> “abc”

(OT. Notice BTW how I use ::[] on OpenCascade. It’s a subclass of Hash.  
In an earlier post I mentioned how I felt that ::new should be able to  
take a hash rather than a default value --well there’s why. I actually  
just spent ~2 hours tracknig a bug that came down to using ::new when I  
should have used []. That sucked!)

> more importanlty,  
> however, the impl above actually conforms to the specification i imagine your  
> annotation class requires, which is that **any** token might be used as an  
> annotation tag, for instance
> 
> ann ‘x’, **id** =\> method(‘x’). **id**
> 
> which no method\_missing approach will ever quite be able to skin.

You’re right about that. There are limitations to using method\_missing.  
Though I don’t mind so much if the limitations are _well defined_ and  
minimial, but the current state of affairs is too iffy.

> but, using a method\_missing approach it becomes
> 
> args = %w( x prop )
> 
> klass.ann.send(args.first).send(args.last)
> 
> this applies to many method\_missing approaches: they are more consise until  
> another layer of abstraction is added, like having the methods be read from a  
> config file, food for thought…

Well, that could be solved with a special interface, eg.

klass.ann.cascade\_send \*args

or something. But it’s a good point too.

T.

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [July 17, 2006, 5:35pm UTC](https://www.ruby-forum.com/t/save-me-from-the-method-missing/98575/5 "2006-07-17T17:35:51Z")

</div>

On Mon, 17 Jul 2006 removed\_email\_address@domain.invalid wrote:

> I imagine that still can be worked in to your impl, but it does starts  
> to get a little thicker.

yes, a bit. very doable though…

> data.x.y.z #=\> “abc”
> 
> (OT. Notice BTW how I use ::[] on OpenCascade. It’s a subclass of Hash.  
> In an earlier post I mentioned how I felt that ::new should be able to  
> take a hash rather than a default value --well there’s why. I actually  
> just spent ~2 hours tracknig a bug that came down to using ::new when I  
> should have used []. That sucked!)

yikes. i’ve done exactly this kind of this many times but i’m tending  
away  
from it. the reason is that the spec just doesn’t quite fit when s is  
defined  
thusly:

s = \<\<-yml

```
 "hard to use" : "forty-two"

 42 : "impossible to use"

 "!can't work" : "etc"

```

yml

i suppose it’s ok to contrain configs you have keys that are valid ruby  
methods, still i’ve just found myself in a corner with that a few times  
and  
have strayed away from it every since. like i said, i still have lots  
of code  
doing stuff with method\_missing, but i thought i’d put my thought out  
there  
for posterity and for people starting new designs.

> You’re right about that. There are limitations to using method\_missing.  
> Though I don’t mind so much if the limitations are _well defined_ and  
> minimial, but the current state of affairs is too iffy.

what do you mean ‘iffy’ exactly? that the list of ‘require’ methods  
seems to  
change every few months?

regards.

-a

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [July 17, 2006, 6:12pm UTC](https://www.ruby-forum.com/t/save-me-from-the-method-missing/98575/6 "2006-07-17T18:12:02Z")

</div>

removed\_email\_address@domain.invalid wrote:

> ```
> "!can't work" : "etc"
> 
> ```
> 
> yml
> 
> i suppose it’s ok to contrain configs you have keys that are valid ruby  
> methods, still i’ve just found myself in a corner with that a few times and  
> have strayed away from it every since. like i said, i still have lots of code  
> doing stuff with method\_missing, but i thought i’d put my thought out there  
> for posterity and for people starting new designs.

Yes, I do constrain the config keys to single word case insensitive  
strings. Unfortuate I just don’t see a nicer way. “y[:a][:b][:c]” just  
lacks all elegance. And path notation (y/:a/:b/:c) while a _little_  
better can’t use setting at the end (eg. y/:a/:b/:c = x). So what else  
is there?

> > You’re right about that. There are limitations to using method\_missing.  
> > Though I don’t mind so much if the limitations are _well defined_ and  
> > minimial, but the current state of affairs is too iffy.
> 
> what do you mean ‘iffy’ exactly?

Well, for instance. If a public method is added to Kernel or Object (or  
any subclass for that matter) it will show up in ones class and block  
out method\_missing.

> that the list of ‘require’ methods seems to change every few months?

Not sure what you mean.

T.

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [July 16, 2006, 5:57pm UTC](https://www.ruby-forum.com/t/save-me-from-the-method-missing/98575/7 "2006-07-16T17:57:32Z")

</div>

On Sun, 16 Jul 2006, Trans wrote:

> end
> 
> and then, someone else comes along:
> 
> No doubt. No suggestion here of getting rid, or anything of the sort.  
> Just looking for a sounder means for the above type of usecase.

hi tom-

i use method\_missing too but, in this case, you’d have to provide an  
extremely  
strong argument why an interface like this won’t suffice:

harp:~ \> cat a.rb  
class Module  
def ann meth, arg = nil  
@ann ||= {}  
if Hash === arg  
arg ? (@ann[meth] ||= {}).update(arg) : @ann[meth]  
else  
arg ? @ann[meth][arg] : @ann[meth]  
end  
end  
end

class X  
ann :x, :class =\> String, :default =\> 10, :foo =\> :bar  
end

X.ann :x, :class #=\> String  
X.ann :x, :default #=\> 10  
X.ann :x, :foo #=\> :bar

X.ann :x #=\> #\<Annotation(X#x) {:class =\> String, :default  
=\> 10, :foo \> :baz}\>

harp:~ \> ruby -W0 a.rb  
String  
10  
:bar  
{:default=\>10, :class=\>String, :foo=\>:bar}

it’s simple and rather concise - adding only a char or so. more  
importanlty,  
however, the impl above actually conforms to the specification i imagine  
your  
annotation class requires, which is that **any** token might be used as  
an  
annotation tag, for instance

ann ‘x’, **id** =\> method(‘x’). **id**

which no method\_missing approach will ever quite be able to skin.

anyhow - just playing devil’s advocate - but i think it’s an important  
consideration.

cheers.

ps.

klass.ann.x.prop

becomes much longer if the arg list is in a variable, for instance, with  
my  
impl above it would be

args = %w( x prop )

klass.ann \*args

but, using a method\_missing approach it becomes

args = %w( x prop )

klass.ann.send(args.first).send(args.last)

this applies to many method\_missing approaches: they are more consise  
until  
another layer of abstraction is added, like having the methods be read  
from a  
config file, food for thought…

-a

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [July 17, 2006, 7:09pm UTC](https://www.ruby-forum.com/t/save-me-from-the-method-missing/98575/8 "2006-07-17T19:09:47Z")

</div>

On Tue, 18 Jul 2006 removed\_email\_address@domain.invalid wrote:

> Yes, I do constrain the config keys to single word case insensitive strings.  
> Unfortuate I just don’t see a nicer way. “y[:a][:b][:c]” just lacks all  
> elegance. And path notation (y/:a/:b/:c) while a _little_ better can’t use  
> setting at the end (eg. y/:a/:b/:c = x). So what else is there?

brainstorming:

harp:~ \> cat a.rb  
require ‘yaml’

class Config \< ::Hash  
def self.new(yml) super().update YAML.load(yml.to\_s) end  
end  
def Config(\*a, &b) Config.new(\*a, &b) end

c =  
Config %(  
a:  
b:  
c: 42  
)

# 

# just an idea

# 

class Config \< ::Hash  
def munge\_keys \*keys  
keys.compact!  
keys.flatten!  
keys.map!{|key| key.to\_s.strip.split %r/\s/}  
keys  
end  
def [] \*keys  
keys = munge\_keys keys  
h = self  
nil while Hash === (h = h.fetch keys.shift.to\_s)  
h  
end  
def []= \*argv  
v, keys = argv.pop, argv  
keys = munge\_keys keys  
h, h2, k = self, nil, nil  
h = h2 while Hash === (h2 = h.fetch(k = keys.shift.to\_s))  
h[k] = v  
end  
end

p c[:a, :b, :c]

c[:a, :b, :c] = ‘forty-two’

p c[:a, :b, :c]

p c

# 

# another, sillier one

# 

class Config  
alias\_method ‘^’, ‘[]’  
end

p c ^ %w( a b c )

harp:~ \> ruby a.rb  
42  
“forty-two”  
{“a”=\>{“b”=\>{“c”=\>“forty-two”}}}  
“forty-two”

> > what do you mean ‘iffy’ exactly?
> 
> Well, for instance. If a public method is added to Kernel or Object (or  
> any subclass for that matter) it will show up in ones class and block  
> out method\_missing.

i see three ways to get around this:

a) use block form methods

```
   obj.configure{

     # push method_missing handler and dsl methods onto stack

     # instance_eval the block

     # pop them off

   }

 so

   obj.configure{
     a 4
     b 2
   }

 this gives you a chance to 'clean-out' the obj each time.

```

b) use block form with blank slate proxy

```
 obj.configure{
   # setup blank-slate proxy

   # instance_eval the block on proxy!

   # copy all state from proxy into object
 }

```

c) use block form with an easily identifiable method name. i do this  
in my  
xx html/xml generation lib where

```
 puts xhtml_{

   p_{ 'note that the "p" tag works! }

   b_{ i_{ u_{ "bold-italic-underline } } }

 }

```

i can filter **only** those methods ending in ‘\_’. this has many  
advantages:

```
 - easy to distiguish ruby's methods like 'p' from html methods like 

```

‘p\_’

```
 - easy to grep for 'special' methods in you source.

```

i realize none of these really apply to a config style class.

> > that the list of ‘require’ methods seems to change every few months?
> 
> Not sure what you mean.

gsub/require/required/

meaning **id** , **send** , et al.

cheers.

-a
