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?

···

--
Posted via http://www.ruby-forum.com/.

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!

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 :slight_smile:

  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

···

On Mon, 27 Jul 2009, Hunt Hunt wrote:

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

Hunt Hunt 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.

···

--
Posted via http://www.ruby-forum.com/\.

Fabian Streitel 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$

···

--
Posted via http://www.ruby-forum.com/\.

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