Forum: Ruby Beautiful Code : Pity he didn't ask here...

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.
John C. (Guest)
on 2007-07-10 04:16
(Received via mailing list)
Just got the O'Reilly announcement of the book "Beautiful
Code"... here is the sample chapter by Tim B. on Ruby!

   http://www.oreilly.com/catalog/9780596510046/chapt...

Pity he didn't run his examples by this forum first, I'm sure we could
have made them more beautiful..

Well, maybe for the 2nd edition, heres my bash at cleaning it up...

For example scanning a log file.....

EXAMPLE 4-2 . Printing article names
1 ARGF.each_line do |line|
2   if line =~ %r{GET /ongoing/When/\d\d\dx/(\d\d\d\d/\d\d/\d\d/[^ .]+)
}
3     puts $1
4   end
5 end

Since most Linux distro's roll the log files to a reasonable size I
would have just gone with...

ARGF.read.scan( %r{GET /ongoing/When/\d\d\dx/(\d\d\d\d/\d\d/\d\d/[^ .]+)
}) do |match|
    puts $1
end

In Example 4.3 he has...
1 counts = {}
2 counts.default = 0

Personally I prefer...
  counts = Hash.new(0)
   or
  counts = Hash.new{|hash,key| hash[key]=0}
buts that's personal preference I guess.

In example 4.4 he rightly identifies line 10 as a little ugly and
bemoans the lack of sort_by_value in hash.
   10 keys_by_count = counts.keys.sort { |a, b| counts[b] <=> counts[a]
}
it seems he doesn't know about..

count.keys.sort_by{|key| count[key]}

Of course he could have done...

class Hash
   def sort_keys_by_value
     keys.sort_by{|key| fetch(key)}
   end
end


Example 4.5 looks like a poster child for the Hash.new block approach...
4 @hash = {}
.
.

9 if @hash[s[0]]
10 @hash[s[0]] << [ s[1], article ]
11 else
12 @hash[s[0]] = [ s[1], article ]
13 end


Replace that with...

4 @hash = Hash.new{|hash,key| hash[key] = []}

10 @hash[s[0]] << [ s[1], article ]


That makes it real pretty code.


In fact, I can't find any pretty reason to have the class BigHash at
all....looks like his Java roots are showing through.

Personally I'd just drop it.

Partly the point of the exercise here is it is slow because it is so
big, a couple of things I wonder about...

For example I would time how long it takes to just read the file and do
nothing..

He mentions the program grew to 1.56gb

Well, he is creating an Array per log entry.

Maybe if he created two hashes instead of an array per entry.

Incidently, I wouldn't have chosen that chunk of Java for illustrating
the binary search....

glibc's implementation is just so clean....


/* Perform a binary search for KEY in BASE which has NMEMB elements
    of SIZE bytes each.  The comparisons are done by (*COMPAR)().  */
void *
bsearch (const void *key, const void *base, size_t nmemb, size_t size,
    int (*compar) (const void *, const void *))
{
   size_t l, u, idx;
   const void *p;
   int comparison;

   l = 0;
   u = nmemb;
   while (l < u)
     {
       idx = (l + u) / 2;
       p = (void *) (((const char *) base) + (idx * size));
       comparison = (*compar) (key, p);
       if (comparison < 0)
   u = idx;
       else if (comparison > 0)
   l = idx + 1;
       else
   return (void *) p;
     }

   return NULL;
}

On the other hand both have the classic bug that (high + low) or (l+u)
overflows on large arrays...



John C.                             Phone : (64)(3) 358 6639
Tait Electronics                        Fax   : (64)(3) 359 4632
PO Box 1645 Christchurch                Email : 
removed_email_address@domain.invalid
New Zealand
James G. (Guest)
on 2007-07-10 04:54
(Received via mailing list)
On Jul 9, 2007, at 7:15 PM, John C. wrote:

> 5 end
>
> Since most Linux distro's roll the log files to a reasonable size I
> would have just gone with...
>
> ARGF.read.scan( %r{GET /ongoing/When/\d\d\dx/(\d\d\d\d/\d\d/\d\d/
> [^ .]+) }) do |match|
>    puts $1
> end

Hmm, I don't think we should slurp when we don't need too.  There's
no reason to be wasteful.

I really liked the rest of your fixes though.

James Edward G. II
Ryan D. (Guest)
on 2007-07-10 10:56
(Received via mailing list)
On Jul 9, 2007, at 17:53 , James Edward G. II wrote:

>> ARGF.read.scan( %r{GET /ongoing/When/\d\d\dx/(\d\d\d\d/\d\d/\d\d/
>> [^ .]+) }) do |match|
>>    puts $1
>> end
>
> Hmm, I don't think we should slurp when we don't need too.  There's
> no reason to be wasteful.

Actually there is plenty of reason to be wasteful:

