Forum: Ruby Class Definition inside a method definition?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
65b23f7757747463b55afc326956d27d?d=identicon&s=25 Bihal (Guest)
on 2006-04-11 02:22
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
1fba4539b6cafe2e60a2916fa184fc2f?d=identicon&s=25 unknown (Guest)
on 2006-04-11 02:31
(Received via mailing list)
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 (dblack@wobblini.net)
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
65b23f7757747463b55afc326956d27d?d=identicon&s=25 Bihal (Guest)
on 2006-04-11 02:39
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
1fba4539b6cafe2e60a2916fa184fc2f?d=identicon&s=25 unknown (Guest)
on 2006-04-11 02:47
(Received via mailing list)
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 :-)  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 (dblack@wobblini.net)
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
47b1910084592eb77a032bc7d8d1a84e?d=identicon&s=25 Joel VanderWerf (Guest)
on 2006-04-11 03:20
(Received via mailing list)
dblack@wobblini.net wrote:
>> line.
>
> Oh.  So it does.  Well, I guess those are allowed, then :-)  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
430ea1cba106cc65b7687d66e9df4f06?d=identicon&s=25 David Vallner (Guest)
on 2006-04-11 03:42
(Received via mailing list)
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 ;P
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 ;P

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 Vallner
65b23f7757747463b55afc326956d27d?d=identicon&s=25 Bihal (Guest)
on 2006-04-11 04:05
Thanks for the explanation David, I'm sure it's close enough :P

> 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 Vallner

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.
65b23f7757747463b55afc326956d27d?d=identicon&s=25 Bihal (Guest)
on 2006-04-11 06:46
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
Cb48ca5059faf7409a5ab3745a964696?d=identicon&s=25 unknown (Guest)
on 2006-04-11 07:05
(Received via mailing list)
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
65b23f7757747463b55afc326956d27d?d=identicon&s=25 Bihal (Guest)
on 2006-04-11 07:15
Thanks a, that makes sense.

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


Bihal
10d9ed7ab11115b081bb36f56a7a13bc?d=identicon&s=25 John Wilger (jwilger)
on 2006-04-11 07:17
(Received via mailing list)
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 Wilger
johnwilger@gmail.com

http://johnwilger.com
65b23f7757747463b55afc326956d27d?d=identicon&s=25 Bihal (Guest)
on 2006-04-11 07:38
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
E34b5cae57e0dd170114dba444e37852?d=identicon&s=25 Logan Capaldo (Guest)
on 2006-04-11 07:39
(Received via mailing list)
On Apr 11, 2006, at 1:17 AM, John Wilger 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.
C1bcb559f87f356698cfad9f6d630235?d=identicon&s=25 Hal Fulton (Guest)
on 2006-04-11 07:48
(Received via mailing list)
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
Cb48ca5059faf7409a5ab3745a964696?d=identicon&s=25 unknown (Guest)
on 2006-04-11 15:38
(Received via mailing list)
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 ;-)

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

-a
10d9ed7ab11115b081bb36f56a7a13bc?d=identicon&s=25 John Wilger (jwilger)
on 2006-04-11 16:09
(Received via mailing list)
On Apr 10, 2006, at 10:36 PM, Logan Capaldo 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 Wilger
johnwilger@gmail.com

http://johnwilger.com
10d9ed7ab11115b081bb36f56a7a13bc?d=identicon&s=25 John Wilger (jwilger)
on 2006-04-11 16:21
(Received via mailing list)
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 Wilger
johnwilger@gmail.com

http://johnwilger.com
6e9ca26fa67c7d2ec5faa8c5f5826761?d=identicon&s=25 Rolly Ferolino (Guest)
on 2006-04-11 16:43
(Received via mailing list)
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?
65b23f7757747463b55afc326956d27d?d=identicon&s=25 Bihal (Guest)
on 2006-04-12 01:26
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 ;-)
>
> 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
E34b5cae57e0dd170114dba444e37852?d=identicon&s=25 Logan Capaldo (Guest)
on 2006-04-12 01:39
(Received via mailing list)
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.
E7559e558ececa67c40f452483b9ac8c?d=identicon&s=25 unknown (Guest)
on 2006-04-12 02:55
(Received via mailing list)
On Apr 11, 2006, at 10:40 AM, Rolly Ferolino wrote:
> 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?

+1

Gary Wright
65b23f7757747463b55afc326956d27d?d=identicon&s=25 Bihal (Guest)
on 2006-04-12 08:27
Logan Capaldo wrote:
> 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.

Because the aim is to parse and produce a (design) model from the code.

Not a list of source files (like in an IDE), but diagrams that show
relationships between classes, etc.

Our software has support for round-trip engineering, which means forward
and reverse engineering and code synchronisation. Which means you can

