My Thought on the "Pickaxe book" (from a Ruby novice)

That's interesting. I always use include?() so it doesn't matter if I'm dealing with a Hash or an Array. :wink:

I am sure glad we can both have it our way.

James Edward Gray II

ยทยทยท

On Jan 19, 2006, at 12:40 PM, Mark Volkmann wrote:

For example, in the Hash class, has_key? = include? = key? = member?
When I see include? and member? it's not immediately obvious to me
whether they test whether a given object is present as a key or a
value. has_key? and key? are more clear and I don't see a benefit to
having both of them.

I guess that's the part I don't get. In the majority the cases, I don't see
how choosing a particular synonym better expresses the intention.

For example, in the Hash class, has_key? = include? = key? = member? When I
see include? and member? it's not immediately obvious to me whether they
test whether a given object is present as a key or a value. has_key? and
key? are more clear and I don't see a benefit to having both of them.

i couldn't disagree more. names, for variables or methods, are of utmost
importance to better expresses intention:

   puts 'this makes sense even without knowing what set is!' if set.member? 42

   puts 'this is requires a comment' if s.has_key? 42

That may be the best example. Here are some others.

Enumerable:
collect = map
entries = to_a
detect = find
member? = include?
find_all = select

   p signals.detect{|sig| sig.freq > 42}

   p list.find{|x| x.freq > 42}

Hash:
store = =
merge! = update
has_value? = value?

Integer:
next = succ

IO:
pos = tell

Kernel:
fail = raise
format = sprintf

String
next = succ
next! = succ!

Thread
fork = start
exit = kill = terminate

for many synonyms consider duck typing usage as well - it's not only about
making sense when reading:

if i have a lib that does this

   exit if bug

then i can use it like this

   require 'lib'

or like this

   successfully_loaded = Thread::new {
     begin
       require 'lib'
       true
     rescue SystemExit
       nil
     end
   }.value

   puts "Thread#exit called in lieu of Kernel#exit - whew" unless successfully_loaded

the interface polymorism gained by synonyms is often handy.

if i design a table class an initially design it around a hash and use

   table.store key, value

in my code, but later decide i need to store multiple values under one key and
switch to a database backend i can simply have a store method that looks like

   def store key, *values
     ...
   end

and then start using

   table.store key, v0, v1, v2

without changing the other code. if i'd used

   table[key] = value

all over the plase initially i'd have a strange mixture of methods and would
require a special method for storing one value, which would quickly become
code smell. in this case the abstract idea of 'storing' something under a key
was more appropriate to my design in the first place so using this interface
saved me grief later.

synonyms exist elsewhere for clarity in ruby too

   unless == if not

thankfully.

regards.

-a

ยทยทยท

On Fri, 20 Jan 2006, Mark Volkmann wrote:
--
strong and healthy, who thinks of sickness until it strikes like lightning?
preoccupied with the world, who thinks of death, until it arrives like
thunder? -- milarepa

> For example, in the Hash class, has_key? = include? = key? = member?
> When I see include? and member? it's not immediately obvious to me
> whether they test whether a given object is present as a key or a
> value. has_key? and key? are more clear and I don't see a benefit to
> having both of them.

That's interesting. I always use include?() so it doesn't matter if
I'm dealing with a Hash or an Array. :wink:

That's a good argument for using include? instead of the other possibilities.

I am sure glad we can both have it our way.

Since you've convinced me of the benefit of your way, I'll make that my way too.

ยทยทยท

On 1/19/06, James Edward Gray II <james@grayproductions.net> wrote:

On Jan 19, 2006, at 12:40 PM, Mark Volkmann wrote:

--
R. Mark Volkmann
Partner, Object Computing, Inc.

> I guess that's the part I don't get. In the majority the cases, I don't see
> how choosing a particular synonym better expresses the intention.
>
> For example, in the Hash class, has_key? = include? = key? = member? When I
> see include? and member? it's not immediately obvious to me whether they
> test whether a given object is present as a key or a value. has_key? and
> key? are more clear and I don't see a benefit to having both of them.

i couldn't disagree more. names, for variables or methods, are of utmost
importance to better expresses intention:

   puts 'this makes sense even without knowing what set is!' if set.member? 42

   puts 'this is requires a comment' if s.has_key? 42

