A ruby course

  • Follow


Hello List,

again I ask for your help. I'm going to give a 16 hours course on ruby 
this week, and I've created some slides to aid me with this.
I have to admit that some examples might not be as bright as I wish, and 
also there are missing some exercises.
I created the slides in english, such that they can be used by a bigger 
part of the community if need should be.

The slides will not cover all that I hope to say in the course, when the 
slides have finished I will start with a free experimentation phase 
based on my ants sample implementation
http://ruby.brian-schroeder.de/ants/

It would be great if some of you could look at the slides and correct 
the language and if somebody comes up with a great example or exercise I 
would also be glad for comments.

The slides are located at
http://ruby.brian-schroeder.de/course/

Regards,

Brian


-- 
Brian Schr�der
http://ruby.brian-schroeder.de/


0
Reply ruby5435 (237) 10/4/2004 5:17:47 PM

On Oct 4, 2004, at 12:17 PM, Brian Schr�der wrote:

> Hello List,
>
> again I ask for your help. I'm going to give a 16 hours course on ruby 
> this week, and I've created some slides to aid me with this.

The presentation is looking pretty good.  One thing I did notice, on 
page 19 and 20, the comments do not reflect the code.  You talk about 
yield, but use a passed block.

Cover slide looks good!  ;)

James Edward Gray II




0
Reply james8284 (4404) 10/4/2004 5:32:53 PM


Brian Schr�der wrote:
>
> Hello List,
>
> again I ask for your help. I'm going to give a 16 hours course on ruby
> this week, and I've created some slides to aid me with this.
> I have to admit that some examples might not be as bright as I wish, and
> also there are missing some exercises.
> I created the slides in english, such that they can be used by a bigger
> part of the community if need should be.
>
> The slides will not cover all that I hope to say in the course, when the
> slides have finished I will start with a free experimentation phase
> based on my ants sample implementation
> http://ruby.brian-schroeder.de/ants/
>
> It would be great if some of you could look at the slides and correct
> the language and if somebody comes up with a great example or exercise I
> would also be glad for comments.
>
> The slides are located at
> http://ruby.brian-schroeder.de/course/

This is great! Can I add your slides to the WhyRuby? repository
(http://whyruby.rubyforge.org/wiki/wiki.pl?Ruby_Presentations)?

Curt



0
Reply curt1 (558) 10/4/2004 5:35:28 PM

Do you have speaker notes? 

If you had 1 to 2 hours to present ruby to a group of people what do
you think would be the most important point to get across? Mind you,
you would need to spend 30- mins on syntax.
Becker


On Tue, 5 Oct 2004 02:32:53 +0900, James Edward Gray II
<james@grayproductions.net> wrote:
> On Oct 4, 2004, at 12:17 PM, Brian Schr�der wrote:
> 
> > Hello List,
> >
> > again I ask for your help. I'm going to give a 16 hours course on ruby
> > this week, and I've created some slides to aid me with this.
> 
> The presentation is looking pretty good.  One thing I did notice, on
> page 19 and 20, the comments do not reflect the code.  You talk about
> yield, but use a passed block.
> 
> Cover slide looks good!  ;)
> 
> James Edward Gray II
> 
>



0
Reply Becker004 (43) 10/4/2004 5:38:53 PM

Ruby Quick Start by Michael Neumann
A German language presentation that introduces Ruby. The target
audience is software developers. Format:
[http://www.pureteenz.com/hentai/ hentai] PDF.

Download at [http://rubyforge.org/docman/view.php/251/94/RubyQuickStart?.tgz
RubyQuickStart?.tgz]

Does anyone have this in english?
Becker


On Tue, 5 Oct 2004 02:35:28 +0900, Curt Hibbs <curt@hibbs.com> wrote:
> 
> 
> Brian Schr�der wrote:
> >
> > Hello List,
> >
> > again I ask for your help. I'm going to give a 16 hours course on ruby
> > this week, and I've created some slides to aid me with this.
> > I have to admit that some examples might not be as bright as I wish, and
> > also there are missing some exercises.
> > I created the slides in english, such that they can be used by a bigger
> > part of the community if need should be.
> >
> > The slides will not cover all that I hope to say in the course, when the
> > slides have finished I will start with a free experimentation phase
> > based on my ants sample implementation
> > http://ruby.brian-schroeder.de/ants/
> >
> > It would be great if some of you could look at the slides and correct
> > the language and if somebody comes up with a great example or exercise I
> > would also be glad for comments.
> >
> > The slides are located at
> > http://ruby.brian-schroeder.de/course/
> 
> This is great! Can I add your slides to the WhyRuby? repository
> (http://whyruby.rubyforge.org/wiki/wiki.pl?Ruby_Presentations)?
> 
> Curt
> 
>



0
Reply Becker004 (43) 10/4/2004 5:42:02 PM

James Edward Gray II wrote:
> On Oct 4, 2004, at 12:17 PM, Brian Schr�der wrote:
> 
>> Hello List,
>>
>> again I ask for your help. I'm going to give a 16 hours course on ruby 
>> this week, and I've created some slides to aid me with this.
> 
> 
> The presentation is looking pretty good.  One thing I did notice, on 
> page 19 and 20, the comments do not reflect the code.  You talk about 
> yield, but use a passed block.
> 
> Cover slide looks good!  ;)

Thanks ;) I really liked this. Even though the unetched one had a better 
angle of vision, but the etched ruby is geekier.

Thanks for the comments. In fact there was a problem in my makefiles, I 
had fixed this before but the update was not reflected. Guess I have to 
learn rake.

I want to link to your sides on the slides homepage to give you the 
credits for the image, where should I link to?

regards,

Brian
-- 
Brian Schr�der
http://ruby.brian-schroeder.de/


0
Reply ruby5435 (237) 10/4/2004 8:08:33 PM

On Oct 4, 2004, at 3:08 PM, Brian Schr�der wrote:

> I want to link to your sides on the slides homepage to give you the 
> credits for the image, where should I link to?

If you're worried about it, just include my name.  Hmm, unless you want 
to use it as an excuse to get more people hooked on Ruby Quiz?  
<laughs>  Seriously, the image is free.  You're under no obligation.  
I'm glad it helped.

James Edward Gray II




0
Reply james8284 (4404) 10/4/2004 8:27:25 PM

[Brian Schr�der <ruby@brian-schroeder.de>, 2004-10-04 19.17 CEST]
> It would be great if some of you could look at the slides and correct 
> the language and if somebody comes up with a great example or exercise I 
> would also be glad for comments.

Page 7: Ruby follow the principle of least surprise POTS
	should be "follows" and "POLS"

Page 8: Function -> Functions
	maybe brackets should be omitted on line 7?
	maybe you should mark what you type from the program's output? I
thought "hello world" was an example of function calling without brackets :)

Page 9: (I don't follow "often a variable will become a method" (??))

Page 12: ruby -> ruby's (?)

Page 14: in "First program": you don't follow your own advice from page 11
("-w" switch).

Page 15: "entrys" -> "entries" (?)

Page 18: "skope" -> "scope"

Page 19: see page 20

Page 20: Is it a good idea to use 'f' both as method name and the name of
the method's main variable?

Page 21: see page 22

Page 22: similar as above (parameter name 'call' in example of Proc#call)

Page 23: ... I got tired ;)

Nice course. Good luck.


0
Reply angus608 (244) 10/5/2004 11:45:18 AM

On Tuesday, October 5, 2004, 3:17:47 AM, Brian wrote:

> Hello List,

> again I ask for your help. I'm going to give a 16 hours course on ruby
> this week, and I've created some slides to aid me with this.
> I have to admit that some examples might not be as bright as I wish, and
> also there are missing some exercises.
> I created the slides in english, such that they can be used by a bigger
> part of the community if need should be.

> The slides will not cover all that I hope to say in the course, when the
> slides have finished I will start with a free experimentation phase 
> based on my ants sample implementation
> http://ruby.brian-schroeder.de/ants/

> It would be great if some of you could look at the slides and correct
> the language and if somebody comes up with a great example or exercise I
> would also be glad for comments.

> The slides are located at
> http://ruby.brian-schroeder.de/course/


p4. Output doesn't fit on page (what I'll call "output overflow").

