What is Ruby's default constructor?

Hi,

I wrote the below class :

class Adder

?> def initialize(my_num)

     @my_num = my_num
   end

?> end
=> nil

ob = Adder.new

ArgumentError: wrong number of arguments (0 for 1)
  from (irb):3:in `initialize'
  from (irb):8:in `new'
  from (irb):8
  from /usr/bin/irb:12:in `<main>'

#~~~> Here it is not allowing the creation of object.Even does not
allowing automatic call to its default constructor which it does when a
class has been defined without "initialize" method.

ob = Adder.new(10)

=> #<Adder:0x000000013df828 @my_num=10>

#~~~> here it is OK. and it should be.

#~~> then in the below class how object is created, what constructor it
has called?

class A
p "hi"
end

"hi"
=> "hi"

ob = A.new

=> #<A:0x0000000122ff50>

···

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

What you call ruby's default constructor is, in fact, Object#initialize, which
takes no argument and does nothing. When you define an #initialize method in
your class, that method will be called from the class .new method and all the
arguments passed to .new will in turn be passed to #initialize.

Since you defined Adder#initialize to take one argument, you have to pass
Adder.new one argument (or give a default value to the argument of
Adder#initialize). As for calling the default constructor when Adder.new is
given no arguments, this is something which never happens in ruby. If you
override a method in a derived class (#initialize is not special in any way),
the overriding method is the one which will always be called, even if the
arguments are wrong.

I hope this helps

Stefano

···

On Monday 18 February 2013 Love U Ruby wrote

Hi,

I wrote the below class :
>> class Adder

?> def initialize(my_num)

>> @my_num = my_num
>>
>> end

?> end
=> nil

>> ob = Adder.new

ArgumentError: wrong number of arguments (0 for 1)
  from (irb):3:in `initialize'
  from (irb):8:in `new'
  from (irb):8
  from /usr/bin/irb:12:in `<main>'

#~~~> Here it is not allowing the creation of object.Even does not
allowing automatic call to its default constructor which it does when a
class has been defined without "initialize" method.

>> ob = Adder.new(10)

=> #<Adder:0x000000013df828 @my_num=10>

#~~~> here it is OK. and it should be.

#~~> then in the below class how object is created, what constructor it
has called?

>> class A
>> p "hi"
>> end

"hi"
=> "hi"

>> ob = A.new

=> #<A:0x0000000122ff50>

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

class A

    >> def Object.new initialize
    >> p "hi"
    >> rescue
    >> end
    >> end
    => nil
    >> begin # <~~~ Here I have pressed on ENTER
    "hi"
    /usr/lib/ruby/1.9.1/irb/ruby-token.rb:94:in `Token': undefined
method `set_backtrace' for "hi":String (NoMethodError)
      from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:348:in `block in
lex_init'
      from /usr/lib/ruby/1.9.1/irb/slex.rb:236:in `call'
      from /usr/lib/ruby/1.9.1/irb/slex.rb:236:in `match_io'
      from /usr/lib/ruby/1.9.1/irb/slex.rb:221:in `match_io'
      from /usr/lib/ruby/1.9.1/irb/slex.rb:75:in `match'
      from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:286:in `token'
      from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:262:in `lex'
      from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:233:in `block (2 levels)
in each_top_level_statement'
      from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:229:in `loop'
      from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:229:in `block in