1) We can.
2) It leads to code that reads like the above.
3) We can!
4) It is only a short hop to:

    puts ARGF.read.scan( %r%GET /ongoing/When/\d\d\dx/(\d\d\d\d/\d\d/
\d\d/[^ .]+) %).join("\n")

5) We can!!
6) It is our moral obligation to use our oft-idle and underused
computers to their fullest.

There was a 7th... but I forgot what it was.
Martin DeMello (Guest)
on 2007-07-10 11:58
(Received via mailing list)
On 7/10/07, John C. <removed_email_address@domain.invalid> wrote:
> Since most Linux distro's roll the log files to a reasonable size I would have just gone 
with...
>
> ARGF.read.scan( %r{GET /ongoing/When/\d\d\dx/(\d\d\d\d/\d\d/\d\d/[^ .]+) }) do |match|
>     puts $1
> end

ARGF.read.scan( %r{GET /ongoing/When/\d{3}x/(\d#{4}/\d#{4}/[^ .]+) }) do
|match|
    puts $1
 end

martin
Robert D. (Guest)
on 2007-07-10 13:49
(Received via mailing list)
On 7/10/07, Martin DeMello <removed_email_address@domain.invalid> wrote:
> On 7/10/07, John C. <removed_email_address@domain.invalid> wrote:
> > Since most Linux distro's roll the log files to a reasonable size I would have just 
gone with...
> >
> > ARGF.read.scan( %r{GET /ongoing/When/\d\d\dx/(\d\d\d\d/\d\d/\d\d/[^ .]+) }) do |match|
> >     puts $1
> > end
>
I am with James do not slurp in the whole string it just does not make
sense to me. I would feel very uneasy using regexps on large strings
even if right now there seems no backtracking issues to be present,
but code evolves sometimes ;)

> ARGF.read.scan( %r{GET /ongoing/When/\d{3}x/(\d#{4}/\d#{4}/[^ .]+) }) do |match|

Nope Martin read the original code again!!  All the / and \ ;).
I was about to fall into the same trap.
As a matter of fact I miss all beauty in that code :( The regexp is
just ugly, some ideas for cosmetic surgery ;)

def dig_dirs *args
    Regexp.new args.map{|n| "\d" * n}.join("/")
end

puts ARGF.map { |line|
    line =~ %r{ GET /ongoing/When/\d{3}x/(#{dig_dirs 4, 2, 2}/[^ .])}
    $1
}.compact

But beauty lies to everybody (or was that "in the eyes of the beholder"?
).

Cheers
Robert
Robert D. (Guest)
on 2007-07-10 14:11
(Received via mailing list)
On 7/10/07, John C. <removed_email_address@domain.invalid> wrote:
> Just got the O'Reilly announcement of the book "Beautiful
<snip>
> In Example 4.3 he has...
> 1 counts = {}
> 2 counts.default = 0

>
> count.keys.sort_by{|key| count[key]}
>
> Of course he could have done...
>
> class Hash
>    def sort_keys_by_value
>      keys.sort_by{|key| fetch(key)}
>    end
> end
or

tops = counts.sort_by{|*kv| kv.last}.reverse[0..9]
puts tops.map{ |k,v| "#{v}: #{k}"}

#each is just a primitive for Enumerables, right?

> 12 @hash[s[0]] = [ s[1], article ]
> That makes it real pretty code.
Save for

   File.open(some_name).each_line

Let the GC close the file!? It is not going to happen !!

<snip>
Robert
Daniel M. (Guest)
on 2007-07-10 16:14
(Received via mailing list)
John C. <removed_email_address@domain.invalid> writes:

> Just got the O'Reilly announcement of the book "Beautiful
> Code"... here is the sample chapter by Tim B. on Ruby!
>
...
>
> For example scanning a log file.....
>
> Since most Linux distro's roll the log files to a reasonable size I would have just gone 
with...
>
> ARGF.read.scan( %r{GET /ongoing/When/\d\d\dx/(\d\d\d\d/\d\d/\d\d/[^ .]+) }) do |match|
>    puts $1
> end

As James said, I'm going to have to disagree on this, though I'd clean
it up to:

article_pattern = \
  %r{GET /ongoing/When/\d\d\dx/(\d\d\d\d/\d\d/\d\d/[^ .]+) }
ARGF.each_line do |line|
  line.scan(article_pattern) do |article,|
    puts article
  end
end

Look, no global variables!

I agree with your use of Hash.new(0), but disagree that it's mere
personal preference - it's much more common to use even the single
argument form in the constructor than to use default=.

It is odd that he seems unaware of Array.sort_by - anyone know when
this was added to Ruby core?  The book could be rather out of date.

> Example 4.5 looks like a poster child for the Hash.new block approach...

Agreed.  I wonder if perhaps he's spent more time in python or some
other dynamic language than Ruby.

> In fact, I can't find any pretty reason to have the class BigHash at
> all....looks like his Java roots are showing through.

Yeah; in Java, you can't have code existing outside of a class, and I
suspect that's a big part of it.

> On the other hand both have the classic bug that (high + low) or
> (l+u) overflows on large arrays...

Actually, his code doesn't: java arrays can only have 2**31 entries
(since their index is a java int), and java ints are always signed.
Therefore, any overflow in the addition in java yields a negative
integer, and >>> in java does right shift without sign extension.
(That is, with 0s shifted in at the left).

The glibc code does have that problem, but only on arrays that have
more than (maximum size_t)/2 elements.
unknown (Guest)
on 2007-07-10 16:15
(Received via mailing list)
Hi --

On Tue, 10 Jul 2007, John C. wrote:

> In Example 4.3 he has...
> 1 counts = {}
> 2 counts.default = 0
>
> Personally I prefer...
> counts = Hash.new(0)
>  or
> counts = Hash.new{|hash,key| hash[key]=0}
> buts that's personal preference I guess.

Yes, but be careful: your two lines don't do the same thing as each
other:

irb(main):007:0> counts = Hash.new(0)
=> {}
irb(main):008:0> counts["hi"]
=> 0
irb(main):009:0> counts
=> {}
irb(main):010:0>  counts = Hash.new{|hash,key| hash[key]=0}
=> {}
irb(main):011:0> counts["hi"]
=> 0
irb(main):012:0> counts
=> {"hi"=>0}

>  def sort_keys_by_value
>    keys.sort_by{|key| fetch(key)}
>  end
> end

It's best not to get into changing the core language, though, if the
book isn't going to discuss the benefits and pitfalls of doing so in
depth.


David
Christoffer S. (Guest)
on 2007-07-10 16:34
(Received via mailing list)
Hello.

On 7/10/07, John C. <removed_email_address@domain.invalid> wrote:
> count.keys.sort_by{|key| count[key]}

IMHO, the most elegant way to do this is:

hash.sort_by { |k, v| v }.map { |k, v| k }

...where k = key and v = value.

Cheers,
Wayne E. Seguin (Guest)
on 2007-07-10 16:42
(Received via mailing list)
On Jul 10, 2007, at 08:27 , Christoffer S. wrote:
>
> Cheers,

Ack, pet peeve.

hash.sort_by { | key, value | value } .map { | key, value | key }

If you have to specify "where k = key and v = value" then these
should have been used in your code.

Always favor readability at the expense of verbosity, both your
future self and whoever else maintains your code will thank you.
Gregory B. (Guest)
on 2007-07-10 17:15
(Received via mailing list)
On 7/10/07, Wayne E. Seguin <removed_email_address@domain.invalid> wrote:
> > ...where k = key and v = value.
> Always favor readability at the expense of verbosity, both your
> future self and whoever else maintains your code will thank you.

I find myself always using |k,v|, when used on something hashlike I
don't think readability suffers.
James G. (Guest)
on 2007-07-10 17:24
(Received via mailing list)
On Jul 10, 2007, at 8:13 AM, Gregory B. wrote:

>> >
>>
>> Always favor readability at the expense of verbosity, both your
>> future self and whoever else maintains your code will thank you.
>
> I find myself always using |k,v|, when used on something hashlike I
> don't think readability suffers.

I've also recently adopted the trick of using _ as an unused
parameter name.  I believe it was Ara that first suggested this and I
think it's a great idea:

   hash.sort_by { |key, _| … }…

James Edward G. II
Daniel M. (Guest)
on 2007-07-10 18:07
(Received via mailing list)
"Robert D." <removed_email_address@domain.invalid> writes:

> On 7/10/07, John C. <removed_email_address@domain.invalid> wrote:
>> Just got the O'Reilly announcement of the book "Beautiful
> <snip>
>> That makes it real pretty code.
>
> Save for
>
>   File.open(some_name).each_line
>
> Let the GC close the file!? It is not going to happen !!

Good point.  In many ways, it feels that the author is not as
comfortable with Ruby blocks as one should be.  A better version,
since we also don't need a separate class:

def get_big_hash(filename)
  hash = Hash.new {|h,k| h[k]=[]}
  lines = 0
  File.open(filename) do |file|
    file.each_line do |line|
      s = line.split
      article = s[2].intern
      hash[s[0]] << [ s[1], article ]
      lines += 1
      STDERR.puts "Line: #{lines}" if (lines % 100_000) == 0
    end
  end
  return hash
end

I really like the block-using form of File.open.  It makes me feel all
nice and safe like being wrapped in with-open-file or a carefully
constructed dynamic-wind.
Paul B. (Guest)
on 2007-07-10 18:26
(Received via mailing list)
On 10/07/07, James Edward G. II <removed_email_address@domain.invalid> wrote:
> I've also recently adopted the trick of using _ as an unused
> parameter name.  I believe it was Ara that first suggested this and I
> think it's a great idea:
>
>    hash.sort_by { |key, _| … }…

I thought it came from Haskell, where _ is a wildcard parameter:

Prelude> let power _ 0 = 1
Prelude> power 4 0
1
Prelude> power 100 0
1
Prelude> power 4 2
*** Exception: <interactive>:1:4-16: Non-exhaustive patterns in function
power
Prelude> let power a b = a ** b
Prelude> power 4 2
16.0

... however, I wouldn't be surprised to find that Haskell took it from
some other language.

Paul.
James G. (Guest)
on 2007-07-10 18:28
(Received via mailing list)
On Jul 10, 2007, at 9:24 AM, Paul B. wrote:

> On 10/07/07, James Edward G. II <removed_email_address@domain.invalid> wrote:
>> I've also recently adopted the trick of using _ as an unused
>> parameter name.  I believe it was Ara that first suggested this and I
>> think it's a great idea:
>>
>>    hash.sort_by { |key, _| … }…
>
> I thought it came from Haskell, where _ is a wildcard parameter:

I meant that I believe it was Ara who recommended it as a good name
for an unused block parameter in Ruby.

James Edward G. II
Tim B. (Guest)
on 2007-07-10 18:48
(Received via mailing list)
On Jul 9, 2007, at 5:15 PM, John C. wrote:

> Just got the O'Reilly announcement of the book "Beautiful
> Code"... here is the sample chapter by Tim B. on Ruby!
>
>   http://www.oreilly.com/catalog/9780596510046/chapt...
>
> Pity he didn't run his examples by this forum first, I'm sure we could
> have made them more beautiful..

Yep, mostly because for some reason I didn't know about sort_by.  I
wonder how I missed that?  Obviously, the main point of my article
was to encourage people to use the idiom of reading lines, picking
'em apart with a regex, and accumulating in a hash, invented in awk,
brought to the world in perl, perfected in Ruby.

sort_by aside, I'm not convinced that any of the alternatives to my
main loop are more beautiful or readable.  I personally think that
the reason Ruby will enjoy an ever increasing market share in the
programming-languages space is because it's more readable.

I'm looking at the following...

>
> ARGF.read.scan( %r{GET /ongoing/When/\d\d\dx/(\d\d\d\d/\d\d/\d\d/
> [^ .]+) }) do |match|
>    puts $1
> end

Really? Considering most of the readership is new to Ruby?

> In Example 4.3 he has...
> 1 counts = {}
> 2 counts.default = 0
>
> Personally I prefer...
>  counts = Hash.new(0)
>   or
>  counts = Hash.new{|hash,key| hash[key]=0}
> buts that's personal preference I guess.

Gosh, I think I totally disagree on readability grounds.

  -Tim
Tim B. (Guest)
on 2007-07-10 18:50
(Received via mailing list)
On Jul 10, 2007, at 5:11 AM, Daniel M. wrote:

>
> Look, no global variables!

Yep, much better, I wish I'd done it that way.

> I agree with your use of Hash.new(0), but disagree that it's mere
> personal preference - it's much more common to use even the single
> argument form in the constructor than to use default=.

Why?  default= makes it more obvious what you're doing.  I think it's
better practice.

>> Example 4.5 looks like a poster child for the Hash.new block
>> approach...
>
> Agreed.  I wonder if perhaps he's spent more time in python or some
> other dynamic language than Ruby.

Perl :)

  -Tim
Wayne E. Seguin (Guest)
on 2007-07-10 18:55
(Received via mailing list)
On Jul 10, 2007, at 09:23 , James Edward G. II wrote:
> I've also recently adopted the trick of using _ as an unused
> parameter name.  I believe it was Ara that first suggested this and
> I think it's a great idea:
>
>   hash.sort_by { |key, _| … }…
>
> James Edward G. II

That is a good idea, I also use that in several places within blocks.
Chad P. (Guest)
on 2007-07-10 21:15
(Received via mailing list)
On Tue, Jul 10, 2007 at 11:47:26PM +0900, Tim B. wrote:
> >buts that's personal preference I guess.
>
> Gosh, I think I totally disagree on readability grounds.

Actually, I think this:

  counts = Hash.new(0)

. . . is perfectly readable, and a bit more elegant than the two-line
version from "Example 4.3".  On the other hand, this bit looks pretty
ugly to me:

  counts = Hash.new{|hash,key| hash[key]=0]}

. . . especially since it looks like someone is afraid he has a limited
number of space characters to use, and doesn't want to run out.  Even
with some spaces added to it, though, it's not as pretty and readable.
Caleb P. (Guest)
on 2007-07-10 22:49
(Received via mailing list)
On 7/10/07, Tim B. <removed_email_address@domain.invalid> wrote:
> Yep, mostly because for some reason I didn't know about sort_by.  I
> wonder how I missed that?  O

Perhaps because sort_by is defined in Enumerable, not in the Array
class. I wish that the Ruby documentation inlined methods like these
from Mixin classes (similar to how Javadoc displays a parent class'
methods). Is this possible when generating using rdoc?

--
Caleb

Doubt is not a pleasant condition, but certainty is absurd - Voltaire
Ryan D. (Guest)
on 2007-07-10 23:51
(Received via mailing list)
On Jul 10, 2007, at 05:41 , Wayne E. Seguin wrote:

> Always favor readability at the expense of verbosity, both your
> future self and whoever else maintains your code will thank you.

I won't. k and v work Just Fine™ for me and whomever else I work
with. Verbosity for verbosity's sake, esp when it pushes outside of
common and accepted idioms, is a form of mentarbation.
ara.t.howard (Guest)
on 2007-07-11 05:16
(Received via mailing list)
On Jul 10, 2007, at 8:28 AM, James Edward G. II wrote:

> I meant that I believe it was Ara who recommended it as a good name
> for an unused block parameter in Ruby.

i'll only take credit if beer is involved ... ;-)


-a
ara.t.howard (Guest)
on 2007-07-11 05:54
(Received via mailing list)
On Jul 10, 2007, at 8:47 AM, Tim B. wrote:

> Gosh, I think I totally disagree on readability grounds.

let's step back for one moment and think about why we all left perl:

   - wtf is $1 ?
   - wtf is ARGF ?
   - regexes are, of all things, the epitome of snoopy swearing

these are the kinds of magic things that used to send us all
perdoc'ing to read our own code.

while i use both of those thing in dirty script i keep in ~/bin/ i'd
never publish them as beautiful.  names are the most important thing
in programing and terminals are pretty dang wide these days

given that, why not

   pattern =
     %r|GET /ongoing/When/\d\d\dx/(\d\d\d\d/\d\d/\d\d/[^ .]+)|x

   STDIN.each_line do |line|
     match, date, *ignored = pattern.match(line).to_a
     next unless date
     puts date
   end

i always consider using the magic $vars a sign of temporary perl
madness.

kind regards.

-a
unknown (Guest)
on 2007-07-11 06:07
(Received via mailing list)
Hi --

On Wed, 11 Jul 2007, ara.t.howard wrote:

>
> On Jul 10, 2007, at 8:47 AM, Tim B. wrote:
>
>> Gosh, I think I totally disagree on readability grounds.
>
> let's step back for one moment and think about why we all left perl:

I fell in love :-)


David
Marcel Molina Jr. (Guest)
on 2007-07-11 06:09
(Received via mailing list)
On Wed, Jul 11, 2007 at 10:53:42AM +0900, ara.t.howard wrote:
>     %r|GET /ongoing/When/\d\d\dx/(\d\d\d\d/\d\d/\d\d/[^ .]+)|x

Looking at all those \d is kind of hard to parse also. I think the
following
way of expression that pattern is considerably clearer:

      %r|GET /ongoing/When/\d{3}x/(\d{4}/\d{2}/\d{2}/[^ .]+)|x

Readability improves even more when Oniguruma allows for named captures.

marcel
James G. (Guest)
on 2007-07-11 06:16
(Received via mailing list)
On Jul 10, 2007, at 8:53 PM, ara.t.howard wrote:

>
> On Jul 10, 2007, at 8:47 AM, Tim B. wrote:
>
>> Gosh, I think I totally disagree on readability grounds.
>
> let's step back for one moment and think about why we all left perl:
>
>   - wtf is $1 ?
>   - wtf is ARGF ?
>   - regexes are, of all things, the epitome of snoopy swearing

You just insulted all of my best friends in one go.  I think I better
get my butt back to Perl…  :)

James Edward G. II
Chad P. (Guest)
on 2007-07-11 06:45
(Received via mailing list)
On Wed, Jul 11, 2007 at 10:53:42AM +0900, ara.t.howard wrote:
>
> On Jul 10, 2007, at 8:47 AM, Tim B. wrote:
>
> >Gosh, I think I totally disagree on readability grounds.
>
> let's step back for one moment and think about why we all left perl:

Speak for yourself.  I didn't leave Perl at all.  I just added Ruby to
my
repertoire.  I'm not sold on the idea that there's One True Language,
and
its name is Ruby.  I use different languages for different purposes.
Some languages are generally good, and some are generally bad, but many
languages are good for at least one thing in a way that other languages
aren't -- and for that reason among others, I use both Perl and Ruby.


>
>   - wtf is $1 ?
>   - wtf is ARGF ?
>   - regexes are, of all things, the epitome of snoopy swearing

$1 is the first capture.  Seems obvious to me.
ARGF is closely related to ARGV.
Regexen are extremely useful, and removing them from Ruby would be a bit
like shooting it in the head.


>
> i always consider using the magic $vars a sign of temporary perl
> madness.

I always see it as a potential sign of greater maintainability (if
they're used well).
ara.t.howard (Guest)
on 2007-07-11 08:04
(Received via mailing list)
On Jul 10, 2007, at 8:08 PM, Marcel Molina Jr. wrote:

> Looking at all those \d is kind of hard to parse also. I think the
> following
> way of expression that pattern is considerably clearer:
>
>       %r|GET /ongoing/When/\d{3}x/(\d{4}/\d{2}/\d{2}/[^ .]+)|x
>
> Readability improves even more when Oniguruma allows for named
> captures.

yeah, i actually like to break them out like

  %r|
            GET
            \d\d\d\d  # year
            \d\d      # month
           |

but i didn't want to go overboard!

named captures are a real want in ruby right now if you ask me.  i've
been using the idiom

   match, yyyy, mm, dd, *ignored = pattern.match(string).to_a

   if match
     ...
   end

as a workaround

(for those that don't know the captures in patterns can be got that way)

cheers.

-a
ara.t.howard (Guest)
on 2007-07-11 08:05
(Received via mailing list)
On Jul 10, 2007, at 8:15 PM, James Edward G. II wrote:

> You just insulted all of my best friends in one go.

many of mine too.  still, there are only a few of my friends i'd
exclaim to be beautiful!  ;-)

-a
ara.t.howard (Guest)
on 2007-07-11 08:08
(Received via mailing list)
On Jul 10, 2007, at 8:43 PM, Chad P. wrote:

> repertoire.  I'm not sold on the idea that there's One True
>>   - wtf is $1 ?
>>
> words. Sometimes that's just easier. For the same reasons that
> pointing has
> not made words obsolete, there will always be command lines."
>


hey chad-

i've been writing oo-perl for many moons, setting $/ to slurp files
and all that...  nevertheless the are features of ruby that attracted
to me it from the context of perl and continue to stand out when
selecting one of the two languages for a particular purpose.  the
power of ruby is that of abstraction and cleanliness.

ps.  truth be told i really only maintain perl now and haven't
written anything new in it for years. ;-)

-a
Robert D. (Guest)
on 2007-07-11 12:25
(Received via mailing list)
On 7/11/07, ara.t.howard <removed_email_address@domain.invalid> wrote:
>
> On Jul 10, 2007, at 8:28 AM, James Edward G. II wrote:
>
> > I meant that I believe it was Ara who recommended it as a good name
> > for an unused block parameter in Ruby.
>
> i'll only take credit if beer is involved ... ;-)

Admit it, you took it from Prolog or Lua or Python or ... :)

Robert
John J. (Guest)
on 2007-07-11 13:05
(Received via mailing list)
On Jul 10, 2007, at 9:08 PM, Marcel Molina Jr. wrote:

> captures.
>
> marcel
> --
> Marcel Molina Jr. <removed_email_address@domain.invalid>
>
It is hard to parse. That's why all RegExes should include a comment
describing wtf it is supposed to match!
Ideally, with an example string.
Oh, wait, that's halfway to a test unit!
Chad P. (Guest)
on 2007-07-11 13:38
(Received via mailing list)
On Wed, Jul 11, 2007 at 01:07:55PM +0900, ara.t.howard wrote:
>
> i've been writing oo-perl for many moons, setting $/ to slurp files
> and all that...  nevertheless the are features of ruby that attracted
> to me it from the context of perl and continue to stand out when
> selecting one of the two languages for a particular purpose.  the
> power of ruby is that of abstraction and cleanliness.

All else being equal, if I have call to write OO code, I'll always
choose
Ruby over Perl.  All else is not always equal, and sometimes OOP is not
the most effective approach to solving a problem, however.
Pit C. (Guest)
on 2007-07-11 15:15
(Received via mailing list)
2007/7/10, James Edward G. II <removed_email_address@domain.invalid>:
> I've also recently adopted the trick of using _ as an unused
> parameter name.  I believe it was Ara that first suggested this and I
> think it's a great idea:
>
>    hash.sort_by { |key, _| … }…

Maybe it was Ara indeed, but the first reference I found on ruby-talk
was a post from Nikolai W. almost two years ago. See
ruby-talk:149793.

Regards,
Pit
Robert D. (Guest)
on 2007-07-11 15:22
(Received via mailing list)
On 7/11/07, Chad P. <removed_email_address@domain.invalid> wrote:
> the most effective approach to solving a problem, however.
Hmm that's for sure, but is not it's notational beauty which sometimes
makes us use it without any good -other- reason. That is a thought I
am incubating for a long time but your sentence and my recent
experience with Lua pushes me to say that.
I love the concept of Lua, I cannot stand the code I have to write :(.

R.
unknown (Guest)
on 2007-07-11 15:25
(Received via mailing list)
Hi --

On Wed, 11 Jul 2007, Pit C. wrote:

> 2007/7/10, James Edward G. II <removed_email_address@domain.invalid>:
>> I've also recently adopted the trick of using _ as an unused
>> parameter name.  I believe it was Ara that first suggested this and I
>> think it's a great idea:
>>
>>    hash.sort_by { |key, _| … }…
>
> Maybe it was Ara indeed, but the first reference I found on ruby-talk
> was a post from Nikolai W. almost two years ago. See
> ruby-talk:149793.

Isn't that the same as:

   hash.sort_by {|key,| ... }

(assuming one isn't going to make use of the value in _)?


David
Robert D. (Guest)
on 2007-07-11 15:31
(Received via mailing list)
On 7/11/07, removed_email_address@domain.invalid 
<removed_email_address@domain.invalid> wrote:
> >
> > Maybe it was Ara indeed, but the first reference I found on ruby-talk
> > was a post from Nikolai W. almost two years ago. See
> > ruby-talk:149793.
>
> Isn't that the same as:
>
>    hash.sort_by {|key,| ... }
>
> (assuming one isn't going to make use of the value in _)?

yup was brought up by Robert (Klemme) recently, and if memory serves
   { | , key | ... }
does not work :(.
>
Robert
James G. (Guest)
on 2007-07-11 16:23
(Received via mailing list)
On Jul 11, 2007, at 6:11 AM, Pit C. wrote:

> 2007/7/10, James Edward G. II <removed_email_address@domain.invalid>:
>> I've also recently adopted the trick of using _ as an unused
>> parameter name.  I believe it was Ara that first suggested this and I
>> think it's a great idea:
>>
>>    hash.sort_by { |key, _| … }…
>
> Maybe it was Ara indeed, but the first reference I found on ruby-talk
> was a post from Nikolai W. almost two years ago. See
> ruby-talk:149793.

Oops, my mistake.

James Edward G. II
degei (Guest)
on 2007-07-11 18:00
(Received via mailing list)
On Jul 10, 10:28 am, James Edward G. II <removed_email_address@domain.invalid>
wrote:
>
> I meant that I believe it was Ara who recommended it as a good name
> for an unused block parameter in Ruby.
>
> James Edward G. II

Just as an aside, I believe Erlang adopts this style as a part of this
language, where it will warn if you have unused variables but allows
you to annotate them with _ (ex. _var) to denote that they will not be
used, or just replace the variable name with _ thus eliminating the
warning.

(I don't know Erlang yet, just remembered reading this in
http://pragdave.pragprog.com/pragdave/2007/04/a_fi...)
diego scataglini (Guest)
on 2007-07-11 18:09
(Received via mailing list)
Nice, didn't know about it. Erlang has a similar thing for throwaway
values.

Thanks James

Diego Scataglini

On Jul 10, 2007, at 9:23 AM, James Edward G. II
<removed_email_address@domain.invalid
alex_land (Guest)
on 2007-07-12 01:06
(Received via mailing list)
Well i for one am feeling pretty good that i learned Ruby here and not
from a textbook.

Anyway, nice work.  Editors are probably wishing they would have gone
with "Cute Code" or "Decent-Looking Code."


--alex
Robert D. (Guest)
on 2007-07-12 01:17
(Received via mailing list)
On 7/11/07, alex_land <removed_email_address@domain.invalid> wrote:
> Well i for one am feeling pretty good that i learned Ruby here and not
> from a textbook.
>
That is something very nice to say :)

> Anyway, nice work.  Editors are probably wishing they would have gone
> with "Cute Code" or "Decent-Looking Code."

It is indeed a very ambitious title, the Ruby chapter is very
disappointing but the author pointed out it was for beginners (sic).
For me that makes no sense :(

Oh BTW please do not top post, a huge majority of us prefer bottom
posting :)
>
>
> --alex
>
>
Robert
John C. (Guest)
on 2007-07-12 03:11
(Received via mailing list)
On Tue, 10 Jul 2007, Tim B. wrote:

> I personally think that the reason Ruby will enjoy an ever
> increasing market share in the programming-languages space is
> because it's more readable.
   >snip<
> Gosh, I think I totally disagree on readability grounds.

I perfectly agree with you.

Yet, I find my use of Ruby has changed on that front.

At first I wrote Ruby that was, I thought, in a most readable style.

What I realized later was, it was most readable to someone who knew
C++ well, but not Ruby.

But now I have found I'm headed more to Hal F.'s attitude as
expressed
in his book "The Ruby Way"
    http://rubyhacker.com/coralbook/

I try to write the most readable code that is most readable by someone
who knows Ruby perfectly well.

If, on the rare occasions that requires deep knowledge of Ruby... I
will explain that in the comment, not the code.

ie. My code assumes you know everything about Ruby. My comments assume
that you are a newbie.

Now that places a conundrum before someone writing a book "Beautiful
Code" for non-Ruby readers. Talk down to them? Speak a C++/Java/Ruby
pidgin?

Personally I would speak up to them. Scan the libraries for the best
code Rubiest have to offer in the Ruby idiom.... and spend my time
explaining the elegance, power and succinctness of it.


John C.                             Phone : (64)(3) 358 6639
Tait Electronics                        Fax   : (64)(3) 359 4632
PO Box 1645 Christchurch                Email : 
removed_email_address@domain.invalid
New Zealand
Tom C. (Guest)
on 2007-07-12 05:19
(Received via mailing list)
On Thu, 2007-07-12 at 08:11 +0900, John C. wrote:
> I try to write the most readable code that is most readable by someone
> who knows Ruby perfectly well.

Right on.  Today Rich Kilmer showed me some Rails code that Chad F.
had written.  It was something like:

some_array.map(&:name)

where some_array was filled with objects that had a name attribute, and
Rails reopened Symbol and added to_proc.

At first I thought "oh, that's ridiculous".  Five minutes later I
thought "hm, that's rather nice".  Five minutes later I agreed with Rich
that it was very clever and we would start using it everywhere :-)

> Personally I would speak up to them. Scan the libraries for the best
> code Rubiest have to offer in the Ruby idiom.... and spend my time
> explaining the elegance, power and succinctness of it.

Well said!

Yours,

Tom
Ezra Z. (Guest)
on 2007-07-12 05:26
(Received via mailing list)
On Jul 11, 2007, at 6:18 PM, Tom C. wrote:

> Right on.  Today Rich Kilmer showed me some Rails code that Chad
> Fowler
> had written.  It was something like:
>
> some_array.map(&:name)

Careful with that one Tom. It's *a lot* slower then writing out the
block since creating a Proc object has some overhead. Syntactically
it's very nice but performance wise it stinks.


Cheers-
-- Ezra Z.
-- Lead Rails Evangelist
-- removed_email_address@domain.invalid
-- Engine Y., Serious Rails Hosting
-- (866) 518-YARD (9273)
Tom C. (Guest)
on 2007-07-12 05:31
(Received via mailing list)
On Thu, 2007-07-12 at 10:25 +0900, Ezra Z. wrote:
> it's very nice but performance wise it stinks.
Ah, cool, OK, thanks for the heads up!

Yours,

Tom
ara.t.howard (Guest)
on 2007-07-12 06:39
(Received via mailing list)
On Jul 11, 2007, at 7:30 PM, Tom C. wrote:

> Ah, cool, OK, thanks for the heads up!


yeah!  i'm always on the lookout for code that runs slow but reads
great - just my style ;-)

-a
Jeremy H. (Guest)
on 2007-07-12 06:46
(Received via mailing list)
On Thu, Jul 12, 2007 at 11:38:00AM +0900, ara.t.howard wrote:
>
> On Jul 11, 2007, at 7:30 PM, Tom C. wrote:
>
> >Ah, cool, OK, thanks for the heads up!
>
>
> yeah!  i'm always on the lookout for code that runs slow but reads
> great - just my style ;-)

I predict the following code will appear in a codeforpeople example
soon.

    some_ara.map(&:fortytwo)

enjoy,

-jeremy>
Martin DeMello (Guest)
on 2007-07-12 12:05
(Received via mailing list)
On 7/12/07, Jeremy H. <removed_email_address@domain.invalid> wrote:
> I predict the following code will appear in a codeforpeople example
> soon.
>
>     some_ara.map(&:fortytwo)

That's definitely one route towards intestinal fortytwod :)

martin
Robert D. (Guest)
on 2007-07-12 12:32
(Received via mailing list)
On 7/12/07, Jeremy H. <removed_email_address@domain.invalid> wrote:
> I predict the following code will appear in a codeforpeople example
> soon.
>
>     some_ara.map(&:fortytwo)
Got you finally!!!,
It as all your fault, 42 (or :fourtytwo ) is a mystery constant.
That has to change

ANSWER_TO_THE_QUESTION_ABOUT_THE_MEANING_OF_LIFE_THE_UNIVERSE_AND_EVERYTHING
= 42

It might be a good idea to include the ISBN of the "Hitchhikers Guide
through the Galaxy" into the constant too.

Robert
Hal F. (Guest)
on 2007-07-13 02:24
(Received via mailing list)
Martin DeMello wrote:
> On 7/12/07, Jeremy H. <removed_email_address@domain.invalid> wrote:
>> I predict the following code will appear in a codeforpeople example
>> soon.
>>
>>     some_ara.map(&:fortytwo)
>
> That's definitely one route towards intestinal fortytwod :)

That pun was despicable and pernicious, and I am disappointed in you...
for having thought of it before I did.


Hal
Christian N. (Guest)
on 2007-07-21 18:29
(Received via mailing list)
John C. <removed_email_address@domain.invalid> writes:

>
> ARGF.read.scan( %r{GET /ongoing/When/\d\d\dx/(\d\d\d\d/\d\d/\d\d/[^ .]+) }) do |match|
>    puts $1
> end

Kinda late to the party, but I'm amazed noone came up with:

ARGF.grep(%r{GET /ongoing/When/\d\d\dx/(\d\d\d\d/\d\d/\d\d/[^ .]+) }) {
  puts $1
}
This topic is locked and can not be replied to.