p7. Output overflow, plu inappropriate full justification of code.

BTW: why can I see "this=is=the=result;nil" all over the place?  Yuck.

p8. s/follow/follows/  s/shure/sure/

p10. s/the class/the class./

p12. s/vi/vim/  :)

p13. Prefer a typewriter (monospace) font.  *Much* prefer.  This goes
     for most, if not all, code and output.  But *especially* on this
     page :)

p14. s/into ri/into irb/

I'll just pause to say that this is a very very very good set of
slides, and attractively presented.  Well done.

p16. s/can be used/can be used.../   s/but beware/...but beware/

p19. "map do ... end" reads badly to me, as a matter of style, because
     map is not *doing* anything; it's generating a value.  So I
     prefer to read "map { ... }".  I realise you're probably trying
     to keep it simple.

p20. You've got room; format line 9 onto three lines for clarity.

p21. Oh, I see.  You may not have room.  Consider it anyway.

p22. Boring example.  Think of something that generates an interesting
     result.

p23. s/instanciated/instantiated/  s/n times/n times./
     s/longest_string ,/longest_string,/
     s/shortest_string/shortest_string,/

p24. s/"/""/

p28. Good exercise. With the Fibonacci generator class, give example
     usage and output so students know what they're aiming for.  This
     will require its own slide.

p29. s/A real application/A Real Application/   (suggestion only)

p31. s/gui/GUI/

p32. Lines 2 and 3 have inconsistent punctuation.  Add a period, or
     remove one.

  (Nice example app, by the way.)

p33. Is it possible to show us a "screenshot" of the application
     before launching into improvements?

p34. As per p32.

p36. s/Re raise/Re-raise/

p36. What about plain old "rescue"?  (i.e. what does it rescue by
     default?)

p37. Slight output overflow.   s/running./running/  ?

p38. s/running./running/  ?

p39. Format line 8 on several lines for readability.

p42. s/clients socket/client's socket/
     s/clients-thread/the client's thread/

p43. Title case?

p44. "Accessor functions" repeated.  "Modules" and "Modules
     Exercises": no other outline has this information.

p45. s/propertys/properties/
     The "Calculated Property" and "Shortcut" boxes would look better
     if their positions were reversed.

p47. s/array like/array-like/g
     s/, can be used/ can be used/g
     Slight overflow bottom right.

p48. s/christian/Christian/    (I think; I use "given name" anyway.)
     The fields and descrptions don't match!!
     s/String::split/String#split/

     Perhaps you want Person#name -> Name object, with
       Name#first and Name#last.
     Then Person#age and Person#gender to complete the exercise.

p49. s/no special/not a special/
     s/function,/function/
     This slide is confusing.  You're not demonstrating the ability to
     "change classes, functions, modules at runtime".

p50. 0! == 1

p51. Good exercise.  How about another?

p52. It would be good to teach extending objects, because it's core to
     Ruby, and important when understanding "class methods".  But you
     can emphasise that it's advanced material, so students needn't be
     worried if they don't get it straight away.  (It's not *that*
     hard to accept, anyway... :)

p53. A comment on line 21 would help: "Includes the AntGame namespace
     to this context", or something.

p54. I can't follow this code at a (late night) glance, so I hope
     you're explaining it well in person :)

p55. Missing exercises.

p56. Title case?

p57. Again, second-level headings in the section overview are
     inconsistent with the early style.


So close, but so tired.  I'll review the rest tomorrow.  This is a
*brilliant* learning/teaching resource.  I'm teaching a couple of
friends Ruby at the moment, and I'll be giving this to them for
self-study.

Cheers,
Gavin



0
Reply gsinclair1 (862) 10/5/2004 2:14:32 PM

Thanks a lot for the exhaustive list! I'm sorry that I seem to have put 
up slides where the formating was broken. I'm just uploading the new 
version. (Now including unit testing).

Regards,

Brian


Gavin Sinclair wrote:
> On Tuesday, October 5, 2004, 3:17:47 AM, Brian wrote:
> 
> 
>>Hello List,
> 
> 
>>again I ask for your help. I'm going to give a 16 hours course on ruby
>>this week, and I've created some slides to aid me with this.
>>I have to admit that some examples might not be as bright as I wish, and
>>also there are missing some exercises.
>>I created the slides in english, such that they can be used by a bigger
>>part of the community if need should be.
> 
> 
>>The slides will not cover all that I hope to say in the course, when the
>>slides have finished I will start with a free experimentation phase 
>>based on my ants sample implementation
>>http://ruby.brian-schroeder.de/ants/
> 
> 
>>It would be great if some of you could look at the slides and correct
>>the language and if somebody comes up with a great example or exercise I
>>would also be glad for comments.
> 
> 
>>The slides are located at
>>http://ruby.brian-schroeder.de/course/
> 
> 
> 
> p4. Output doesn't fit on page (what I'll call "output overflow").
> 
> p7. Output overflow, plu inappropriate full justification of code.
> 
> BTW: why can I see "this=is=the=result;nil" all over the place?  Yuck.
> 
> p8. s/follow/follows/  s/shure/sure/
> 
> p10. s/the class/the class./
> 
> p12. s/vi/vim/  :)
> 
> p13. Prefer a typewriter (monospace) font.  *Much* prefer.  This goes
>      for most, if not all, code and output.  But *especially* on this
>      page :)
> 
> p14. s/into ri/into irb/
> 
> I'll just pause to say that this is a very very very good set of
> slides, and attractively presented.  Well done.
> 
> p16. s/can be used/can be used.../   s/but beware/...but beware/
> 
> p19. "map do ... end" reads badly to me, as a matter of style, because
>      map is not *doing* anything; it's generating a value.  So I
>      prefer to read "map { ... }".  I realise you're probably trying
>      to keep it simple.
> 
> p20. You've got room; format line 9 onto three lines for clarity.
> 
> p21. Oh, I see.  You may not have room.  Consider it anyway.
> 
> p22. Boring example.  Think of something that generates an interesting
>      result.
> 
> p23. s/instanciated/instantiated/  s/n times/n times./
>      s/longest_string ,/longest_string,/
>      s/shortest_string/shortest_string,/
> 
> p24. s/"/""/
> 
> p28. Good exercise. With the Fibonacci generator class, give example
>      usage and output so students know what they're aiming for.  This
>      will require its own slide.
> 
> p29. s/A real application/A Real Application/   (suggestion only)
> 
> p31. s/gui/GUI/
> 
> p32. Lines 2 and 3 have inconsistent punctuation.  Add a period, or
>      remove one.
> 
>   (Nice example app, by the way.)
> 
> p33. Is it possible to show us a "screenshot" of the application
>      before launching into improvements?
> 
> p34. As per p32.
> 
> p36. s/Re raise/Re-raise/
> 
> p36. What about plain old "rescue"?  (i.e. what does it rescue by
>      default?)
> 
> p37. Slight output overflow.   s/running./running/  ?
> 
> p38. s/running./running/  ?
> 
> p39. Format line 8 on several lines for readability.
> 
> p42. s/clients socket/client's socket/
>      s/clients-thread/the client's thread/
> 
> p43. Title case?
> 
> p44. "Accessor functions" repeated.  "Modules" and "Modules
>      Exercises": no other outline has this information.
> 
> p45. s/propertys/properties/
>      The "Calculated Property" and "Shortcut" boxes would look better
>      if their positions were reversed.
> 
> p47. s/array like/array-like/g
>      s/, can be used/ can be used/g
>      Slight overflow bottom right.
> 
> p48. s/christian/Christian/    (I think; I use "given name" anyway.)
>      The fields and descrptions don't match!!
>      s/String::split/String#split/
> 
>      Perhaps you want Person#name -> Name object, with
>        Name#first and Name#last.
>      Then Person#age and Person#gender to complete the exercise.
> 
> p49. s/no special/not a special/
>      s/function,/function/
>      This slide is confusing.  You're not demonstrating the ability to
>      "change classes, functions, modules at runtime".
> 
> p50. 0! == 1
> 
> p51. Good exercise.  How about another?
> 
> p52. It would be good to teach extending objects, because it's core to
>      Ruby, and important when understanding "class methods".  But you
>      can emphasise that it's advanced material, so students needn't be
>      worried if they don't get it straight away.  (It's not *that*
>      hard to accept, anyway... :)
> 
> p53. A comment on line 21 would help: "Includes the AntGame namespace
>      to this context", or something.
> 
> p54. I can't follow this code at a (late night) glance, so I hope
>      you're explaining it well in person :)
> 
> p55. Missing exercises.
> 
> p56. Title case?
> 
> p57. Again, second-level headings in the section overview are
>      inconsistent with the early style.
> 
> 
> So close, but so tired.  I'll review the rest tomorrow.  This is a
> *brilliant* learning/teaching resource.  I'm teaching a couple of
> friends Ruby at the moment, and I'll be giving this to them for
> self-study.
> 
> Cheers,
> Gavin
> 
> 

