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

L

Lionel Thiry

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

Hal Fulton

Lionel said:
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
 
B

Bill Kelly

From: "Lionel Thiry said:
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
 
N

nobu.nokada

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

Saynatkari

Lionel said:
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.

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
 
D

Dave Burt

Bill Kelly said:
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
 
F

Florian Groß

Dave said:
"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.
 
D

Dave Burt

Florian Groß said:
That would not work though as the block can not bind to the | operator.

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
 
C

Curt Sampson

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
 
J

Jon Raphaelson

Curt Sampson wrote:
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

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

Dominik Bathon

Curt Sampson wrote:


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
 
C

Curt Sampson

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.

cjs
 
C

Curt Sampson

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.

cjs
 
P

Pit Capitain

Curt said:
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,734
Messages
2,569,441
Members
44,832
Latest member
GlennSmall

Latest Threads

Top