Difference between Foo = Class.new and class Foo

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

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

···

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?

--
remember.guy do |as, often| as.you_can - without end

Hi,

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

···

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:
--
              matz.

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

···

On Oct 7, 2008, at 10:56, Robert Klemme wrote:

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

--
remember.guy do |as, often| as.you_can - without end

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

···

On Oct 7, 2008, at 10:57, Yukihiro Matsumoto wrote:

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

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.