-- 
Brian Schr�der
http://ruby.brian-schroeder.de/


0
Reply ruby5435 (237) 10/5/2004 2:55:34 PM

Hello Group,

I need more help.

Gavin Sinclair wrote:
> 
> p51. Good exercise.  How about another?
> 

Anybody has an idea for an exercise on extending existing classes. So 
far the only thing I have come up with is:

\exercise{Fibonacci II}{
   Extend \codetype{Integer} with a function fib that calculates the
   corresponding fibonacci number.}

And my creativity is at an all time low.

> p52. It would be good to teach extending objects, because it's core to
>      Ruby, and important when understanding "class methods".  But you
>      can emphasise that it's advanced material, so students needn't be
>      worried if they don't get it straight away.  (It's not *that*
>      hard to accept, anyway... :)
> 

Anybody nows of a good example where it is neccessary to extend an 
existing object?
I have never used this feature and I don't know when to use it in a 
sensible way.

> p55. Missing exercises.

Somebody has an idea for an exercise on using modules (as namespace and 
mixin?)

A big thanks so far to all the people who have reviewed the slides!

regards,

Brian
-- 
Brian Schr�der
http://ruby.brian-schroeder.de/


0
Reply ruby5435 (237) 10/5/2004 5:24:12 PM

Brian Schr�der wrote:

> Hello Group,
> 
> I need more help.
> 
> Gavin Sinclair wrote:
> 
>>
>> p51. Good exercise.  How about another?
>>
> 
> Anybody has an idea for an exercise on extending existing classes. So 
> far the only thing I have come up with is:
> 
> \exercise{Fibonacci II}{
>   Extend \codetype{Integer} with a function fib that calculates the
>   corresponding fibonacci number.}
> 
> And my creativity is at an all time low.
> 

Hi!

what about
- extending REXML::Element with a method that strips all unnecessary 
whitespaces and all children
- extending String so you can tell it to remove cpp comments /* remove me */

Of course both tasks could be accomplished without extending those 
classes. I have no idea in which cases you should write helper methods 
and when you should extend existing classes... does anybody have some 
'heuristics' or best practices?

regards,
Henrik


0
Reply ryco (76) 10/5/2004 5:43:11 PM

Henrik Horneber wrote:
> - extending REXML::Element with a method that strips all unnecessary 
> whitespaces and all children


make that 'and does that to all children'

sorry :)


0
Reply ryco (76) 10/5/2004 5:45:05 PM

Henrik Horneber wrote:
> Brian Schr�der wrote:
> 
>> Hello Group,
>>
>> I need more help.
>>
>> Gavin Sinclair wrote:
>>
>>>
>>> p51. Good exercise.  How about another?
>>>
>>
>> Anybody has an idea for an exercise on extending existing classes. So 
>> far the only thing I have come up with is:
>>
>> \exercise{Fibonacci II}{
>>   Extend \codetype{Integer} with a function fib that calculates the
>>   corresponding fibonacci number.}
>>
>> And my creativity is at an all time low.
>>
> 
> Hi!
> 
> what about
> - extending REXML::Element with a method that strips all unnecessary 
> whitespaces and all children
> - extending String so you can tell it to remove cpp comments /* remove 
> me */
> 
> Of course both tasks could be accomplished without extending those 
> classes. I have no idea in which cases you should write helper methods 
> and when you should extend existing classes... does anybody have some 
> 'heuristics' or best practices?
> 
> regards,
> Henrik
> 

Hello Henrik,

Sadly I don't want to introduce REXML (even though its a great library). 
But this would cost me too much time.

Extending string with something like remove_cpp_comments seems awkward 
to me. In any usecase for this I'd rather have a class CppCode that I 
can ask to remove_comments. (Or even better, to give me the source 
without comments.)

So my personal heuristic tells me not to extend in this case.

thanks for your comment,

Brian
-- 
Brian Schr�der
http://ruby.brian-schroeder.de/


0
Reply ruby5435 (237) 10/5/2004 5:58:50 PM

On Tue, 2004-10-05 at 10:24, Brian Schröder wrote:
> Hello Group,
> 
> I need more help.
> 
> Anybody has an idea for an exercise on extending existing classes. So 
> far the only thing I have come up with is:
> 
> \exercise{Fibonacci II}{
>    Extend \codetype{Integer} with a function fib that calculates the
>    corresponding fibonacci number.}
> 
> And my creativity is at an all time low.

      * Sub class (or extend) array to support "card deck" semantics,
        e.g. cut, shuffle, deal, and (*smile*) maybe even stack?

      * Add set-like operations to hash (e.g. &&, ||)

      * Here's one I find this very useful: add aggregate behaviour to
        hashes.  For example have { :a=>3, :b=>[0,5,2], :c=>8 } +
        {:b=>[7], :c=>4} return { :a=>3, :b=>[0,5,2,7], :c=>12 }

      * Add some sort of simple substitution cypher to String


> > p52. It would be good to teach extending objects, because it's core to
> >      Ruby, and important when understanding "class methods".  But you
> >      can emphasise that it's advanced material, so students needn't be
> >      worried if they don't get it straight away.  (It's not *that*
> >      hard to accept, anyway... :)
> > 
> 
> Anybody nows of a good example where it is neccessary to extend an 
> existing object?

As far as I'm concerned, things like:

def Symbol.intern
     self
     end

but I don't think that's quite what your asking.

> I have never used this feature and I don't know when to use it in a 
> sensible way.

     If you're talking about extending individual objects, the only time