1) Import your code and see how it works from a high level
2) Design your code and generate the source files from the design
3) Import code or create a design, and synchronise changes forward and
backward. ie. Change the code and the model can be updated, change the
model and the code can be updated.

I hope that makes sense.

Bihal
93d566cc26b230c553c197c4cd8ac6e4?d=identicon&s=25 Pit Capitain (Guest)
on 2006-04-12 09:10
(Received via mailing list)
Bihal schrieb:
> Our software has support for round-trip engineering, which means forward
> and reverse engineering and code synchronisation. Which means you can
>
> 1) Import your code and see how it works from a high level
> 2) Design your code and generate the source files from the design
> 3) Import code or create a design, and synchronise changes forward and
> backward. ie. Change the code and the model can be updated, change the
> model and the code can be updated.

Bihal, forward engineering Ruby code should be no problem, but I doubt
that you can reverse engineer arbitrary Ruby code. I see at least the
following problems:

1) The Ruby object model is different from that of other OO languages.
In Ruby, you can add methods to single objects. I don't think that the
meta model of your tool can represent this concept. You would also need
to handle Ruby's concept of mixins, which is a kind of multiple
inheritance, but with slightly different semantics.

2) Ruby is very dynamic. You can create and alter classes and methods at
runtime. The design model of such code could only be determined by
actually running the code, and it could be dependent on runtime
parameters.

3) You can use method_missing to implement methods "on the fly". A tool
has no chance to recognize those methods. Even running the code wouldn't
help in this case.

Again, it would be nice to have Ruby support in your tool, but there are
huge problems way beyond the syntax level. As others have mentioned, I'd
strongly suggest learning the Ruby concepts first. Only then, if you
still think your tool can handle all this, should you look at the
syntax.

Regards,
Pit
65b23f7757747463b55afc326956d27d?d=identicon&s=25 Bihal (Guest)
on 2006-04-12 09:22
Pit Capitain wrote:
> Bihal schrieb:
>> Our software has support for round-trip engineering, which means forward
>> and reverse engineering and code synchronisation. Which means you can
>>
>> 1) Import your code and see how it works from a high level
>> 2) Design your code and generate the source files from the design
>> 3) Import code or create a design, and synchronise changes forward and
>> backward. ie. Change the code and the model can be updated, change the
>> model and the code can be updated.
>
> Bihal, forward engineering Ruby code should be no problem, but I doubt
> that you can reverse engineer arbitrary Ruby code. I see at least the
> following problems:
>
> 1) The Ruby object model is different from that of other OO languages.
> In Ruby, you can add methods to single objects. I don't think that the
> meta model of your tool can represent this concept. You would also need
> to handle Ruby's concept of mixins, which is a kind of multiple
> inheritance, but with slightly different semantics.
>
> 2) Ruby is very dynamic. You can create and alter classes and methods at
> runtime. The design model of such code could only be determined by
> actually running the code, and it could be dependent on runtime
> parameters.
>
> 3) You can use method_missing to implement methods "on the fly". A tool
> has no chance to recognize those methods. Even running the code wouldn't
> help in this case.
>
> Again, it would be nice to have Ruby support in your tool, but there are
> huge problems way beyond the syntax level. As others have mentioned, I'd
> strongly suggest learning the Ruby concepts first. Only then, if you
> still think your tool can handle all this, should you look at the
> syntax.
>
> Regards,
> Pit

Thanks Pit.

Yes, as I've come to know Ruby better, I've run into these things. Some
have already come up in other languages, but Ruby is pretty unique.
However, we can only start with the basics, and that's all we're aiming
for at the moment.

How to model the more complicated parts (and mix-ins is one we've
already discussed) are really being pushed into the "later" box for the
time being. Our tool is quite customisable and I do believe we could
accomodate most of Ruby's nuances.

I'm kind of hoping that in the future when we are figuring/deciding
these things, that some of you guys might be able to provide some input!
:D

Bill

PS: I don't know if this is implicit or not, but in our software code
that is just parsed as general code is left alone in the synchronising,
so mixins etc. would not be damaged by reverse engineering, just
not...conceptualised.
31ab75f7ddda241830659630746cdd3a?d=identicon&s=25 Austin Ziegler (Guest)
on 2006-04-12 17:05
(Received via mailing list)
On 4/12/06, Bihal <wmioch@hotmail.com> wrote:
> How to model the more complicated parts (and mix-ins is one we've
> already discussed) are really being pushed into the "later" box for the
> time being. Our tool is quite customisable and I do believe we could
> accomodate most of Ruby's nuances.

For the static part of the modeling, you may want to try to understand
how RDoc generates DOT files for generation with AT&T's GraphViz,
since it can at least do basic class diagrams.

-austin
This topic is locked and can not be replied to.