Difference between Class.new and class

Hi,

why do class definitions with the keyword "class" return nil and not the class itself?

   >> class Foo
   >> def foo
   >> puts "in Foo"
   >> end
   >> end
   => nil

and what is the difference to:

   >> Bar = Class.new do
   >> define_method(:bar) do
   >> puts "in Bar"
   >> end
   >> end
   => Bar

Thank you,
Levin

Hi,

why do class definitions with the keyword "class" return nil and not
the class itself?

Because the last expression in the block is returned:

class Foo; self end

=> Foo

class Bar; 123 end

=> 123

Method definitions ("def ...") return nil.

   >> class Foo
   >> def foo
   >> puts "in Foo"
   >> end
   >> end
   => nil

and what is the difference to:

   >> Bar = Class.new do
   >> define_method(:bar) do
   >> puts "in Bar"
   >> end
   >> end
   => Bar

The former is the standard syntax for defining classes. The latter can be used to create anonymous classes.

Irks = Class.new

=> Irks

ui = Class.new

=> #<Class:0x10189d98>

A disadvantage of the latter approach is that you cannot define methods that receive a block. There is no equivalent (yet) for "def foo(&b) b.call(1) end" with define_method, because you cannot do define_method(:foo) {|&b| b.call(1)}. Also, you cannot have default values for method arguments with define_value. The bottom line is: use the block form only if you need anonymous classes or have to otherwise. HTH

Kind regards

    robert

···

Levin Alexander <levin@grundeis.net> wrote:

Levin Alexander wrote:

Hi,

why do class definitions with the keyword "class" return nil and not the class itself?

  >> class Foo
  >> def foo
  >> puts "in Foo"
  >> end
  >> end
  => nil

irb(main):001:0> class X
irb(main):002:1> def y
irb(main):003:2> puts "z"
irb(main):004:2> end
irb(main):005:1> self
irb(main):006:1> end
=> X
The class definition returns the result of the last statement, so you can put 'self' just before the end of the definition to get it to return the class. It's returning nil because def returns nil.

Robert Klemme wrote:

A disadvantage of the latter approach is that you cannot define methods that receive a block. There is no equivalent (yet) for "def foo(&b) b.call(1) end" with define_method, because you cannot do define_method(:foo) {|&b| b.call(1)}.

(flori@lambda:~ 0)$ irb
irb(main):001:0> A = Class.new { define_method(:foo) {|&b| b.call(1)} }
=> A
irb(main):002:0> A.new.foo { |x| 2 * x }
=> 2
irb(main):003:0> RUBY_VERSION
=> "1.9.0"

···

--
Florian Frank

"Robert Klemme" <bob.news@gmx.net> writes:

There is no equivalent (yet) for "def foo(&b) b.call(1) end" with
define_method, because you cannot do define_method(:foo) {|&b|
b.call(1)}.

As Florian Frank pointed out, this is fixed in Ruby 1.9.

Also, you cannot have default values for method arguments
with [define_method].

I just wanted to point out that this is not a show-stopping problem.
In Ruby 1.9, `define_method' can do everything `def' can.

   def foo(bar, baz = QUUX, *rest)
     ...
   end

can be written as

   define_method :foo do |bar, *rest|
     baz = rest.empty? and QUUX or rest.shift
     ...
   end

For longer parameter lists, you could refactor a bit:

   class Array
     def shift_or default
       if empty? then default else shift end
     end
   end

   define_method :foo do |bar, *rest|
     baz1 = rest.shift_or QUUX1
     baz2 = rest.shift_or QUUX2
     baz3 = rest.shift_or QUUX3
     ...
   end

But of course, you already know this.

As I said, I just wanted to point out that `def' and `define_method'
are essentially equal in power as of Ruby 1.9.

···

--
Daniel Brockman <daniel@brockman.se>

    So really, we all have to ask ourselves:
    Am I waiting for RMS to do this? --TTN.

Robert Klemme wrote:

A disadvantage of the latter approach is that you cannot define methods that receive a block. There is no equivalent (yet) for "def foo(&b) b.call(1) end" with define_method, because you cannot do define_method(:foo) {|&b| b.call(1)}. Also, you cannot have default values for method arguments with define_value. The bottom line is: use the block form only if you need anonymous classes or have to otherwise.

But you can use def in Class.new blocks:

Bar = Class.new do
   def two_times(&block)
     2.times(&block)
   end
end

Bar.new.two_times { puts "Hello World!"}

This is on 1.8.2.

Daniel Brockman <daniel@brockman.se> writes:

   def foo(bar, baz = QUUX, *rest)
     ...
   end

can be written as

   define_method :foo do |bar, *rest|
     baz = rest.empty? and QUUX or rest.shift
     ...
   end

My apologies, that should have been

   define_method :foo do |bar, *rest|
     baz = rest.empty? && QUUX || rest.shift
     ...
   end

···

--
Daniel Brockman <daniel@brockman.se>