I can recall using it extensively was in a little text based adventure
game.  It's kind of odd now that I think about it: I love the ability
but I use it very sparingly. 

> > p55. Missing exercises.
> 
> Somebody has an idea for an exercise on using modules (as namespace and 
> mixin?)

     A linked list or tree package is the semi-standard answer.  You can
add it to any class & do "classical" lists & trees.  You may want to
note that this isn't very rubyesque thought.
     Maybe a simple version history "memento" setup?  Or taint tagging
with more history/details than tainted or not?  Or some sort of math
package (& use this to introduce Math)?


     -- Markus




0
Reply markus623 (304) 10/5/2004 6:12:35 PM

On Wed, 6 Oct 2004 02:24:12 +0900, Brian Schr�der
<ruby@brian-schroeder.de> wrote:
> 
> Anybody has an idea for an exercise on extending existing classes. So
> far the only thing I have come up with is:
> 

Taken from the Design Patterns book, Decorator pattern:

"Attach additional responsibilities to an object dynamically.
Decorators provide a flexible alternative to subclassing for extending
functionality."

You could extend Integer with a fibonacci method, so that you can
write something like:

puts 0.fibonacci       > 0
puts 1.fibonacci       > 1
puts 5.fibonacci       > 5

My 2 cents.
Ed

-- 
" Don't relax!  It's only your tension that's holding you together."



0
Reply ehames (113) 10/5/2004 6:20:12 PM

Hi!

Taking over from Brian (sorry :) ) I need to ask a question of my own.


Brian Schr�der wrote:

> Henrik Horneber wrote:
....
>> - extending String so you can tell it to remove cpp comments /* remove 
>> me */
>>
>> Of course both tasks could be accomplished without extending those 
>> classes. I have no idea in which cases you should write helper methods 
>> and when you should extend existing classes... does anybody have some 
>> 'heuristics' or best practices?
>>
>> regards,
>> Henrik
>>
> 
> Hello Henrik,
> 
....
> 
> Extending string with something like remove_cpp_comments seems awkward 
> to me. In any usecase for this I'd rather have a class CppCode that I 
> can ask to remove_comments. (Or even better, to give me the source 
> without comments.)
> 
> So my personal heuristic tells me not to extend in this case.

Now, the reason I was immediatly reminded of that remove_cpp_comments 
example is, that I wrote a small script some time ago, which used 
exactly this case. First, I implemented remove_cpp_comments in its own 
class (which was not called CppCode, but had the same intend), but out 
of curiosity (and because in ruby I can, dang it! :) ) I moved the 
remove_cpp_comments method to String. Turns out, the method got shorter 
  and somewhat clearer, at least to me. And I could write something like

source_code = IO.readlines(file).join("\n")        	
source_code.strip_comments!
# instead of source_code = CppCode.strip_comments( source_code)	


.... you get the idea.

Even though the code became clearer on that level, I still have to agree 
with Brian that it is somehow dirty/awkward on a different level to 
extend String with such a method.

This, formerly extremly happy, Ruby user is confused.

What are your experiences?

regards,

Henrik







0
Reply ryco (76) 10/5/2004 6:29:35 PM

On Wed, 6 Oct 2004 03:29:35 +0900, Henrik Horneber <ryco@gmx.net> wrote:
> >> - extending String so you can tell it to remove cpp comments /* remove
> >> me */
> >
> > Extending string with something like remove_cpp_comments seems awkward
> > to me. In any usecase for this I'd rather have a class CppCode that I
> > can ask to remove_comments. (Or even better, to give me the source
> > without comments.)
> >
> > So my personal heuristic tells me not to extend in this case.
> 
> Now, the reason I was immediatly reminded of that remove_cpp_comments
> example is, that I wrote a small script some time ago, which used
> exactly this case. First, I implemented remove_cpp_comments in its own
> class (which was not called CppCode, but had the same intend), but out
> of curiosity (and because in ruby I can, dang it! :) ) I moved the
> remove_cpp_comments method to String. Turns out, the method got shorter
>  and somewhat clearer, at least to me. And I could write something like
> 
> source_code = IO.readlines(file).join("\n")
> source_code.strip_comments!
> # instead of source_code = CppCode.strip_comments( source_code)
> 
> .... you get the idea.
> 
> Even though the code became clearer on that level, I still have to agree
> with Brian that it is somehow dirty/awkward on a different level to
> extend String with such a method.
> 

I usually try not to do that kind of things. Then, for each new
lanaguage you are going to support, you should now add a
remove_#{lang}_comments to String. But then, when reading a given
source file you could remove comments that are not so in that
language.

Regards,
Ed
-- 
" Don't relax!  It's only your tension that's holding you together."


0
Reply ehames (113) 10/5/2004 6:38:04 PM

On Oct 5, 2004, at 1:20 PM, Edgardo Hames wrote:

> You could extend Integer with a fibonacci method, so that you can
> write something like:
>
> puts 0.fibonacci       > 0
> puts 1.fibonacci       > 1
> puts 5.fibonacci       > 5

There was an excellent example along these lines in the RubyConf '04 
blogs.  According to Francis Hwang's blog:

"Also, Rich [Kilmer] described a cool little hack: Adding time-unit 
methods to Fixnum so you can write code like time_to_restart = 5.hours 
+ 15.minutes. Dude, I'm totally stealing that."

I have to agree with the entry, it's a killer trick.

James Edward Gray II



0
Reply james8284 (4404) 10/5/2004 6:40:03 PM

On Wed, 6 Oct 2004 03:40:03 +0900, James Edward Gray II
<james@grayproductions.net> wrote:
> On Oct 5, 2004, at 1:20 PM, Edgardo Hames wrote:
> 
> > You could extend Integer with a fibonacci method, so that you can
> > write something like:
> 
> "Also, Rich [Kilmer] described a cool little hack: Adding time-unit
> methods to Fixnum so you can write code like time_to_restart = 5.hours
> + 15.minutes. Dude, I'm totally stealing that."

That's right, I meant adding the #fibonacci method to Fixnum.

Ed
-- 
" Don't relax!  It's only your tension that's holding you together."


0
Reply ehames (113) 10/5/2004 6:43:31 PM

Edgardo Hames wrote:

> On Wed, 6 Oct 2004 03:29:35 +0900, Henrik Horneber <ryco@gmx.net> wrote:
> 
>>>>- extending String so you can tell it to remove cpp comments /* remove
>>>>me */
>>>
>>>Extending string with something like remove_cpp_comments seems awkward
>>>to me. In any usecase for this I'd rather have a class CppCode that I
>>>can ask to remove_comments. (Or even better, to give me the source
>>>without comments.)
>>>
>>>So my personal heuristic tells me not to extend in this case.
>>
>>Now, the reason I was immediatly reminded of that remove_cpp_comments
>>example is, that I wrote a small script some time ago, which used
>>exactly this case. First, I implemented remove_cpp_comments in its own
>>class (which was not called CppCode, but had the same intend), but out
>>of curiosity (and because in ruby I can, dang it! :) ) I moved the
>>remove_cpp_comments method to String. Turns out, the method got shorter
>> and somewhat clearer, at least to me. And I could write something like
>>
>>source_code = IO.readlines(file).join("\n")
>>source_code.strip_comments!
>># instead of source_code = CppCode.strip_comments( source_code)
>>
>>.... you get the idea.
>>
>>Even though the code became clearer on that level, I still have to agree
>>with Brian that it is somehow dirty/awkward on a different level to
>>extend String with such a method.
>>
> 
> 
> I usually try not to do that kind of things. Then, for each new
> lanaguage you are going to support, you should now add a
> remove_#{lang}_comments to String. But then, when reading a given
> source file you could remove comments that are not so in that
> language.
> 
> Regards,
> Ed

