Class Definition inside a method definition?


#1

I was under the impression that a class definition could not be inside a
method.
Quote from Programming Ruby

“Method definitions may not contain class, module, or instance method
definitions.”

And yet I’ve found this source code.

def add_accessor(name)
methodname = name
if self.respond_to?(methodname)
methodname = safe_accessor_name(methodname)
end
sclass = class << self; self; end
sclass.send(:define_method, methodname, proc {
@data[@array.index(name)]
})
sclass.send(:define_method, methodname + ‘=’, proc { |value|
@data[@array.index(name)] = value
})
end

Are singeltons just special?

Bihal


#2

Hi –

On Tue, 11 Apr 2006, Bihal wrote:

methodname = name
end

Are singeltons just special?

The call to send is not a class definition; it’s a method call that
happens to result in a class coming into being. The rule doesn’t say
that the number of classes that exist when the method exits has to be
the same as the number that existed when it started – just that there
can’t be a class definition (i.e., the syntactic contruct introduced
with the “class” keyword) inside a method definition.

David


David A. Black (removed_email_address@domain.invalid)
Ruby Power and Light, LLC (http://www.rubypowerandlight.com)

“Ruby for Rails” coming in PDF April 15, and in paper May 5!
http://www.manning.com/black


#3

Thanks David. I’m not sure you caught sight of the line of code I was
worried about. I should have made it more clear. This one in particular

sclass = class << self; self; end

does use a class keyword and syntactic construct, it’s just on a single
line.

Bihal


#4

removed_email_address@domain.invalid wrote:

line.

Oh. So it does. Well, I guess those are allowed, then :slight_smile: I’m not
sure what the rationale is. I wonder if it has something to do with
the realm of constants, compile-time resolution, etc., or just the
theory that class << obj isn’t of much use if you can’t use it
dynamically in methods.

Maybe it is allowed for consistency with the fact that the ‘def
obj.meth’ form is allowed in that context.

def foo
x = []
def x.bar
“bar”
end
puts x.bar
end

foo


#5

Hi –

On Tue, 11 Apr 2006, Bihal wrote:

Thanks David. I’m not sure you caught sight of the line of code I was
worried about. I should have made it more clear. This one in particular

sclass = class << self; self; end

does use a class keyword and syntactic construct, it’s just on a single
line.

Oh. So it does. Well, I guess those are allowed, then :slight_smile: I’m not
sure what the rationale is. I wonder if it has something to do with
the realm of constants, compile-time resolution, etc., or just the
theory that class << obj isn’t of much use if you can’t use it
dynamically in methods.

David


David A. Black (removed_email_address@domain.invalid)
Ruby Power and Light, LLC (http://www.rubypowerandlight.com)

“Ruby for Rails” coming in PDF April 15, and in paper May 5!
http://www.manning.com/black


#6

Thanks for the explanation David, I’m sure it’s close enough :stuck_out_tongue:

Also, Pickaxe seems mildly wrong about the instance method definition
bit:

irb(main):001:0> class Foo
irb(main):002:1> def bar
irb(main):003:2> def quux
irb(main):004:3> puts “Foo#quux”
irb(main):005:3> end
irb(main):006:2> end
irb(main):007:1> end
=> nil
irb(main):008:0> foo = Foo.new
=> #Foo:0xb7caf8c8
irb(main):009:0> foo.quux
NoMethodError: undefined method `quux’ for #Foo:0xb7caf8c8
from (irb):9
from :0
irb(main):010:0> foo.bar
=> nil
irb(main):011:0> foo.quux
Foo#quux
=> nil
irb(main):012:0> Foo.new.quux
Foo#quux
=> nil

Is that 1st ed. or 2nd ed. you’re quoting? Might have changed between
Ruby 1.6
and 1.8.

David V.

1st Edition. I’ve been tossing up whether I should ask the money guys
around here to buy the 2nd Ed. I don’t know how much it will help me to
write this grammar than the first edition.


#7

DÅ?a Utorok 11. Apríl 2006 02:39 Bihal napísal:

Thanks David. I’m not sure you caught sight of the line of code I was
worried about. I should have made it more clear. This one in particular

sclass = class << self; self; end

does use a class keyword and syntactic construct, it’s just on a single
line.

Bihal

Well, “class << self” isn’t really a class definition, it’s a change of
scope
into an object’s singleton class. It just looks a real awful lot like
one :stuck_out_tongue_winking_eye:
Which might, or might not exist at the time, and in the latter case it
indeeds starts to exist. I’m also possibly very wrong, but I’ve been
able to
live with understanding this that way :stuck_out_tongue_winking_eye:

Also, Pickaxe seems mildly wrong about the instance method definition
bit:

irb(main):001:0> class Foo
irb(main):002:1> def bar
irb(main):003:2> def quux
irb(main):004:3> puts “Foo#quux”
irb(main):005:3> end
irb(main):006:2> end
irb(main):007:1> end
=> nil
irb(main):008:0> foo = Foo.new
=> #Foo:0xb7caf8c8
irb(main):009:0> foo.quux
NoMethodError: undefined method `quux’ for #Foo:0xb7caf8c8
from (irb):9
from :0
irb(main):010:0> foo.bar
=> nil
irb(main):011:0> foo.quux
Foo#quux
=> nil
irb(main):012:0> Foo.new.quux
Foo#quux
=> nil

Is that 1st ed. or 2nd ed. you’re quoting? Might have changed between
Ruby 1.6
and 1.8.

David V.


#8

On Tue, 11 Apr 2006, Bihal wrote:

EEOOFF
eval(str)
eval("#{classname} ")
end

Any thoughts?

Bihal

i don’t see a class definition - only some methods being called on
‘self’,
which happens to be a class here.

eg.

self.eval str
self.eval “#{ classname }”

this method could have just have easily been written as

def self.declare_dndclass cn, rn
klass =
Class.new(DragDropRubyObject) do
FormatName = rn.to_s
FormatId = RegisterClipboardFormat[FormatName]
end
const_set cn, klass
const_get cn
end

and here this is also no class definition in the syntactical sense -
only the
creation of a class object and a const assignment.

make sense?

-a


#9

Hey guys,

Here’s another one, only it’s not a singelton

def self.declare_dndclass(classname,registername)
str = <<“EEOOFF”
class #{classname} < DragDropRubyObject
FormatName = ‘#{registername}’
FormatId = RegisterClipboardFormat.call(FormatName)
end
EEOOFF
eval(str)
eval("#{classname} ")
end

Any thoughts?

Bihal


#10

On Apr 10, 2006, at 9:46 PM, Bihal wrote:

Any thoughts?

I might suggest taking the time to actually sit down and really learn
Ruby. At the risk of sounding rude – spending the day asking the
mailing list questions about the language syntax without trying to
learn the language and actually program with it is just a waste of
everyone’s time (including your own).

You said you are working off the 1st ed. of the Pickaxe, I’d
definitely recommend getting a copy of the second edition. Beyond
that, you’re only going to get a good feel for the language if you
actually use the language and experiment with it.

I don’t intend to put you off or make you feel unwelcome here, I just
think you are selling yourself and the language short by thinking it
is enough to simply understand the parsing grammar without
understanding the semantics.

Regards,

John W.
removed_email_address@domain.invalid

http://johnwilger.com


#11

Thanks a, that makes sense.

It’s just, from my point of view, really convoluted. >.<

Bihal


#12

Sorry John, I didn’t realise this was a mailing list as opposed to a
forum.

As for learning Ruby, I simply don’t have the time. We are putting
together a free Ruby plugin for our software, but it’s taken so much
time already that we’re about to drop it. I’ve come here to get quick
and accurate answers from experienced users. I can see how this would be
annoying on a mail list, so again I apologise.

Bihal


#13

On Apr 11, 2006, at 1:17 AM, John W. wrote:

I don’t intend to put you off or make you feel unwelcome here, I
just think you are selling yourself and the language short by
thinking it is enough to simply understand the parsing grammar
without understanding the semantics.

Well his job is to write a ruby grammar, I don’t think he necessarily
wants or needs to learn ruby for its own sake.


#14

Bihal wrote:

Sorry John, I didn’t realise this was a mailing list as opposed to a
forum.

As for learning Ruby, I simply don’t have the time. We are putting
together a free Ruby plugin for our software, but it’s taken so much
time already that we’re about to drop it. I’ve come here to get quick
and accurate answers from experienced users. I can see how this would be
annoying on a mail list, so again I apologise.

Don’t worry too much about that. The mailing list and the newsgroup are
mirrored to each other (except when that breaks) and apparently the
ruby-forum messages go here too.

Two comments though.

  1. It’s much easier and meaningful to write a grammar for a language
    whose semantics you understand, not just syntax.

  2. Writing a Ruby parser is difficult for several reasons. Ask those
    who tried and gave up.

But please: Stay and learn Ruby. We’ll help.

Hal


#15

On Apr 10, 2006, at 10:36 PM, Logan C. wrote:

Well his job is to write a ruby grammar, I don’t think he
necessarily wants or needs to learn ruby for its own sake.

That’s just it – in my opinion, trying to write the parser without
learning Ruby is probably a futile effort. If someone has evidence to
the contrary, I’m not unwilling to change that view – I’ve just
never seen any.

Regards,

John W.
removed_email_address@domain.invalid

http://johnwilger.com


#16

On Tue, 11 Apr 2006, Bihal wrote:

Sorry John, I didn’t realise this was a mailing list as opposed to a
forum.

As for learning Ruby, I simply don’t have the time. We are putting
together a free Ruby plugin for our software, but it’s taken so much
time already that we’re about to drop it. I’ve come here to get quick
and accurate answers from experienced users. I can see how this would be
annoying on a mail list, so again I apologise.

Bihal

believe us - there have been much more annoying posters in the past.
you’ve
got a ways to go before entering the truly annoying leagues :wink:

i haven’t followed all of this thread but, given ruby’s dual license,
can’t
you just rip out it’s parser?

-a


#17

On Apr 10, 2006, at 10:38 PM, Bihal wrote:

As for learning Ruby, I simply don’t have the time. We are putting
together a free Ruby plugin for our software, but it’s taken so much
time already that we’re about to drop it. I’ve come here to get quick
and accurate answers from experienced users.

While it’s great that your company is interested in providing support
for Ruby, if your constraints prevent you from taking the time to
learn the language (or spend the money to work with someone who
already knows it), it’s unlikely to be something that an experienced
Ruby programmer is going to find very useful. Since it would be
nice to see more tools supporting Ruby, I’ll urge you to take the
time to learn the language and be able to provide excellent support
for it in your product. (Besides, you’ll probably find that you
really enjoy programming in Ruby!)

As someone else already said, the Ruby community is a great group of
people, and this list in particular has always been willing to go the
extra mile to help people learn the language.

I can see how this would be
annoying on a mail list, so again I apologise.

Perhaps I came across too harshly in my original message. Again, I
don’t want to discourage you from learning Ruby or participating in
the group. I only meant to suggest that the specific questions you
were asking were unlikely to provide the answers you’ll need in the
long run.

Regards,

John W.
removed_email_address@domain.invalid

http://johnwilger.com


#18

On Apr 11, 2006, at 7:27 PM, Bihal wrote:

e have an in-house parser already, which we provide grammar files
to so
that it can parse. Because it’s modelling software, it’s not simply a
matter of parsing it, but telling the software what to do with each
line
when reverse engineering.

Can’t you use Ruby’s C API to do all this? Why are you “reverse-
engineering” ruby especially given ruby’s open source nature.


#19

I don’t think that the original question was annoying. It came from
someone
new to the language and sincerely wanted to learn it. Not all of us are
experts in parsers and semantics; and some of us need additional
dialogue to
get the concept sink in. What’s annoying to others might be interesting
to
some. So what’s the use of the community if it is not willing to help?


#20

unknown wrote:

believe us - there have been much more annoying posters in the past.
you’ve
got a ways to go before entering the truly annoying leagues :wink:

i haven’t followed all of this thread but, given ruby’s dual license,
can’t
you just rip out it’s parser?

-a

We have an in-house parser already, which we provide grammar files to so
that it can parse. Because it’s modelling software, it’s not simply a
matter of parsing it, but telling the software what to do with each line
when reverse engineering.

Thanks for the support everyone,

Bihal