On Monday 18 February 2013 Love U Ruby wrote
conclusion(although) that’s wrong), when I typed “ob = A .new”. The same
result I got. Then I thought I did something wrong in my customization.
So I tried to create the object creation within an exception block. And
when I typed “begin” and pressed “ENTER” - i got the same error. And
that time my all motivation turned out to the point - “why such error?”
–
Posted via http://www.ruby-forum.com/.
There was nothing “wrong” in your code before the ‘begin’.
What happened is that you redefined Object.new not to return a new
object, but
to return whatever
p ‘hi’
returned (that is, the string ‘hi’). This obviously messes up
everything: IRB
tried to create an instance of a certain class (let’s call it X) by
using
X.new, which is the same as Object.new. However, this didn’t return an
instance of X, but a string. Then IRB tried to call the #set_backtrace
method
on the returned object (which should have been an instance of X but was
instead a string). Since a string doesn’t have a set_backtrace method,
you get
the error.
Why this happens here rather than earlier depends on the inner workings
of
IRB, which I don’t know.
If you wanted to check whether Object#initialize had been called or not,
you
should have done something like this:
class Object
def initialize
puts “this is Object#initialize”
end
end
From what you write, I think you may be making confusion between .new
and
#initialize (in particular, Object.new and Object#initialize).
Object.new
(which is actually the instance method new of class Class) does only two
things:
- allocates memory for a new object
- calls the #initialize method on the new object, passing all the
arguments
passed to it
- returns the new object
If Class#new (not Class.new) were written in ruby (actually, it’s
written in
C), it would be something like this:
class Class
def new *args
obj = allocate
obj.initialize *args
obj
end
end
Now, you usually never need to redefine a class’s .new method, which is
what
you have done. Almost always, what you need to (re)define is the
#initialize
method. In both cases however, you should always call super, so that the
base
class method will get called (unless you have very good reasons not to
want
that). The only exception is if you’re told that the base class version
of the
method does nothing, as in Object#initialize.
Stefano