In my case there is never going to be a different language to support, 
but in general, that is a good reason not to do it. I'd like to get away 
from my example and to a little wider discussion of when to extend 
existing classes. I could have written my own subclass of String called 
CppSource, so I could have written

source_code = CppSource.new( IO.readlines(file).join("\n") )
source_code.strip_comments!

which might actually be a better solution than to put strip_comments! 
into String. On the other hand (again stealing from the other thread), 
writing

time_to_restart = TimeNumeric.new(5).hours + TimeNumeric.new(15).minutes

is just what we would like to avoid. So, as a guideline, should you only 
extend an existing class when you use lots of literals in your code?

regards,

Henrik


0
Reply ryco (76) 10/5/2004 6:55:12 PM

Edgardo Hames wrote:
> On Wed, 6 Oct 2004 02:24:12 +0900, Brian Schr�der
> <ruby@brian-schroeder.de> wrote:
> 
>>Anybody has an idea for an exercise on extending existing classes. So
>>far the only thing I have come up with is:
>>
> 
> 
> Taken from the Design Patterns book, Decorator pattern:
> 
> "Attach additional responsibilities to an object dynamically.
> Decorators provide a flexible alternative to subclassing for extending
> functionality."
> 
> You could extend Integer with a fibonacci method, so that you can
> write something like:
> 
> puts 0.fibonacci       > 0
> puts 1.fibonacci       > 1
> puts 5.fibonacci       > 5
Should be 12, shouldn't it?
> 
> My 2 cents.
> Ed
> 

I'm sorry, but this was exactly the example I gave. It seems we have a 
similar mindset ;)

Regards,

Brian

-- 
Brian Schr�der
http://ruby.brian-schroeder.de/


0
Reply ruby5435 (237) 10/5/2004 7:18:17 PM

On Tue, 2004-10-05 at 11:40, James Edward Gray II wrote:
> On Oct 5, 2004, at 1:20 PM, Edgardo Hames wrote:
> 

> There was an excellent example along these lines in the RubyConf '04 
> blogs.  According to Francis Hwang's blog:
> 
> "Also, Rich [Kilmer] described a cool little hack: Adding time-unit 
> methods to Fixnum so you can write code like time_to_restart = 5.hours 
> + 15.minutes. Dude, I'm totally stealing that."
> 
> I have to agree with the entry, it's a killer trick.
> 

    Here's something I've used from time to time (not completely fleshed
out, since I've just been implementing what I need each time I use it). 
It lets you write things like:

1.0[kilometers]

1.0[kilometers][miles]

1.0[seconds][hours]

1.0[miles/hours]

1.0[kilometers/second][miles/hour]

1.0[kilometers] + 1.0[miles]
 
...and does all the right stuff for you.  The n[kilometers][miles] form,
for example, gives you the distance in miles equal to n kilometers.

-- Markus

P.S. RubyLicence, GPL, your choice, yada yada


require '/usr/local/ruby/1.8/extensions.rb'
#
#  By Markus (MQR) Roberts, 2003+/-1
#
class A_component_vector < Hash
    #
    # Because the keys are dimensions that themselves contain component
    #     vectors, we don't want to deep copy past here.
    #
    def deep_copy
        clone
        end
    end

$known_dimensions = {}
class A_dimension
    attr_accessor :name
    def initialize(name)
        @name = name
        end
    def components
        A_component_vector.new(self=>1.0)
        end
    def *(other)
       
A_derived_dimension.new("#{self.name}*#{other.name}",self.components+other.components)
        end
    def /(other)
       
A_derived_dimension.new("#{self.name}/#{other.name}",self.components-other.components)
        end
    def to_str
        @name
        end
    end

class A_derived_dimension < A_dimension
   attr_reader :components,:hash
   def initialize(name,components)
       super(name)
       @components = components
       #@hash = 0
       #@components.each_pair { |k,v| @hash += v*k.hash }
       @hash = @components.inject(0) { |x,p| x+p[1]*p[0].hash }
       end
   def ==(other)
       self.class == other.class and
         @hash == other.hash and
         @components.length == other.components.length and
         @components.all? { |k,v|
             v == other.components[k]
             }
       end
   end

def define_dimension(name,components=nil)
    name = name.to_s.intern
    $known_dimensions[name] = components ?
A_derived_dimension.new(name,components.components) :
A_dimension.new(name)
    #eval "#{name.to_s.capitalize} = $known_dimensions[#{name.inspect}]"
    eval %Q{
        def #{name}
            $known_dimensions[#{name.inspect}]
            end
        }
    end

define_dimension :duration
define_dimension :distance
define_dimension :area,     distance*distance
define_dimension :speed,    distance/duration
#define_dimension :velocity, displacement/duration

$known_units = {}
class A_unit
   attr_accessor :what,:how_much,:name
   def initialize
       end
   def A_unit.to_measure(what,name,conversion=nil)
       result = A_unit.new
       result.name = name
       conversion = 1.0 unless conversion
       conversion = conversion.value*conversion.units.how_much if
conversion.is? A_measure
       $known_units[what] ||= {}
       $known_units[what][result] = conversion
       result.what     = what
       result.how_much = conversion
       result
       end
   def *(other)
      
A_unit.to_measure(self.what*other.what,"(#{self.name})*(#{other.name})",self.how_much*other.how_much)
       end
   def /(other)
      
A_unit.to_measure(self.what/other.what,"(#{self.name})/(#{other.name})",self.how_much/other.how_much)
       end
   def to(units)
       return 1.0 if units == self
       fail "Can't coerce #{self.what.name} to #{units.what.name}" if
self.what != units.what
       fail "Can't coerce #{self} to #{units}" if self.what !=
units.what
       return self.how_much/units.how_much
       end
   def to_s
       @name #$known_units[@what]
       end
   def to_str
       @name #$known_units[@what]
       end
   end

class A_measure
    attr_reader :value,:units
    def initialize(value,units)
        @value = value
        @units = units
        end
    def [](units)
        p "Trying to convert #{self} to #{units}\n"
        A_measure.new(@units.to(units)*@value,units)
        #@units.to(units)*@value
        end
    def *(other)
        case other
          when A_measure then
A_measure.new(@value*other.value,@units*other.units)
          else                A_measure.new(@value*other,     
@units            )
          end
        end
    def /(other)
        case other
          when A_measure then
A_measure.new(@value/other.value,@units/other.units)
          else                A_measure.new(@value/other,     
@units            )
          end
        end
    def +(other)
        A_measure.new(@value+other[@units].value,@units)
        end
    def -(other)
        A_measure.new(@value-other[@units].value,@units)
        end
    def to_s
        "#{value}[#{units}]"
        end
    def to_str
        "#{value}[#{units}]"
        end
    end
    
class Numeric
    def [](units)
        A_measure.new(self,units)
        end
    end

def define_unit_of(what,names,comparison=nil)
    names = [names,names.to_s+'s'] unless names.is_a? Array
    names.each { |name|
        eval %Q{
            def #{name}(quantity=nil)
                if quantity
                    A_measure.new(quantity,#{name})
                  else
                   
A_unit.to_measure(#{what.name},"#{name}",#{comparison ? comparison :
'nil'})
                  end
                end
            }
        }
    end
    
def define_metric_unit_of(what,name,comparison=nil)
    define_unit_of what,name,comparison
    define_unit_of what,'nano' +name.to_s,1e-9[name]
    define_unit_of what,'micro'+name.to_s,1e-6[name]
    define_unit_of what,'milli'+name.to_s,1e-3[name]
    define_unit_of what,'centi'+name.to_s,1e-2[name]
    define_unit_of what,'deci' +name.to_s,1e-1[name]
    define_unit_of what,'deka' +name.to_s,1e+1[name]
    define_unit_of what,'kilo' +name.to_s,1e+3[name]
    define_unit_of what,'mega' +name.to_s,1e+6[name]
    define_unit_of what,'giga' +name.to_s,1e+9[name]
    end

define_metric_unit_of distance,  :meter
define_unit_of        distance,  [:foot,:feet],   0.3048[meters]
define_unit_of        distance,  :mile,        1609.344[meters]
define_metric_unit_of duration,  :second
define_unit_of        duration,  :minute,        60.0[seconds]
define_unit_of        duration,  :hour,          60.0[minutes]

fail "Type checking doesn't work!" unless begin
    print "#{1.0[kilometers] + 1.0[seconds]}\n"
    false
  rescue
    true
  end

print "#{1.0[kilometers]}\n"
print "#{1.0[kilometers][miles]}\n"
print "#{1.0[seconds][hours]}\n"
print "#{1.0[miles/hours]}\n"
print "#{1.0[kilometers/second][miles/hour]}\n"
print "#{1.0[kilometers] + 1.0[miles]}\n"
  





0
Reply markus623 (304) 10/5/2004 7:19:34 PM

On Wed, 6 Oct 2004 04:18:17 +0900, Brian Schr�der
<ruby@brian-schroeder.de> wrote:
> Edgardo Hames wrote:
> > On Wed, 6 Oct 2004 02:24:12 +0900, Brian Schr�der
> > <ruby@brian-schroeder.de> wrote:
> >
> >>Anybody has an idea for an exercise on extending existing classes. So
> >>far the only thing I have come up with is:
> >>
> >
> >
> > Taken from the Design Patterns book, Decorator pattern:
> >
> > "Attach additional responsibilities to an object dynamically.
> > Decorators provide a flexible alternative to subclassing for extending
> > functionality."
> >
> > You could extend Integer with a fibonacci method, so that you can
> > write something like:
> >
> > puts 0.fibonacci       > 0
> > puts 1.fibonacci       > 1
> > puts 5.fibonacci       > 5
>
> Should be 12, shouldn't it?

0.fib  > 0
1.fib  > 1
2.fib  > 1
3.fib  > 2
4.fib  > 3
5.fib  > 5

> I'm sorry, but this was exactly the example I gave. It seems we have a
> similar mindset ;)

I'm really sorry, I must admit I didn't really paid much attention to
the example. I'm replying messages while in a training session... :(

But anyway, you can think of the Visitor or Decorator pattern, for
extending classes. Did I mention adding a fib method to Fixnum? ;)

