Method_missing - but can it be "isolated" to per-project basis?

Hi.

I have been playing with the following code (explanation follows after
the code):


require ‘pp’

class Object
def method_missing(*args)
return args.join ’ ’
end
end

def foo(i = nil)
puts i if i
puts yield if block_given?
end

foo
foo ‘testing 1’
foo { ‘testing 2’ }
foo { testing 3 }

The code above returns:

testing 1

testing 2

testing 3


Ok, this code defines method foo, and we use 4 different ways to
call it.

What I was most interested in was the last version - I want to access
all what was passed in a block as string. This is useful for one
project, but it is not good to modify Object in such a way in larger
projects.

Any advice on whether it is possible to keep this piece of code only on
a per-project basis? Like, I want to extend class Object only in the
context of that specific object, but if I use it in a larger project, I
don’t want to use that very modification to class Object (because,
outside that project, it would be counter-productive to act on
method_missing that way).

Edit: Oh well, seems the code above doesn’t work anyway as expected…
can’t seem to pass in stuff like
{ testing gkljejklwe hlkjhjklhhwe }

Not exactly sure what you are trying to accomplish, but you could create
a
base class for your project and use it where ever it is needed.

module MyLib
class Base
def method_missing(*args)
return args.join ’ ’
end
end

class Foo < Base
   ...
end

end

On Fri, Jan 27, 2012 at 4:06 PM, Marc H. [email protected]
wrote:

require ‘pp’

You require pp but never use it.

class Object
def method_missing(*args)

O.o be careful with this, it’s likely to end in misery.

Any advice on whether it is possible to keep this piece of code only on
a per-project basis? Like, I want to extend class Object only in the
context of that specific object, but if I use it in a larger project, I
don’t want to use that very modification to class Object (because,
outside that project, it would be counter-productive to act on
method_missing that way).

It’s unclear to me what you mean by “I want to extend class Object only
in
the context of that specific object”. Here are some ways to deal with
this
sort of thing that might be helpful (I can’t really even think of a use
case for this, maybe if you explain what you’re really trying to do, a
better solution can be offered).

  1. Just rescue the exception. (recommended)

begin
Object.new.abc(123)
rescue NoMethodError => e
puts “#{e.name} #{e.args.join ’ '}”
end

>> abc 123

  1. Extend just the object you want to do this to. I don’t dig it, but at
    least the crazy is contained to just that object. Note that methods not
    on
    this object will still behave as normal (even if invoked by a method on
    this object)

module CrazyMethodMissing
def method_missing(*args)
args.join ’ ’
end
end

Object.new.extend(CrazyMethodMissing).abc(123) # => “abc 123”
Object.new.abc(123) # ~> -:8:in <main>': undefined method abc’ for
#Object:0x0b50a4 (NoMethodError)

  1. Conditionally switch this behaviour on and off with a global variable
    (highly discouraged, and if you made library code which did this – what
    I
    assume you mean by the “project” comments – then I would be quite
    displeased when I found out).

class Object
def method_missing(*args)
return super if $neverdie.zero?
args.map(&:to_s).join ’ ’
end

$neverdie = 0
def neverdie(&block)
$neverdie += 1
instance_eval &block
ensure
$neverdie -= 1
end
end

Object.new.neverdie { abc 123 } # => “abc 123”
Object.new.abc 123

~> -:3:in method_missing': undefined method abc’ for

#Object:0x0b494c
(NoMethodError)

~> from -:17:in `’