Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[curiousity] why aren't declarations just syntactic sugar?

0 views
Skip to first unread message

Lionel Thiry

unread,
Apr 5, 2005, 7:25:53 PM4/5/05
to
Hello!

I'd like to know why in ruby, a construction like:
class MyClass
...
end

isn't just a syntactic sugar for:
MyClass = Class.new do
...
end

Is it a problem about block variable binding? Is it a problem of speed?
Something else?

Thanks in advance.

--
Lionel Thiry

Bill Kelly

unread,
Apr 5, 2005, 7:32:17 PM4/5/05
to
From: "Lionel Thiry" <lthiryido...@skynetnospam.be>

>
> I'd like to know why in ruby, a construction like:
> class MyClass
> ...
> end
>
> isn't just a syntactic sugar for:
> MyClass = Class.new do
> ...
> end

It'd probably at least have to be:

(MyClass ||= Class.new) do

so we can re-open classes as we currently do.

Other than that... I dunno... :)


Regards,

Bill


Hal Fulton

unread,
Apr 5, 2005, 7:31:08 PM4/5/05
to
Lionel Thiry wrote:
> Hello!
>
> I'd like to know why in ruby, a construction like:
> class MyClass
> ...
> end
>
> isn't just a syntactic sugar for:
> MyClass = Class.new do
> ...
> end
>
> Is it a problem about block variable binding? Is it a problem of speed?
> Something else?

I've seen this discussed... I think it's just historical reasons
first of all. I'm not sure this kind of unification was "thought of"
at the beginning.

But there are also other considerations, I think. For example, a block
is a closure, whereas the body of a class definition is not. A question
of scope.


Hal

nobu....@softhome.net

unread,
Apr 5, 2005, 7:33:19 PM4/5/05
to
Hi,

At Wed, 6 Apr 2005 08:24:39 +0900,
Lionel Thiry wrote in [ruby-talk:137002]:
> class MyClass
> ...
> end

class hides outer scope, so this causes an error.

x = 1
class MyClass
p x # => Name Error
end

> isn't just a syntactic sugar for:
> MyClass = Class.new do
> ...
> end

But block doesn't.

--
Nobu Nakada


Saynatkari

unread,
Apr 5, 2005, 10:08:38 PM4/5/05
to

I, I think that is a good idea. On the other hand, I also think that

def foo(x)
do_something_with x
end

Should be syntactic sugar for

def(:name => :foo,
:bind => binding,
:body => {|x| do_something_with x}
)

Then again, the current system works well too :)

> Lionel Thiry

E


Dave Burt

unread,
Apr 5, 2005, 10:45:37 PM4/5/05
to
"Bill Kelly" <bi...@cts.com> scribbled:

> It'd probably at least have to be:
>
> (MyClass ||= Class.new) do
>
> so we can re-open classes as we currently do.

"MyClass do ..." looks like a syntax error to me.

How about a Class#| for this (think set union like Array#|)?

MyClass |= Class.new do
...

First-class methods would make implementation of something like this
convenient.

Cheers,
Dave


Florian Groß

unread,
Apr 6, 2005, 8:51:03 AM4/6/05
to
Dave Burt wrote:

> "MyClass do ..." looks like a syntax error to me.
>
> How about a Class#| for this (think set union like Array#|)?
>
> MyClass |= Class.new do

> ....


>
> First-class methods would make implementation of something like this
> convenient.

That would not work though as the block can not bind to the | operator.

Dave Burt

unread,
Apr 7, 2005, 2:28:47 AM4/7/05
to
"Florian Groß" <flo...@gmail.com> responded:

I know that. I was thinking, "what if you could add all the methods defined
in that anonymous class to MyClass?"

This would effectively be a way of doing multiple inheritance, and has all
the problems associated with that. (e.g. Class.new will make a class that
inherits from Object, and those methods would have to be "ORed" into MyClass
as well as any explicitly defined.) So it's a bad thing.