Regards,
Ed

-- 
" Don't relax!  It's only your tension that's holding you together."



0
Reply ehames (113) 10/5/2004 7:25:25 PM

Edgardo Hames wrote:
>>>
>>>You could extend Integer with a fibonacci method, so that you can
>>>write something like:
>>>
>>>puts 0.fibonacci       > 0
>>>puts 1.fibonacci       > 1
>>>puts 5.fibonacci       > 5
>>
>>Should be 12, shouldn't it?
> 
> 
> 0.fib  > 0
> 1.fib  > 1
> 2.fib  > 1
> 3.fib  > 2
> 4.fib  > 3
> 5.fib  > 5
> 

Oh, 12 was the sum of the fibonaccy numbers up to 5. Too much thinking 
is bad for your brain.

-- 
Brian Schr�der
http://ruby.brian-schroeder.de/


0
Reply ruby5435 (237) 10/5/2004 7:36:23 PM

Brian Schr�der wrote:

> Hello Group,
> 
> I need more help.
> 
> Anybody has an idea for an exercise on extending existing classes.

The code below introduce a new string concatenation operator '/' which 
concatenates two strings placing '/' beween them. This is useful
when forming path from directory and filename components.

class String
  def /(rhs)
    self.sub(%r{/+$}, '') + '/' + rhs.sub(%r{^/+}, '')
  end 
end if 

Now you can write the following code:

$dir='/usr/local/bin'
$name='ruby'
$full_path= $dir/$name

Also the '/' operator will make sure that the strings are joined by one and
only one slash. Example:
$dir='/badby/formed/dir///'

$name='///foo'

$dir/$name  => '/badby/formed/dir/foo'

Note, that poatterns like '///' were removed.

Hope it helps,
Leo

-- 
[ LEOR _at_ WINLAB _dot_ RUTGERS _dot_ EDU ]
0
Reply see_signature9677 (2) 10/5/2004 7:37:04 PM

Leo wrote:
> Brian Schr�der wrote:
> 
> 
>>Hello Group,
>>
>>I need more help.
>>
>>Anybody has an idea for an exercise on extending existing classes.
> 
> 
> The code below introduce a new string concatenation operator '/' which 
> concatenates two strings placing '/' beween them. This is useful
> when forming path from directory and filename components.
> 
> class String
>   def /(rhs)
>     self.sub(%r{/+$}, '') + '/' + rhs.sub(%r{^/+}, '')
>   end 
> end if 
> 
> Now you can write the following code:
> 
> $dir='/usr/local/bin'
> $name='ruby'
> $full_path= $dir/$name
> 
> Also the '/' operator will make sure that the strings are joined by one and
> only one slash. Example:
> $dir='/badby/formed/dir///'
> 
> $name='///foo'
> 
> $dir/$name  => '/badby/formed/dir/foo'
> 
> Note, that poatterns like '///' were removed.
> 
> Hope it helps,
> Leo
> 

That is short and cool. I think this could be an example for me!

Thanks,

Brian

-- 
Brian Schr�der
http://ruby.brian-schroeder.de/


0
Reply ruby5435 (237) 10/5/2004 7:48:00 PM

On Wed, 6 Oct 2004 04:36:23 +0900, Brian Schr�der
<ruby@brian-schroeder.de> wrote:
> Edgardo Hames wrote:
> >>>
> >>>You could extend Integer with a fibonacci method, so that you can
> >>>write something like:
> >>>
> >>>puts 0.fibonacci       > 0
> >>>puts 1.fibonacci       > 1
> >>>puts 5.fibonacci       > 5
> >>
> >>Should be 12, shouldn't it?
> >
> >
> > 0.fib  > 0
> > 1.fib  > 1
> > 2.fib  > 1
> > 3.fib  > 2
> > 4.fib  > 3
> > 5.fib  > 5
> >
> 
> Oh, 12 was the sum of the fibonaccy numbers up to 5. Too much thinking
> is bad for your brain.
> 

What are you talking about? As far as I know the fibonacci series is defined as

fib n = fib (n-1) + fib (n-2)

Then,
fib 5 = 
= fib 4 + fib 3
= (fib 3 + fib 2) + (fib 2  + fib 1)
= ((fib 2 + fib 1) + (fib 1 + fib 0)) + (fib 1 + fib 0) + (1+0)
= ((fib 1 + fib 0) + (1+ 0))+ (1+0) + (1+0) + (1+ 0)
= 1+1+1+1+1
= 5

You might cosider taking a look at 
http://mathworld.wolfram.com/FibonacciNumber.html
It defines fib 0 = 0,  but either way, 12 doesn't belong to the series.

Regards,
Ed

-- 
" Don't relax!  It's only your tension that's holding you together."



0
Reply ehames (113) 10/5/2004 7:58:20 PM