each_top_level_statement'
      from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:228:in `catch'
      from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:228:in
`each_top_level_statement'
      from /usr/lib/ruby/1.9.1/irb.rb:155:in `eval_input'
      from /usr/lib/ruby/1.9.1/irb.rb:70:in `block in start'
      from /usr/lib/ruby/1.9.1/irb.rb:69:in `catch'
      from /usr/lib/ruby/1.9.1/irb.rb:69:in `start'
      from /usr/bin/irb:12:in `<main>'
    @ubuntu:~$

Now my question is :-

- how the "hi" has been printed?

- what is the reason of the error as above printed

- if such an `initialize` definition is not allowed then why error has
not come after I ended with the `class` definition?

···

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

didnt you maybe think that this line:
  def Object.new initialize
is totally wrong in ruby?

i think you need to read your code twice

···

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

@Stefano - yes you are right. That's not only the "begin" keyword,
anything if you type you will be ended up with the above exception. But
I am astonished after seeing that - if the construct is wrong - then why
IRB didn't told me when the "class" definition has been ended with the
"end" keyword.

What I actually trying to see when no 'initialize' method is given to an
class definition then the class as you said should call the
"Object#initialize", which here I tried to customize and see if it has
been called or not. With that approach I reached to a
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/.

Now I typed directly into the IRB and it produced the same error, whose
explanation has been provided already. But trying to understand who
called that below version inside from the class without having any
object creation?

@ubuntu:~$ irb --simple-prompt

  def Object.new initialize
  p "hi"
  end

=> nil

nn

"hi"
/usr/lib/ruby/1.9.1/irb/ruby-token.rb:96:in `Token': undefined method
`set_backtrace' for "hi":String (NoMethodError)
  from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:869:in `identify_identifier'
  from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:731:in `block in lex_int2'
  from /usr/lib/ruby/1.9.1/irb/slex.rb:236:in `call'
  from /usr/lib/ruby/1.9.1/irb/slex.rb:236:in `match_io'
  from /usr/lib/ruby/1.9.1/irb/slex.rb:75:in `match'
  from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:286:in `token'
  from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:262:in `lex'
  from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:233:in `block (2 levels) in
each_top_level_statement'
  from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:229:in `loop'
  from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:229:in `block in
each_top_level_statement'
  from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:228:in `catch'
  from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:228:in
`each_top_level_statement'
  from /usr/lib/ruby/1.9.1/irb.rb:155:in `eval_input'
  from /usr/lib/ruby/1.9.1/irb.rb:70:in `block in start'
  from /usr/lib/ruby/1.9.1/irb.rb:69:in `catch'
  from /usr/lib/ruby/1.9.1/irb.rb:69:in `start'
  from /usr/bin/irb:12:in `<main>'
@ubuntu:~$

···

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

Hans Mackowiak wrote in post #1097446:

didnt you maybe think that this line:
  def Object.new initialize
is totally wrong in ruby?

i think you need to read your code twice

Yes. I know that line wrong. But why the output "hi" came? how the
inside "initialize" method has been invoked?

have you seem that "hi" at the top of the exception?

Thanks

···

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

>> class A
>>
    >> def Object.new initialize
    >>
    >> p "hi"
    >> rescue
    >>
    >> end
    >> end

    => nil

    >> begin # <~~~ Here I have pressed on ENTER

    "hi"
    /usr/lib/ruby/1.9.1/irb/ruby-token.rb:94:in `Token': undefined
method `set_backtrace' for "hi":String (NoMethodError)
      from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:348:in `block in
lex_init'
      from /usr/lib/ruby/1.9.1/irb/slex.rb:236:in `call'
      from /usr/lib/ruby/1.9.1/irb/slex.rb:236:in `match_io'
      from /usr/lib/ruby/1.9.1/irb/slex.rb:221:in `match_io'
      from /usr/lib/ruby/1.9.1/irb/slex.rb:75:in `match'
      from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:286:in `token'
      from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:262:in `lex'
      from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:233:in `block (2 levels)
in each_top_level_statement'
      from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:229:in `loop'
      from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:229:in `block in
