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.