Edgardo Hames wrote:
> On Wed, 6 Oct 2004 04:36:23 +0900, Brian Schr�der
> <ruby@brian-schroeder.de> wrote:
> 
>>Edgardo Hames wrote:
>>
>>>>>You could extend Integer with a fibonacci method, so that you can
>>>>>write something like:
>>>>>
>>>>>puts 0.fibonacci       > 0
>>>>>puts 1.fibonacci       > 1
>>>>>puts 5.fibonacci       > 5
>>>>
>>>>Should be 12, shouldn't it?
>>>
>>>
>>>0.fib  > 0
>>>1.fib  > 1
>>>2.fib  > 1
>>>3.fib  > 2
>>>4.fib  > 3
>>>5.fib  > 5
>>>
>>
>>Oh, 12 was the sum of the fibonaccy numbers up to 5. Too much thinking
>>is bad for your brain.
>>
> 
> 
> What are you talking about? As far as I know the fibonacci series is defined as
> 
> fib n = fib (n-1) + fib (n-2)
> 
> Then,
> fib 5 = 
> = fib 4 + fib 3
> = (fib 3 + fib 2) + (fib 2  + fib 1)
> = ((fib 2 + fib 1) + (fib 1 + fib 0)) + (fib 1 + fib 0) + (1+0)
> = ((fib 1 + fib 0) + (1+ 0))+ (1+0) + (1+0) + (1+ 0)
> = 1+1+1+1+1
> = 5
> 
> You might cosider taking a look at 
> http://mathworld.wolfram.com/FibonacciNumber.html
> It defines fib 0 = 0,  but either way, 12 doesn't belong to the series.
> 
> Regards,
> Ed
> 
I meant "bad for _my_ brain". Sorry if I have confused you. You were 
absolutely right, and I calculated the wrong thing.

Regards,

Brian

-- 
Brian Schr�der
http://ruby.brian-schroeder.de/


0
Reply ruby5435 (237) 10/5/2004 8:19:00 PM

On Wed, 6 Oct 2004 03:55:12 +0900, Henrik Horneber <ryco@gmx.net> wrote:
> Edgardo Hames wrote:
> 
> > On Wed, 6 Oct 2004 03:29:35 +0900, Henrik Horneber <ryco@gmx.net> wrote:
> >
> >>>>- extending String so you can tell it to remove cpp comments /* remove
> >>>>me */
> >>>
> >>>Extending string with something like remove_cpp_comments seems awkward
> >>>to me. In any usecase for this I'd rather have a class CppCode that I
> >>>can ask to remove_comments. (Or even better, to give me the source
> >>>without comments.)
> >>>
> >>>So my personal heuristic tells me not to extend in this case.
> >>
> >>Now, the reason I was immediatly reminded of that remove_cpp_comments
> >>example is, that I wrote a small script some time ago, which used
> >>exactly this case. First, I implemented remove_cpp_comments in its own
> >>class (which was not called CppCode, but had the same intend), but out
> >>of curiosity (and because in ruby I can, dang it! :) ) I moved the
> >>remove_cpp_comments method to String. Turns out, the method got shorter
> >> and somewhat clearer, at least to me. And I could write something like
> >>
> >>source_code = IO.readlines(file).join("\n")
> >>source_code.strip_comments!
> >># instead of source_code = CppCode.strip_comments( source_code)
> >>
> >>.... you get the idea.
> >>
> >>Even though the code became clearer on that level, I still have to agree
> >>with Brian that it is somehow dirty/awkward on a different level to
> >>extend String with such a method.
> >>
> >
> >
> > I usually try not to do that kind of things. Then, for each new
> > lanaguage you are going to support, you should now add a
> > remove_#{lang}_comments to String. But then, when reading a given
> > source file you could remove comments that are not so in that
> > language.
> >
> > Regards,
> > Ed
> 
> In my case there is never going to be a different language to support,
> but in general, that is a good reason not to do it. I'd like to get away
> from my example and to a little wider discussion of when to extend
> existing classes. I could have written my own subclass of String called
> CppSource, so I could have written
> 
> source_code = CppSource.new( IO.readlines(file).join("\n") )
> source_code.strip_comments!
> 
> which might actually be a better solution than to put strip_comments!
> into String. On the other hand (again stealing from the other thread),
> writing
> 
> time_to_restart = TimeNumeric.new(5).hours + TimeNumeric.new(15).minutes
> 
> is just what we would like to avoid. So, as a guideline, should you only
> extend an existing class when you use lots of literals in your code?

imho, there are two occasions for extending a class:
1. When the added methods are useful for that class in general (ie,
String#rot13, Integer#factors)
2. When you're just hacking :)

If the data that you are working with is sort of an extended version
of the class, that's when I would subclass. I think the common text
markup modules are excellent examples of this; redcloth and bluecloth
both act just like strings, but the have a few important methods that
treat them as specific data types.

In this vein, TimeNumeric might be subclassed to use like this:
# TimeNumeric < Float
... where the float value is the number of seconds.

time_to_shutdown = TimeNumeric.new(5*60*60 + 15*60)
or better yet:
time_to_shutdown = TimeNumeric.hours(5.25)
or even:
time_to_shutdown = TimeNumeric["5:15:00"] # calls "#to_time_numeric"
on the string

cheers,
Mark


0
Reply discordantus (236) 10/5/2004 9:22:46 PM

On Oct 5, 2004, at 5:22 PM, Mark Hubbart wrote:
> imho, there are two occasions for extending a class:
> 1. When the added methods are useful for that class in general (ie,
> String#rot13, Integer#factors)
> 2. When you're just hacking :)

But this is all fairly subjective, isn't it? Among some programmers, 
String#rot13 might be a really sensible thing to add, but to others 
maybe it might seem like cruft. One interesting example from RubyConf 
was Rich Kilmer saying that he added methods like #minutes and #days to 
Fixnum, so he could say things like

15.minutes + 2.hours

It's also very easy to imagine using this for, say, feet and inches:

1.miles + 6.feet + 6.inches

... which is culturally specific, isn't it? I mean, you're not going to 
use that if you use the metric system like a civilized people.

There are two competing philosophies in OO theory. On one hand, you 
have the Platonists who believe that types are eternal forms that can 
be found in nature, so if you did your analysis right you'd find those 
forms and be able to codify them in your class definitions. On the 
other hand, you have the Pragmatists who believe that types are just 
shorthand, to be defined and discarded as the situation allows.

Ruby is more of a Pragmatist language, which personally I like 'cause 
on some deep level it jibes with my own belief in the subjectivity of 
experience. So, you know, if you want to extend a class, do it if it 
makes your life easier. If it doesn't, then don't do it.

Francis Hwang
http://fhwang.net/
AIM: francisrhizome



0
Reply sera (331) 10/5/2004 11:52:27 PM

On Wednesday, October 6, 2004, 3:24:12 AM, Brian wrote:

> Hello Group,

> I need more help.

> Gavin Sinclair wrote:
>> 
>> p51. Good exercise.  How about another?
>> 

> Anybody has an idea for an exercise on extending existing classes. So
> far the only thing I have come up with is:

> \exercise{Fibonacci II}{
>    Extend \codetype{Integer} with a function fib that calculates the
>    corresponding fibonacci number.}

> And my creativity is at an all time low.

There are plenty of examples at http://extensions.rubyforge.org.  I
was thinking of something like String#indent as an exercise, but you
haven't taught regexen at this point, so that's out.  But something
else might do.

>> p52. It would be good to teach extending objects, because it's core to
>>      Ruby, and important when understanding "class methods".  But you
>>      can emphasise that it's advanced material, so students needn't be
>>      worried if they don't get it straight away.  (It's not *that*
>>      hard to accept, anyway... :)
>> 

> Anybody nows of a good example where it is neccessary to extend an 
> existing object?

> I have never used this feature and I don't know when to use it in a 
> sensible way.

It could be something academic like changing the to_s output for a
particular array/string.  But really, the main point of this feature
(adding methods to objects) is to add methods to classes (which are
objects).  So perhaps use that as an example.

>> p55. Missing exercises.

> Somebody has an idea for an exercise on using modules (as namespace and
> mixin?)

A favourite of mine is building a new class, then mixing in Enumerable
and Comparable.  So you're not building a new module, but reusing two
existing ones.

Gavin





0
Reply gsinclair1 (862) 10/6/2004 1:36:43 AM

On Wednesday, October 6, 2004, 5:18:17 AM, Brian wrote:

> Edgardo Hames wrote:
>> On Wed, 6 Oct 2004 02:24:12 +0900, Brian Schr�der
>> <ruby@brian-schroeder.de> wrote:
>> 
>>>Anybody has an idea for an exercise on extending existing classes. So
>>>far the only thing I have come up with is:
>>>
>> 
>> 
>> Taken from the Design Patterns book, Decorator pattern:
>> 
>> "Attach additional responsibilities to an object dynamically.
>> Decorators provide a flexible alternative to subclassing for extending
>> functionality."
>> 
>> You could extend Integer with a fibonacci method, so that you can
>> write something like:
>> 
>> puts 0.fibonacci       > 0
>> puts 1.fibonacci       > 1
>> puts 5.fibonacci       > 5
> Should be 12, shouldn't it?
>> 
>> My 2 cents.
>> Ed
>> 

> I'm sorry, but this was exactly the example I gave. It seems we have a
> similar mindset ;)