each_top_level_statement'
      from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:228:in `catch'
      from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:228:in
`each_top_level_statement'
      from /usr/lib/ruby/1.9.1/irb.rb:155:in `eval_input'
      from /usr/lib/ruby/1.9.1/irb.rb:70:in `block in start'
      from /usr/lib/ruby/1.9.1/irb.rb:69:in `catch'
      from /usr/lib/ruby/1.9.1/irb.rb:69:in `start'
      from /usr/bin/irb:12:in `<main>'
    @ubuntu:~$

Now my question is :-

- how the "hi" has been printed?

- what is the reason of the error as above printed

- if such an `initialize` definition is not allowed then why error has
not come after I ended with the `class` definition?

I'm not sure what you're trying to accomplish here. However, this is what's
happening:

>> class A
>>
    >> def Object.new initialize

You're overriding Object.new. This will affect any object's creation. Since
you're not even calling super (that is, the original Object.new) the new
object will not even be created. All this method will do is print a string

    >> rescue
    >> end
    >> end

No idea of what exactly this does here.

    >> begin

I guess that, since you're seriously messing with ruby core functionality
(after all, you've completely changed how objects are created), something in
IRB brokes, causing the error you seee.

If you try running that code from a script, you'll simply get a syntax error
because of a missing end.

What are you training to achieve, exactly?

Stefano

···

On Monday 18 February 2013 Love U Ruby wrote

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

···

On Monday 18 February 2013 Love U Ruby wrote

@Stefano - yes you are right. That's not only the "begin" keyword,
anything if you type you will be ended up with the above exception. But
I am astonished after seeing that - if the construct is wrong - then why
IRB didn't told me when the "class" definition has been ended with the
"end" keyword.

What I actually trying to see when no 'initialize' method is given to an
class definition then the class as you said should call the
"Object#initialize", which here I tried to customize and see if it has
been called or not. With that approach I reached to a
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/\.

It's not wrong, although I would do a double-take myself if I saw this in a code. It defines a method 'new' on 'Object' that takes an 'initialize' argument.

···

On Sun, 17 Feb 2013 20:45:02 +0100, Hans Mackowiak <lists@ruby-forum.com> wrote:

didnt you maybe think that this line:
  def Object.new initialize
is totally wrong in ruby?

i think you need to read your code twice

--
Matma Rex

Now I typed directly into the IRB and it produced the same error, whose
explanation has been provided already. But trying to understand who
called that below version inside from the class without having any
object creation?

The backtrace below answers that. That's what it is for. You should explore more before going straight to the forum.

···

On Feb 17, 2013, at 13:56 , Love U Ruby <lists@ruby-forum.com> wrote:

@ubuntu:~$ irb --simple-prompt

def Object.new initialize
p "hi"
end

=> nil

nn

"hi"
/usr/lib/ruby/1.9.1/irb/ruby-token.rb:96:in `Token': undefined method
`set_backtrace' for "hi":String (NoMethodError)
from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:869:in `identify_identifier'
from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:731:in `block in lex_int2'
from /usr/lib/ruby/1.9.1/irb/slex.rb:236:in `call'
from /usr/lib/ruby/1.9.1/irb/slex.rb:236:in `match_io'
from /usr/lib/ruby/1.9.1/irb/slex.rb:75:in `match'
from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:286:in `token'
from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:262:in `lex'
from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:233:in `block (2 levels) in
each_top_level_statement'
from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:229:in `loop'
from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:229:in `block in
each_top_level_statement'
from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:228:in `catch'
from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:228:in
`each_top_level_statement'
from /usr/lib/ruby/1.9.1/irb.rb:155:in `eval_input'
from /usr/lib/ruby/1.9.1/irb.rb:70:in `block in start'
from /usr/lib/ruby/1.9.1/irb.rb:69:in `catch'
from /usr/lib/ruby/1.9.1/irb.rb:69:in `start'
from /usr/bin/irb:12:in `<main>'
@ubuntu:~$

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

Stefano Crocco wrote in post #1097453:

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.

As per your above explanation it seems and definitely an allocation to
the memory has been made and only the reference has been lost. From my
piece code - can it be possible to print also that memory address like
"object_id" like the `p "hi" ` ?

Thanks.

···

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

Note that you rewrote Object.new to only print a message: it doesn't event
allocate memory. If you want to see that, you need to something like:

def Object.new
  res = super
  p res.object_id
  res
end

Stefano

···

On Monday 18 February 2013 Love U Ruby wrote

Stefano Crocco wrote in post #1097453:
> 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.

As per your above explanation it seems and definitely an allocation to
the memory has been made and only the reference has been lost. From my
piece code - can it be possible to print also that memory address like
"object_id" like the `p "hi" ` ?

Thanks.

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