Forum: Ruby Difference between Foo = Class.new and class Foo

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
0e5fc52ee8fe5166a259908e0626039e?d=identicon&s=25 Brandon Dimcheff (Guest)
on 2008-10-07 17:31
(Received via mailing list)
I'm playing around with classes and discovered that

class Foo
   ...
end

and

Foo = Class.new do
   ...
end

seem to behave slightly differently.  I assumed that "class Foo" was
just a shortcut that got translated into "Foo = Class.new", but when I
muck with class in the following way:

class Class
   class << self
     def new
       puts "new called"
       super
     end
   end
end

and then do "Foo = Class.new",  I get "new called" printed to stdout.
If I do "class Foo..." I get nothing.  So it seems that the "class"
keyword does not end up calling new on Class when you define a new
class.  Does anybody know what's going on here?  Is something else
called instead?

Thanks,
Brandon
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (Guest)
on 2008-10-07 18:00
(Received via mailing list)
2008/10/7 Brandon Dimcheff <bdimchef@wieldim.com>:
> and then do "Foo = Class.new",  I get "new called" printed to stdout.  If I
> do "class Foo..." I get nothing.  So it seems that the "class" keyword does
> not end up calling new on Class when you define a new class.  Does anybody
> know what's going on here?  Is something else called instead?

Looks like there is a shortcut:

16:55:57 bas$ ruby -e 'set_trace_func lambda {|*a|p a}; class Foo;end'
["line", "-e", 1, nil, #<Binding:0x1002f0d4>, false]
["c-call", "-e", 1, :inherited, #<Binding:0x1002ef80>, Class]
["c-return", "-e", 1, :inherited, #<Binding:0x1002ef44>, Class]
["class", "-e", 1, nil, #<Binding:0x1002ed64>, false]
["end", "-e", 1, nil, nil, false]
16:56:13 bas$ ruby -e 'set_trace_func lambda {|*a|p a}; Foo=Class.new'
["line", "-e", 1, nil, #<Binding:0x1002f0e8>, false]
["c-call", "-e", 1, :new, #<Binding:0x1002f0ac>, Class]
["c-call", "-e", 1, :initialize, #<Binding:0x1002eeb8>, Class]
["c-call", "-e", 1, :inherited, #<Binding:0x1002edb4>, Class]
["c-return", "-e", 1, :inherited, #<Binding:0x1002ed78>, Class]
["c-return", "-e", 1, :initialize, #<Binding:0x1002ec88>, Class]
["c-return", "-e", 1, :new, #<Binding:0x1002eb98>, Class]
16:56:44 bas$

If you need hooks for class creation look closely at ":inherited" above.

Kind regards

robert
0ec4920185b657a03edf01fff96b4e9b?d=identicon&s=25 Yukihiro Matsumoto (Guest)
on 2008-10-07 18:01
(Received via mailing list)
Hi,

In message "Re: Difference between Foo = Class.new and class Foo"
    on Tue, 7 Oct 2008 23:51:03 +0900, Brandon Dimcheff
<bdimchef@wieldim.com> writes:

|I'm playing around with classes and discovered that
|
|class Foo
|   ...
|end
|
|and
|
|Foo = Class.new do
|   ...
|end
|
|seem to behave slightly differently.  I assumed that "class Foo" was
|just a shortcut that got translated into "Foo = Class.new", but when I
|muck with class in the following way:
|
|class Class
|   class << self
|     def new
|       puts "new called"
|       super
|     end
|   end
|end
|
|and then do "Foo = Class.new",  I get "new called" printed to stdout.
|If I do "class Foo..." I get nothing.  So it seems that the "class"
|keyword does not end up calling new on Class when you define a new
|class.  Does anybody know what's going on here?  Is something else
|called instead?

I think you're comparing the different code.  See the following code:

class Foo
   class << self
     def new
       puts "foo new called"
       super
     end
   end
end

Foo.new


Bar = Class.new do
   class << self
     def new
       puts "bar new called"
       super
     end
   end
end

Bar.new
0e5fc52ee8fe5166a259908e0626039e?d=identicon&s=25 Brandon Dimcheff (Guest)
on 2008-10-07 18:04
(Received via mailing list)
matz,

I don't think I'm doing conceptually different things below.  I'm
looking at creating and defining classes, not creating objects from
those classes.  I'm attempting to create a class called Foo in both
cases.  The first time, I use the class keyword.  The second time, I
call Class.new.  It seems that using the class keyword doesn't call
Class's metaclass's "new" method, while Class.new (obviously) does.

Thanks,
Brandon
0e5fc52ee8fe5166a259908e0626039e?d=identicon&s=25 Brandon Dimcheff (Guest)
on 2008-10-07 18:20
(Received via mailing list)
hmm, interesting.  I'm definitely going to have to use set_trace_func
more often.  Do you know if there's any way to tell which c function
is being called for the c-calls?  Like how does the ruby method
"inherited" map to rb_... in MRI?

Thanks,
Brandon
0ec4920185b657a03edf01fff96b4e9b?d=identicon&s=25 Yukihiro Matsumoto (Guest)
on 2008-10-07 18:27
(Received via mailing list)
Hi,

In message "Re: Difference between Foo = Class.new and class Foo"
    on Wed, 8 Oct 2008 00:32:41 +0900, Brandon Dimcheff
<bdimchef@wieldim.com> writes:

|I don't think I'm doing conceptually different things below.  I'm
|looking at creating and defining classes, not creating objects from
|those classes.  I'm attempting to create a class called Foo in both
|cases.  The first time, I use the class keyword.  The second time, I
|call Class.new.  It seems that using the class keyword doesn't call
|Class's metaclass's "new" method, while Class.new (obviously) does.

Now I know what you meant.  Literals and expressions do not go through
"new" method as a general rule.

              matz.
This topic is locked and can not be replied to.