It makes more sense if the RHS is a Module. And you can do that already,
with mix-ins (extend, include)

I still think it's an interesting thought.

Cheers,
Dave


Curt Sampson

unread,
Apr 8, 2005, 12:49:39 AM4/8/05
to
On Wed, 6 Apr 2005, Saynatkari wrote:

> I, I think that is a good idea. On the other hand, I also think that
>
> def foo(x)
> do_something_with x
> end
>
> Should be syntactic sugar for
>
> def(:name => :foo,
> :bind => binding,
> :body => {|x| do_something_with x}
> )
>
> Then again, the current system works well too :)

Nah, your suggestion is much better. [(let f (lambda ...))]

This is the thing that kills me about ruby, and makes it a very
difficult language to learn well: all the stupid "tricks" you need to
learn, at great pain and expense.

For example: explain the results of these two programs to me:

----------
def do_me_harder
puts "Oh yes!"
end

puts do_me_harder
----------
module Foo

def do_me_harder
puts "Oh yes!"
end

puts do_me_harder
end
----------

cjs
--
Curt Sampson <c...@cynic.net> +81 90 7737 2974 http://www.NetBSD.org
Make up enjoying your city life...produced by BIC CAMERA


Jon Raphaelson

unread,
Apr 8, 2005, 1:24:54 AM4/8/05
to
Curt Sampson wrote:
<snip>

>
> For example: explain the results of these two programs to me:
>
> ----------
> def do_me_harder
> puts "Oh yes!"
> end
>
> puts do_me_harder
> ----------
> module Foo
>
> def do_me_harder
> puts "Oh yes!"
> end
>
> puts do_me_harder
> end
> ----------
>
> cjs

Both of those will produce the output

Oh yes!
nil

which is absolutly correct. I'm not sure what the problem with those is.
If it is that you are confused about the nil, that's because puts
returns nil, and you are puts'ing the result of do_me_harder, which is
the result of the last expression in do_me_harder, which is a puts and
hence nil.