Good example. I guess what I'm looking for is an example of when
set.has_key? expresses intent better than set.member?. If there is no
such case then it seems to me the Set class shouldn't support
has_key?. Maybe this is related to what James said about being able to
use a different class without changing the code .. switching from a
Set to a Hash.

> That may be the best example. Here are some others.
>
> Enumerable:
> collect = map
> entries = to_a
> detect = find
> member? = include?
> find_all = select

   p signals.detect{|sig| sig.freq > 42}

   p list.find{|x| x.freq > 42}

That seems like a domain-specific example. I guess you're saying that
you detect signals, you don't find them. I feel like Ruby would really
be a mess if we added lots of domain-specific method names to the
built-in classes.

> Hash:
> store = =
> merge! = update
> has_value? = value?
>
> Integer:
> next = succ
>
> IO:
> pos = tell
>
> Kernel:
> fail = raise
> format = sprintf
>
> String
> next = succ
> next! = succ!
>
> Thread
> fork = start
> exit = kill = terminate

for many synonyms consider duck typing usage as well - it's not only about
making sense when reading:

Yes, that makes sense. I guess you could say that having synonyms
allows you to decide on a case-by-case basis whether you care more
about readability or the ability to change classes later without
changing code (for example, the case James pointed out where he could
switch between an Array and a Hash).

ยทยทยท

On 1/19/06, ara.t.howard@noaa.gov <ara.t.howard@noaa.gov> wrote:

On Fri, 20 Jan 2006, Mark Volkmann wrote:

--
R. Mark Volkmann
Partner, Object Computing, Inc.

#: ara.t.howard@noaa.gov changed the world a bit at a time by saying (astral date: 1/19/2006 9:10 PM) :#

I guess that's the part I don't get. In the majority the cases, I don't see
how choosing a particular synonym better expresses the intention.

For example, in the Hash class, has_key? = include? = key? = member? When I
see include? and member? it's not immediately obvious to me whether they
test whether a given object is present as a key or a value. has_key? and
key? are more clear and I don't see a benefit to having both of them.

i couldn't disagree more. names, for variables or methods, are of utmost
importance to better expresses intention:

   puts 'this makes sense even without knowing what set is!' if set.member? 42

   puts 'this is requires a comment' if s.has_key? 42

With all due respect, I would say these tricks are used _after_ you master the API.
The discussion (as far as i got it) was about leaning it (so _before_ mastering the API). And having 6 methods with different names is kind of confusing while learning. You are loosing a lot of time trying to identify if there are any differences between them.

I agree with you that after mastering the API these may become handy.

cheers,
./alex

ยทยทยท

On Fri, 20 Jan 2006, Mark Volkmann wrote:

--
.w( the_mindstorm )p.

