query

H

Hunt Hunt

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?
 
F

Fabian Streitel

[Note: parts of this message were removed to make it a legal post.]

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!
 
D

David A. Black

Hi --

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

If you don't get a syntax error there, you've got a very strange
version of Ruby installed :)
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?

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

--
David A. Black / Ruby Power and Light, LLC / http://www.rubypal.com
Q: What's the best way to get a really solid knowledge of Ruby?
A: Come to our Ruby training in Edison, New Jersey, September 14-17!
Instructors: David A. Black and Erik Kastner
More info and registration: http://rubyurl.com/vmzN
 
B

Brian Candler

Hunt said:
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.
 
H

Hunt Hunt

Fabian said:
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$
 
F

Fabian Streitel

[Note: parts of this message were removed to make it a legal post.]

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,431
Messages
2,571,677
Members
48,796
Latest member
Greg L.

Latest Threads

Top