If the confusion is that the program wrapped in a module prints
something, that is because, unlike other programming languages where the
class/module defintions are read but not executed, in ruby those
definitions are executed. This is really useful, for example this is the
way alias works and mixins I believe (but I don't know for sure, so if
I'm worng sorry), as well as most domain specific language stuff.


Dominik Bathon

unread,
Apr 9, 2005, 1:46:24 PM4/9/05
to
On Fri, 08 Apr 2005 07:24:54 +0200, Jon Raphaelson
<jonrap...@gmail.com> wrote:

> Curt Sampson wrote:
> <snip>
>> For example: explain the results of these two programs to me:
>> ----------
>> def do_me_harder
>> puts "Oh yes!"
>> end
>> puts do_me_harder
>> ----------
>> module Foo
>> def do_me_harder
>> puts "Oh yes!"
>> end
>> puts do_me_harder
>> end
>> ----------
>> cjs
>
> Both of those will produce the output
>
> Oh yes!
> nil

No, they won't ;-)

The 2nd will raise an exception:
NameError: undefined local variable or method `do_me_harder' for Foo:Module

do_me_harder is an instance method (you can only call it on an instance of
a class including Foo):

class A
include Foo
end

A.new.do_me_harder

But the following would work:

module Foo
def Foo.do_me_harder
puts "Oh yes!"
end

puts do_me_harder
end

In this case do_me_harder is a singleton method of module Foo.

HTH,
Dominik


Curt Sampson

unread,
Apr 13, 2005, 2:27:17 AM4/13/05
to
On Fri, 8 Apr 2005, Jon Raphaelson wrote:

> Both of those will produce the output
> Oh yes!

You and I must be using different versions of ruby:

$ cat z.rb


module Foo
def do_me_harder
puts "Oh yes!"
end

do_me_harder
end
$ ruby z.rb
z.rb:5: undefined local variable or method `do_me_harder' for Foo:Module (NameError)

Whereas:

$ cat z1.rb


def do_me_harder
puts "Oh yes!"
end

do_me_harder
$ ruby z1.rb
Oh yes!

Now care to try again with an explanation?

Two notes on the previous post, BTW. First the doubled "puts" was not
intentional; just me typing without proof-reading. Second, this may have
worked for you because you put both code samples into the same file and
ran them in the order I gave orginally, which was reversed from above.

Curt Sampson

unread,
Apr 13, 2005, 2:38:40 AM4/13/05
to
On Sun, 10 Apr 2005, Dominik Bathon wrote:

> module Foo
> def Foo.do_me_harder
> puts "Oh yes!"
> end
> puts do_me_harder
> end
>
> In this case do_me_harder is a singleton method of module Foo.

Oops! Shoulda read your post first. Anyway, so what's going on with this,
as compared to doing the same thing outside a module declaration, which
I'd understood to mean you were defining stuff in the "top-level module."

Well, it's really the top-level class (i.e., Object), right? But then,

def hello
puts "hello"
end

class Object
def goodbye
puts "goodbye"
end
end

Object.new.goodbye # prints "goodbye"
goodbye # prints "goodbye"
class Object
hello # prints "hello"
end
Object.new.hello # private method `hello' called for #<Object:...

I dunno; a lot of my predictions about what should happen in Ruby don't
work out very well.

I wish that there were a two-page document somewhere explaining just the
language syntax itself that would, if read very carefully, explain all
of this.

Pit Capitain

unread,
Apr 13, 2005, 3:36:58 AM4/13/05
to
Curt Sampson schrieb:

> I'd understood to mean you were defining stuff in the "top-level module."
>
> Well, it's really the top-level class (i.e., Object), right? But then,
>
> def hello
> puts "hello"
> end

This defines a private instance method of Object. You define the method
without specifying a class, just like a procedure in a non-OO language.
Because it is defined in Object, you can call it everywhere:

hello
class X
hello
def m
hello
end
end

You can really treat it like a standalone procedure. But you cannot
treat it like an object's method, because it is private. Private methods
can only be called without specifying the receiver of the method.

"foo".hello # => error, private method...

There's a trick for calling private methods, though:

"foo".send( :hello ) # => hello

The method is there (inherited from Object), but it is private. This is
a clever way to be able to either write procedural or OO code and to
even use both together.

> class Object
> def goodbye
> puts "goodbye"
> end
> end

This defines a public (per default) instance method of Object.

> Object.new.goodbye # prints "goodbye"

Send the message to a new object, which inherits the (public) method
"goodbye" from Object (as all objects do).

> goodbye # prints "goodbye"

Send the message to self, the top level object (main). This is an
Object, so it inherits method "goodbye" from Object, too.

> class Object
> hello # prints "hello"
> end

Send the message to the class Object. Since classes are instances of
Object in Ruby, even the class Object inherits method "goodbye" from Object.

> Object.new.hello # private method `hello' called for #<Object:...

Send the message to a new object. The object inherits method "hello"
from Object, but it is a private method, so it can't be called with an
explicit receiver.

> I dunno; a lot of my predictions about what should happen in Ruby don't
> work out very well.

When learning Ruby, I made the experience that most of the times the
code I wrote just worked. Without thinking about the language's
internals I wrote some kind of pseudocode in Ruby syntax and more than
often found that I just could run it. Sometimes I really was surprised
that the code I had written was working, and I thought "how is Ruby
doing this?" Then I started to experiment with the language and I had
many surprises, but it finally made sense most of the times, at least
for me. I got the most POLS out of Ruby when not thinking about Ruby.

> I wish that there were a two-page document somewhere explaining just the
> language syntax itself that would, if read very carefully, explain all
> of this.

I don't think that the syntax alone would have helped you in this case.

Regards,
Pit


0 new messages