Python Equivalent of Ruby's 'Method_Missing'

Python equivalent of Ruby's 'method_missing'

There is no difference in Python between properties and methods. A method is just a property, whose type is just instancemethod, that happens to be callable (supports __call__).

If you want to implement this, your __getattr__ method should return a function (a lambda or a regular def, whatever suite your needs) and maybe check something after the call.

Ruby’s “method_missing” in Python

As others have mentioned, in Python, when you execute o.f(x), it's really a two-step operation: First, get the f attribute of o, then call it with parameter x. It's the first step that fails because there is no attribute f, and it's that step that invokes the Python magic method __getattr__.

So you have to implement __getattr__, and what it returns must be callable. Keep in mind, if you also try to get o.some_data_that_doesnt_exist, the same __getattr__ will be called, and it won't know that it's a "data" attribute vs. a "method" that being sought.

Here's an example of returning a callable:

class MyRubylikeThing(object):
#...

def __getattr__(self, name):
def _missing(*args, **kwargs):
print "A missing method was called."
print "The object was %r, the method was %r. " % (self, name)
print "It was called with %r and %r as arguments" % (args, kwargs)
return _missing

r = MyRubylikeThing()
r.hello("there", "world", also="bye")

produces:

A missing method was called.
The object was <__main__.MyRubylikeThing object at 0x01FA5940>, the method was 'hello'.
It was called with ('there', 'world') and {'also': 'bye'} as arguments

Are there equivalents to Ruby's method_missing in other languages?

Some use cases of method_missing can be implemented in Python using __getattr__ e.g.

class Roman(object):
def roman_to_int(self, roman):
# implementation here

def __getattr__(self, name):
return self.roman_to_int(name)

Then you can do:

>>> r = Roman()
>>> r.iv
4

Numeric class and method missing

puts handles arrays in a special way. Therefore, puts 5 attempts to call 5.to_ary and when implementing method_missing, it calls it with an argument of :to_ary.

Within method_missing you call puts self which is equivalent to puts 5. This is a recursion which Ruby shows as [...].

This recursive array produces the same output:

ary = []
#=> []
ary << ary
#=> [[...]]

method_missing equivalent in R

For the access a$b, yes, this is possible – if messy. The reason is that $ is just an operator that we can redefine.

The default definition can be retrieved as follows:

> `$`
.Primitive("$")

It’s easy enough possible to change this so that we first test whether the b in a$b actually exists. Here’s a rough outline (but only a rough outline, see below):

`$` <- function (a, b) {
if (exists(as.character(substitute(b)), where = a))
.Primitive("$")(a, b)
else
methodMissing(as.character(substitute(a)), as.character(substitute(b)))
}

… now we just need to supply methodMissing:

methodMissing <- function (a, b)
cat(sprintf('Requested missing %s on %s\n', b, a))

… and we can use it:

> foo <- list(bar = 'Hello')
> foo$bar
[1] "hello"
> foo$baz
Requested missing baz on foo

However, note that this breaks in interesting ways for other types – for instance, it no longer works with data frames:

> cars$speed
NULL

I don’t know whether it’s trivial to fix this – it’s not enough to test for is.list(a), for instance – so proceed with caution.

The solutions for S3 and S4 are left as an exercise for the reader (actually, I have no clue – I don’t use S4 and rarely use S3).

Does Javascript have something like Ruby's method_missing feature?

The ruby feature that you are explaining is called "method_missing" http://rubylearning.com/satishtalim/ruby_method_missing.htm.

It's a brand new feature that is present only in some browsers like Firefox (in the spider monkey Javascript engine). In SpiderMonkey it's called "__noSuchMethod__" https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/NoSuchMethod

Please read this article from Yehuda Katz http://yehudakatz.com/2008/08/18/method_missing-in-javascript/ for more details about the upcoming implementation.



Related Topics



Leave a reply



Submit