Query

hi friends,

I hav a query to ask…

class A
def self.go
return A.new
end

def method_missing( method_name)
puts in methodmissing
puts " #{method_name} method is missing"
end

end

a = A.go
a.name # a.name will print in method missing & name method is missing.

upto here it is working.

now when i create an object

A.new.add # it also prints in method missing & add method is missing.

which i don’t want I want that class method go which return an instance
should call method_missing not an instance which is created
by A.new

how am i supposed to do?

hi, try this:

class A
class << self
def go
obj = A.new
def obj.method_missing *args
p ‘method missing’
end
obj
end
end
end

A.go.uiae
A.new.uiae

Greetz!

Hunt H. wrote:

class A
def self.go
return A.new
end

def method_missing( method_name)
puts in methodmissing
puts " #{method_name} method is missing"
end

end

You’re missing the quotes around the first puts:

puts “in method_missing”

but otherwise that’s fine.

now when i create an object

A.new.add # it also prints in method missing & add method is missing.

Of course. A.new creates a new instance of A. This new object doesn’t
have any instance methods of its own (except those which it inherits
from Object), so calling A.new.anything will trigger the method_missing
hook.

which i don’t want I want that class method go which return an instance
should call method_missing not an instance which is created
by A.new

I’m not sure what you mean - can you give a more concrete example? Your
class method A.go calls A.new internally, so there is obviously no
difference between an object created by A.go and one created by A.new.

Do you want to prevent a user from calling A.new? You can do

class A
class << self
protected :new
end
end

But in Ruby, you can never prevent anything 100%. There are many
different ways a user could call A.new bypassing this restriction (e.g.
using class_eval or send)

Otherwise, if you want an object returned by A.go to behave differently
to an object returned by A.new, then you will have to make them
different somehow. For example:

  • A.go returns an object of a different class
  • A.go returns an object with instance variables set differently
  • A.go returns an object with singleton methods

An example of the third case:

class A
def A.go
res = A.new
def res.method_missing(*args)
puts “method_missing: #{args.inspect}”
end
res
end
end
A.go.wibble # has method_missing method
A.new.wibble # doesn’t

This can be done in a cleaner, more extendable way:

class A
module GoMethods
def method_missing(*args)
puts “method_missing: #{args.inspect}”
end
end
def A.go
A.new.extend GoMethods
end
end
A.go.wibble
A.new.wibble

The objects returned by these two calls are both instances of class A,
but one has singleton methods added. This has some consequences - in
particular, objects with a singleton class cannot be serialised using
Marshal.dump

You don’t get that problem if you just return an instance of a different
class:

class A
class SoupedUp < A
def method_missing(*args)
puts “method_missing: #{args.inspect}”
end
end
def A.go
SoupedUp.new
end
end
A.go.wibble # instance of A::SoupedUp
A.new.wibble # instance of A

HTH,

Brian.

Fabian S. wrote:

hi, try this:

class A
class << self
def go
obj = A.new
def obj.method_missing *args
p ‘method missing’
end
obj
end
end
end

A.go.uiae
A.new.uiae

Greetz!

i checked this program was run the out put is
akshat@-desktop:~/Ruby/meta_class_&patanahi_23_july$ ruby test_meta3.rb
“method missing”
test_meta3.rb:14: undefined method `uia’ for #<A:0xb7ca3944>
(NoMethodError)
akshat@-desktop:~/Ruby/meta_class
&_patanahi_23_july$

Hi –

On Mon, 27 Jul 2009, Hunt H. wrote:

puts in methodmissing
If you don’t get a syntax error there, you’ve got a very strange
version of Ruby installed :slight_smile:

now when i create an object

A.new.add # it also prints in method missing & add method is missing.

which i don’t want I want that class method go which return an instance
should call method_missing not an instance which is created
by A.new

how am i supposed to do?

Ruby provides a full toolkit for making two objects of the same class
behave differently from each other. (In fact, classes are really just
a convenient way to save writing code when you’ve got multiple objects
that happen to share behaviors.)

Here’s what you can do:

class A
module SpecialMethodMissing
def method_missing( method_name)
puts “in methodmissing”
puts " #{method_name} method is missing"
end
end

def self.go
A.new.extend(SpecialMethodMissing)
end
end

I’m using extend to add the special method_missing behavior (via the
module) to that one instance.

Depending on the structure of the rest of your program, you might want
to subclass A and have a different class whose instances have that
special method_missing.

David

well, that’s what you described.
objects created with A.go have a method missing, objects
created with A.new don’t.
So calling A.go.uiae will execute method_missing,
calling A.new.uiae will result in an error, since there is no uiae
method.

Greetz