ps: I guess this is pretty much in the idea of a series of blog posts that happen lately about human interfaces vs good APIs vs ... (iirc the start was somewhere on Martin Fowler's blog)

That may be the best example. Here are some others.

Enumerable:
collect = map
entries = to_a
detect = find
member? = include?
find_all = select

   p signals.detect{|sig| sig.freq > 42}

   p list.find{|x| x.freq > 42}

Hash:
store = =
merge! = update
has_value? = value?

Integer:
next = succ

IO:
pos = tell

Kernel:
fail = raise
format = sprintf

String
next = succ
next! = succ!

Thread
fork = start
exit = kill = terminate

for many synonyms consider duck typing usage as well - it's not only about
making sense when reading:

if i have a lib that does this

   exit if bug

then i can use it like this

   require 'lib'

or like this

   successfully_loaded = Thread::new {
     begin
       require 'lib'
       true
     rescue SystemExit
       nil
     end
   }.value

   puts "Thread#exit called in lieu of Kernel#exit - whew" unless successfully_loaded

the interface polymorism gained by synonyms is often handy.

if i design a table class an initially design it around a hash and use

   table.store key, value

in my code, but later decide i need to store multiple values under one key and
switch to a database backend i can simply have a store method that looks like

   def store key, *values
     ...
   end

and then start using

   table.store key, v0, v1, v2

without changing the other code. if i'd used

   table[key] = value

all over the plase initially i'd have a strange mixture of methods and would
require a special method for storing one value, which would quickly become
code smell. in this case the abstract idea of 'storing' something under a key
was more appropriate to my design in the first place so using this interface
saved me grief later.

synonyms exist elsewhere for clarity in ruby too

   unless == if not

thankfully.

regards.

-a

If you think the Ruby documentation is lacking you should try Pythons.
I've often noted their excuse for poor documentation is that the
language is easy to learn.

I don't think thats a valid excuse!

ยทยทยท

On 1/19/06, Mark Volkmann <r.mark.volkmann@gmail.com> wrote:

On 1/19/06, ara.t.howard@noaa.gov <ara.t.howard@noaa.gov> wrote:
> On Fri, 20 Jan 2006, Mark Volkmann wrote:
>
> > I guess that's the part I don't get. In the majority the cases, I don't see
> > how choosing a particular synonym better expresses the intention.
> >
> > For example, in the Hash class, has_key? = include? = key? = member? When I
> > see include? and member? it's not immediately obvious to me whether they
> > test whether a given object is present as a key or a value. has_key? and
> > key? are more clear and I don't see a benefit to having both of them.
>
> i couldn't disagree more. names, for variables or methods, are of utmost
> importance to better expresses intention:
>
> puts 'this makes sense even without knowing what set is!' if set.member? 42
>
> puts 'this is requires a comment' if s.has_key? 42

Good example. I guess what I'm looking for is an example of when
set.has_key? expresses intent better than set.member?. If there is no
such case then it seems to me the Set class shouldn't support
has_key?. Maybe this is related to what James said about being able to
use a different class without changing the code .. switching from a
Set to a Hash.

> > That may be the best example. Here are some others.
> >
> > Enumerable:
> > collect = map
> > entries = to_a
> > detect = find
> > member? = include?
> > find_all = select
>
> p signals.detect{|sig| sig.freq > 42}
>
> p list.find{|x| x.freq > 42}

That seems like a domain-specific example. I guess you're saying that
you detect signals, you don't find them. I feel like Ruby would really
be a mess if we added lots of domain-specific method names to the
built-in classes.

> > Hash:
> > store = =
> > merge! = update
> > has_value? = value?
> >
> > Integer:
> > next = succ
> >
> > IO:
> > pos = tell
> >
> > Kernel:
> > fail = raise
> > format = sprintf
> >
> > String
> > next = succ
> > next! = succ!
> >
> > Thread
> > fork = start
> > exit = kill = terminate
>
> for many synonyms consider duck typing usage as well - it's not only about
> making sense when reading:

Yes, that makes sense. I guess you could say that having synonyms
allows you to decide on a case-by-case basis whether you care more
about readability or the ability to change classes later without
changing code (for example, the case James pointed out where he could
switch between an Array and a Hash).

--
R. Mark Volkmann
Partner, Object Computing, Inc.

--
Wisdom is the reward you get for a lifetime of listening when you'd
have preferred to talk.

I'm working through the book myself
but I personally find it a little tedious.
Its not a bad book so far, but I would
have to rate it just so-so compared to
other programming books I've read.

One way I think it can improve is
by having unified source code for programs.
They seem to have this style that they
show a little piece of a program, then another
piece a few pages later, then another piece
maybe even a few chapters later... its really
frustrating not being able to get a program
to run because its code is scattered across
half the book.

I would upgrade my rating from so-so to good
if they would unify more of the source code
in the next version of the book.

Just my $0.02 :slight_smile:

ยทยทยท

--
Alex Combas
http://noodlejunkie.blogspot.com/

I definitely agree that you could probably stumble along by learning
just one way but you'll be left in the wilderness looking at someone
else's code. At least that's how I feel right now.

Ruby's versatility is like English. You can speak English with a very
heavy Spanish accent or German accent and even your grammar could be
heavily influenced but it will still be valid English nonetheless. To
stretch the metaphor further two non-native English speakers coming
from different languages usually have trouble understanding each
other's English.

I still wish there were more books out there on Ruby and Rails.
That'll will change drastically in 2006. I'm sure our more
experienced rubyists would benefit from a Ruby Pocket Reference
(actually available in Japanese from Oreilly).

How long did it take most of you to feel comfortable enough in Ruby to
understand other people's code as well?

ยทยทยท

On 1/20/06, Alexandru Popescu <the.mindstorm.mailinglist@gmail.com> wrote:

#: ara.t.howard@noaa.gov changed the world a bit at a time by saying (astral date: 1/19/2006 9:10 PM) :#
> On Fri, 20 Jan 2006, Mark Volkmann wrote:
>
>> I guess that's the part I don't get. In the majority the cases, I don't see
>> how choosing a particular synonym better expresses the intention.
>>
>> For example, in the Hash class, has_key? = include? = key? = member? When I
>> see include? and member? it's not immediately obvious to me whether they
>> test whether a given object is present as a key or a value. has_key? and
>> key? are more clear and I don't see a benefit to having both of them.
>
> i couldn't disagree more. names, for variables or methods, are of utmost
> importance to better expresses intention:
>
> puts 'this makes sense even without knowing what set is!' if set.member? 42
>
>
> puts 'this is requires a comment' if s.has_key? 42
>

With all due respect, I would say these tricks are used _after_ you master the API.
The discussion (as far as i got it) was about leaning it (so _before_ mastering the API). And having
6 methods with different names is kind of confusing while learning. You are loosing a lot of time
trying to identify if there are any differences between them.

I agree with you that after mastering the API these may become handy.

cheers,
./alex
--
.w( the_mindstorm )p.

ps: I guess this is pretty much in the idea of a series of blog posts that happen lately about human
interfaces vs good APIs vs ... (iirc the start was somewhere on Martin Fowler's blog)

>> That may be the best example. Here are some others.
>>
>> Enumerable:
>> collect = map
>> entries = to_a
>> detect = find
>> member? = include?
>> find_all = select
>
>
> p signals.detect{|sig| sig.freq > 42}
>
> p list.find{|x| x.freq > 42}
>
>> Hash:
>> store = =
>> merge! = update
>> has_value? = value?
>>
>> Integer:
>> next = succ
>>
>> IO:
>> pos = tell
>>
>> Kernel:
>> fail = raise
>> format = sprintf
>>
>> String
>> next = succ
>> next! = succ!
>>
>> Thread
>> fork = start
>> exit = kill = terminate
>
> for many synonyms consider duck typing usage as well - it's not only about
> making sense when reading:
>
> if i have a lib that does this
>
> exit if bug
>
> then i can use it like this
>
> require 'lib'
>
> or like this
>
> successfully_loaded = Thread::new {
> begin
> require 'lib'
> true
> rescue SystemExit
> nil
> end
> }.value
>
> puts "Thread#exit called in lieu of Kernel#exit - whew" unless successfully_loaded
>
>
> the interface polymorism gained by synonyms is often handy.
>
> if i design a table class an initially design it around a hash and use
>
> table.store key, value
>
> in my code, but later decide i need to store multiple values under one key and
> switch to a database backend i can simply have a store method that looks like
>
> def store key, *values
> ...
> end
>
> and then start using
>
> table.store key, v0, v1, v2
>
> without changing the other code. if i'd used
>
> table[key] = value
>
> all over the plase initially i'd have a strange mixture of methods and would
> require a special method for storing one value, which would quickly become
> code smell. in this case the abstract idea of 'storing' something under a key
> was more appropriate to my design in the first place so using this interface
> saved me grief later.
>
> synonyms exist elsewhere for clarity in ruby too
>
> unless == if not
>
> thankfully.
>
> regards.
>
> -a

The book is an excellent beginning and a decent reference, but I wish
that the topics were introduced in a more logical manner (from simple to
complex, or essential to might-never-use). In a metaphor, if the topics
are 1 (easy) through 10 (complex), I think the book reads like this:

1,3,5,3,4,7,2,6,8,7,6,9...

I'm ready for the Ruby for Dummies book. Anyone?

ยทยทยท

--
Posted via http://www.ruby-forum.com/.

Alex Combas wrote:

I'm working through the book myself
but I personally find it a little tedious.
Its not a bad book so far, but I would
have to rate it just so-so compared to
other programming books I've read.

One way I think it can improve is
by having unified source code for programs.
They seem to have this style that they
show a little piece of a program, then another
piece a few pages later, then another piece
maybe even a few chapters later... its really
frustrating not being able to get a program
to run because its code is scattered across
half the book.

I would upgrade my rating from so-so to good
if they would unify more of the source code
in the next version of the book.

Just my $0.02 :slight_smile:

As a newcomer I would tend to agree with this. What I did with my
PickAxeII was to actually split it along the spine into 3 more
manageable books and rebind (DIY style) each of the 3 smaller parts are
as follows:

1: Part I (Facets of Ruby)
2: Part II, III (Ruby in its setting, with objects explained at the end)
3: Part IV upto the end (Bulky reference)

I tend to get some reading done at night and I found it was getting a
bit too bulky for reading just the introdcutory parts. I don't really
see why I should carry around the bulk of the reference when I won't
even be using it for a while. I think it would be better to split the
book in 3 physical sections, and market them as one book (another
innovative thing to consider for Pragmatic Programmers.)

Also, I think that the book jumps around with its examples and tended to
frustrate me in the beginning when I was trying to use it as a tutorial.
What I ended up doing was take the 3 parts and read them buffet style.
Each chapter explains concepts well, if you don't mind not having a
cohesive strategy of code examples supporting the theoretical material.

So, how am I going about learning Ruby?

My approach is to read PickAxeII in conjunction with excellent tutorials
out there (Why's and Chris Pines come to mind). Read tutorial, See what
PickAxe has to say about it, read some more tutorial read the object
explanations etc. etc.

Right now, I would say to the newcomers to use Chris Pine's book in
conjunction with Why's tutorial and the Parts I, II and III of the
PickAxeII. To understand Objects in Ruby read the "A little Ruby, A lot
of objects" tutorial. Even though I tend to get lost towards the end of
the tutorial with the meta-classes/meta-meta-objects etc.

So, fellow newbies, this is how I'm going about it:
1. Chris Pines PDF book from PragProgg'rs (the pdf book is well worth
it)
2. Why's Poignant guide (take frequent breathers and come back to it.
You'll find that Why is literally sneaking ruby concepts through your
subconscious)
3. PickAxe2 : Part I, II, II (occasionally Part IV, but ri is always
easier and much lighter)
4. Brian Marick's "A little ruby A lot of objects"

Unfortunately PickAxeII is NOT the greatest Ruby tutorial out there,
even though Part I & II are excellent introductory texts, but the
pedagogical style suffers from inconsistency and code doesn't exactly
build on theory. I still constider it an excellent reference book and
frequently re-read parts to understand what's going on.

I personally would like to see some of the Japanese texts translated
which explain the internals of Ruby. One would be the Ruby Hacking Guide
which Why talks about in his article on Ruby GC.
(http://whytheluckystiff.net/articles/theFullyUpturnedBin.html\).

Either that or I'll have to learn Japanese. :slight_smile:

-Amr

ยทยทยท

--
Posted via http://www.ruby-forum.com/\.

It was a hard decision: showing full listings all the time would significantly add to the size of an already big book. That's why we did it the way we did, but also made sure we have full and complete listings, ties to the page numbers, available online at http://pragmaticprogrammer.com/titles/ruby/code

Cheers

Dave

ยทยทยท

On Jan 20, 2006, at 3:23 AM, Alex Combas wrote:

One way I think it can improve is
by having unified source code for programs.
They seem to have this style that they
show a little piece of a program, then another
piece a few pages later, then another piece
maybe even a few chapters later... its really
frustrating not being able to get a program
to run because its code is scattered across
half the book.

I would upgrade my rating from so-so to good
if they would unify more of the source code
in the next version of the book.

I've skimmed a bit of "Learn to program", maybe it's what you're looking for:
http://www.pragmaticprogrammer.com/titles/fr_ltp/index.html

Especially if you've decided you like the pragmatic prgrammer style. :slight_smile:

-Harold

ยทยทยท

On 1/19/06, Thomas Snide <Tom@tcssoftware.com> wrote:

I'm ready for the Ruby for Dummies book. Anyone?

Thanks Dave!
Is that mentioned anywhere in the book itself? That makes
a big difference. You've upgraded my opinion from Good to Great :}

ยทยทยท

On 1/23/06, Dave Thomas <dave@pragprog.com> wrote:

It was a hard decision: showing full listings all the time would
significantly add to the size of an already big book. That's why we
did it the way we did, but also made sure we have full and complete
listings, ties to the page numbers, available online at http://
pragmaticprogrammer.com/titles/ruby/code

--
Alex Combas
http://noodlejunkie.blogspot.com/