Maybe extend this, then:

  module InlineMath
    def fib; ...; end
    def fac; ...; end
    def sin; ...; end
    def cos; ...; end
    def tan; ...; end
  end

  class Numeric
    include InlineMath
  end

Students have to implement those methods, and try it out with real
numbers.  Caveat: what about 3.5.fib and 3.5.fac?  Do the
trigonometric methods assume degress or radians?

Gavin




0
Reply gsinclair1 (862) 10/6/2004 1:51:39 AM

On Wed, 6 Oct 2004 10:36:43 +0900, Gavin Sinclair
<gsinclair@soyabean.com.au> wrote:
> On Wednesday, October 6, 2004, 3:24:12 AM, Brian wrote:
> 
> > Hello Group,
> 
> > I need more help.
> 
> > Gavin Sinclair wrote:
> >>
> >> p51. Good exercise.  How about another?
> >>
> 
> > Anybody has an idea for an exercise on extending existing classes. So
> > far the only thing I have come up with is:
> 
> > \exercise{Fibonacci II}{
> >    Extend \codetype{Integer} with a function fib that calculates the
> >    corresponding fibonacci number.}
> 
> > And my creativity is at an all time low.
> 
> There are plenty of examples at http://extensions.rubyforge.org.  I
> was thinking of something like String#indent as an exercise, but you
> haven't taught regexen at this point, so that's out.  But something
> else might do.
> 
>>>SNIP<<<

A question someone asked earlier on ruby-talk might be an easy, but
appropriate extension to go with #indent and others:
-- String#pack:

class String
 def pack(arg)
    self.split(//).pack(arg)
  end
end


Good luck!
/wad


0
Reply drewry (9) 10/6/2004 6:13:31 AM

On Wed, 6 Oct 2004 08:52:27 +0900, Francis Hwang <sera@fhwang.net> wrote:
> 
> On Oct 5, 2004, at 5:22 PM, Mark Hubbart wrote:
> > imho, there are two occasions for extending a class:
> > 1. When the added methods are useful for that class in general (ie,
> > String#rot13, Integer#factors)
> > 2. When you're just hacking :)
> 
> But this is all fairly subjective, isn't it?

Extremely :) In fact, my first draft of the email said so... but I
revised it, and apparently left that statement out.

What I was getting at here, is that #rot13 could be reasonably applied
to any text; and that is the primary use of strings in ruby: a text
container. Whereas, #remove_html_attributes would only be used on
special types of text: html documents/snippets. In this case, I would
subclass; in the rot13 case, I would extend. But that's just me, you
might feel differently. :)

> Among some programmers,
> String#rot13 might be a really sensible thing to add, but to others
> maybe it might seem like cruft. One interesting example from RubyConf
> was Rich Kilmer saying that he added methods like #minutes and #days to
> Fixnum, so he could say things like
> 
> 15.minutes + 2.hours
> 
> It's also very easy to imagine using this for, say, feet and inches:
> 
> 1.miles + 6.feet + 6.inches
> 
> ... which is culturally specific, isn't it? I mean, you're not going to
> use that if you use the metric system like a civilized people.

These things are great tricks, and very handy. But the ability to do
this belongs in the hands of the last coder to work on it. They
shouldn't be included in libs, etc, unless the express purpose of the
lib is to add them. They shouldn't be a side effect.

But they can be awfully handy in a script, or in small applications.

> There are two competing philosophies in OO theory. On one hand, you
> have the Platonists who believe that types are eternal forms that can
> be found in nature, so if you did your analysis right you'd find those
> forms and be able to codify them in your class definitions. On the
> other hand, you have the Pragmatists who believe that types are just
> shorthand, to be defined and discarded as the situation allows.

I tend to be more Pragmatic when I'm writing code that others won't be
editing/coding around, and Platonic when I'm writing library code.

> Ruby is more of a Pragmatist language, which personally I like 'cause
> on some deep level it jibes with my own belief in the subjectivity of
> experience. So, you know, if you want to extend a class, do it if it
> makes your life easier. If it doesn't, then don't do it.

Ruby *lets* you be pragmatic. That doesn't mean Ruby *itself* conforms
to your definition of pragmatic. Check the library code, and you'll
probably find it to be awfully platonic. And that's the way I like it,
because I often have trouble understanding other people's pragmatic
code :)

Still, as I said, I'm not trying too say you should program any way
you want. my earlier post was prefaced with "imho"  for that reason:
It truly was just my opinion, and you can safely ignore it if you want
:)

cheers,
Mark


0
Reply discordantus (236) 10/6/2004 7:13:19 PM

Brian Schr�der wrote:
> Hello List,
> 
> again I ask for your help. I'm going to give a 16 hours course on ruby 
> this week, and I've created some slides to aid me with this.
> I have to admit that some examples might not be as bright as I wish, and 
> also there are missing some exercises.
> I created the slides in english, such that they can be used by a bigger 
> part of the community if need should be.
> 
> The slides will not cover all that I hope to say in the course, when the 
> slides have finished I will start with a free experimentation phase 
> based on my ants sample implementation
> http://ruby.brian-schroeder.de/ants/
> 
> It would be great if some of you could look at the slides and correct 
> the language and if somebody comes up with a great example or exercise I 
> would also be glad for comments.
> 
> The slides are located at
> http://ruby.brian-schroeder.de/course/
> 
> Regards,
> 
> Brian
> 
> 


Thank you all for the great discussion and helpfull examples!

Sadly I could not use all the examples, because I have limited time in 
the course. But I wanted to acknowledge that people here are always full 
of good ideas.

Regards,

Brian

-- 
Brian Schr�der
http://ruby.brian-schroeder.de/


0
Reply ruby5435 (237) 10/6/2004 7:49:46 PM

35 Replies
38 Views

(page loaded in 0.336 seconds)


Reply: