1

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" that yes I can overload the Object#initialize method.But all has been ended up with the below exception. 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.

>>  class A
>>  def Object.new initialize
>>   p "hi"
>>   rescue
>>  end
>>  end
=> nil
>>  begin # <~~~ Here I have pressed on ENTER
"hi"  #<~~~~ How was it print out?
/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 questions are -

  • How has the "hi" been printed?

  • What is the cause of the error as printed above?

  • If such initialize definition is not allowed,then why has the error not come after I ended with the class definition?

EDIT

As per @casper I tried below:

>> def Object.new
>> p "hi"
>> end
=> nil
>> begin
/usr/lib/ruby/1.9.1/irb/ruby-token.rb:96: stack level too deep (SystemStackError)

But here no "hi" printed back.

So what made the "hi" to print back in the first case?

Arup Rakshit
  • 116,827
  • 30
  • 260
  • 317
  • 1
    Also, it is bad to start a question with a chunk of code without explanation. I think that is also pretty much rude. What is the reader supposed to do with it? Always start with an ordinary text. A code should be preceded with a text telling how it is relevant in the context and what the reader is supposed to do with it. – sawa Feb 17 '13 at 20:50

1 Answers1

3

What exactly are you trying to do? You just redefined Object.new, so there is no surprise you make everything go haywire.

You can basically get the same effect by just:

>> def Object.new
>> end
>> [press enter]
KABOOM

The reason "hi" is printed is that someone just called Object.new, probably the irb REPL loop, and it expected an object, but instead it gets gobledygook.

You can also try this:

def Object.new *args
  p args
end

And you will see funny stuff. However you won't be able to quit irb or do anything useful with it after that. Again: you just broke Object.

To make some sense of it you should read this:
In Ruby, what's the relationship between 'new' and 'initialize'? How to return nil while initializing?

And then you can try this:

class Object
  class << self
    alias :old_new :new
  end
end

Now you can do:

def Object.new *args
   p args
   old_new *args
end

This won't break new because you are still calling the old version of it. However you will now be printing out stuff every time someone calls new.

Community
  • 1
  • 1
Casper
  • 33,403
  • 4
  • 84
  • 79
  • 1
    Well..it is a valid definition, but you are modifying a live running program. This program is `irb`. By changing `Object.new` you are breaking irb while irb is running: irb is a Ruby program and you just broke the fundamental base object in Ruby by redefining `new` on it. – Casper Feb 17 '13 at 20:38
  • Completely satisfied with your answer,but my a bit confusion is - with my code who called the `.new` method? – Arup Rakshit Feb 17 '13 at 21:02
  • @user2060534 irb called it. Irb is a REPL [Read-Eval-Print-Loop](http://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop). Irb is a Ruby program that handles all your input and everything you do on the command line. Each time you press enter it does a lot of things and among the things it does it probably does something at some point that creates a new object. So irb will break, and therefore it will crash, which will crash everything and Ruby throws in the towel and just quits with an error. – Casper Feb 17 '13 at 21:06
  • @user2060534 To clarify. Every time you press enter there will be Ruby code that is executed. Even if you just press enter on an empty line. That's what irb does. It interprets the command line. It's a big hunk of Ruby code. Look in `/usr/lib/ruby/1.9.1/irb.rb`. That is what is happening. – Casper Feb 17 '13 at 21:08