Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

"Readability" inflation

1 view
Skip to first unread message

David A. Black

unread,
Oct 28, 2005, 12:10:21 PM10/28/05
to
Hi --

I'm writing this separately from any thread partly because it's a new
topic, and partly because I don't want to appear to be pouncing on any
particular post or person. If anything, I'm pouncing on several of
each :-) But really I'm just puzzling things through.

Over the years and, I think, particularly in recent months, there's
been a ton of suggestions for changing Ruby syntax. The majority
involve adding new semantics through new punctuation. Most of the
rest involve some kind of distillation of existing syntax into
something smaller.

Thus we've see talk of:

lambda -> () {}
ary.every.capitalize
def some_method(:a: :b:,; c::d=:e => f) :-)

and so forth.

Ruby has always "sold itself" to programmers in large part because it
looks so good and, in the eyes of many, many people, successfully
balances expressiveness with clarity. "Readability" is not an
absolute -- but the empirical evidence suggests that a lot of people
experience Ruby as very readable.

I'm certainly convinced that if even a few of the punctuation and/or
condensation things happen to the syntax, Ruby's reputation for
readability will decline rapidly and permanently. I may be wrong, but
my belief and working hypothesis is that the "readability margin" is
quite narrow and easily erased.

That leaves me wondering why all these suggestions keep arising.

I think what's happening is that people who've used Ruby for a while
get used to it, and then they sort of shift their readability
threshold. In other words, if you've seen this:

a.map {|b| b.meth }

for several years, then even though it looked beautiful and concise
and transparent to you at first, it will start to look verbose and
syntactically inefficient. So then you might want to have:

a.every.meth {|b| (or implicit var, or whatever) }

Similarly, if you're used to:

f = lambda {|a,b| ... }

then after a while, you might find that so natural that you feel
"ready" for

f = lambda -> (a,b) { ... }

And yet... if you had encountered the latter version first, you would
never have had the feeling of balance and cleanness that you got (or
at least I did) from the former version.

So I think there's a kind of readability inflation going on: people
who are acclimatized to Ruby start feeling comfortable about going to
the "next" level of line-noise and/or compactness.

I'd like to sound a note of caution about this. I think it has the
potential to disserve Ruby's interests, by moving the language away
from the thing that has been proven to be so attractive.

I've never been big on the idea of adding features to Ruby to make
newcomers "from" other languages feel at home. But here, I am indeed
concerned about newcomers. The point, though, is the same, but from
the other side: just as I do not advocate putting in C++, Java, or
Perl features to sweeten the pot for people considering Ruby, so I do
not advocate *removing* what I see as *Ruby* features (even at a
fairly fine-grained level). I think either of these things can alter
the balance.

No, I do not think Ruby should stagnate and be dead. If 1.8.3 were
the last version, it would not stagnate and be dead, because people
*use* it and do things with it. The fact that, for me, that counts as
non-stagnation does perhaps mean that I am quite conservative about
language change. I don't think the language needs to change, unless
something is truly broken or missing.


David

--
David A. Black
dbl...@wobblini.net


James Britt

unread,
Oct 28, 2005, 12:29:26 PM10/28/05
to
David A. Black wrote:
> That leaves me wondering why all these suggestions keep arising.

My Instant Theory:

Early users (circa release of Programming Ruby, 1st edition , or
earlier) of Ruby were language geeks, the sort of people who actively
scan the horizon for interesting programming languages. They are
already accustomed to a variety of syntax, so readability is a fairly
fluid concept.

Once Ruby started getting more attention it attracted a wider audience,
including many with less broad language experience and a different idea
of readability.

I haven't gone back to see who has been advocating or supporting what
change or additions, so I do not know if this is even remotely accurate.
But there are certain topics that have attained permathread status,
and syntax munging is becoming one of them as Ruby attracts more users.

I also suspect that on this matter Ruby is a "victim" of its own
success. It makes it far easier to create DSLs and more-readable code,
and may have raised users' expectations about such.

(In fact, when I explain Ruby to people, among the first things I tell
them about is method_missing and send, and how, with those two things,
you can write almost anything like you like and get Ruby to do something
useful.)

James

--

http://www.ruby-doc.org - The Ruby Documentation Site
http://www.rubyxml.com - News, Articles, and Listings for Ruby & XML
http://www.rubystuff.com - The Ruby Store for Ruby Stuff
http://www.jamesbritt.com - Playing with Better Toys


Daniel Schierbeck

unread,
Oct 28, 2005, 12:30:50 PM10/28/05
to

I agree with you that many suggestions have arisen, but many of them are
simply a way to think outside the box (I hate myself for using that
phrase, but I can't think of anything better.)

I think one of the many great things about Ruby is that each new
addition is carefully considered; does it correspond to the Ruby Way? It
it clear to me that `collection.every.method' does not. Neither do I
think the `->' lambda syntax does. But in the case of named arguments,
the great amount of alternative syntax propositions is a huge advantage
- they may not look anything like what we'll end up with, but they've
been considered, and maybe parts of them can be melted into the final
syntax.

One thing I would like to add is that we really ought to reconsider the
heavy use of symbols, especially arrows. This just doesn't look good:

def foo(a =>, b =>, c =>)
obj = -> (a, b = 1){ block }

And it's not clear to an outsider what it means. Use English words when
possible, and don't abbreviate too much.


Cheers,
Daniel

Trans

unread,
Oct 28, 2005, 1:03:20 PM10/28/05
to

Daniel Schierbeck wrote:

> I agree with you that many suggestions have arisen, but many of them are
> simply a way to think outside the box (I hate myself for using that
> phrase, but I can't think of anything better.)

Ruby the Can-Do langauge :-)

> I think one of the many great things about Ruby is that each new
> addition is carefully considered; does it correspond to the Ruby Way? It
> it clear to me that `collection.every.method' does not. Neither do I
> think the `->' lambda syntax does.

The { |x| ... } syntax never turned me on about Ruby. In fact, my
first thought what why not do(x) ... end. But it was the *utility* of
blocks that made the difference.

> But in the case of named arguments,
> the great amount of alternative syntax propositions is a huge advantage
> - they may not look anything like what we'll end up with, but they've
> been considered, and maybe parts of them can be melted into the final
> syntax.
>
> One thing I would like to add is that we really ought to reconsider the
> heavy use of symbols, especially arrows. This just doesn't look good:
>
> def foo(a =>, b =>, c =>)
> obj = -> (a, b = 1){ block }

Does

def foo(a:, b:, c:)

look any better? Not to me. To me it looks worse b/c of what :a and
a::b are.

> And it's not clear to an outsider what it means. Use English words when
> possible, and don't abbreviate too much.

Case in point, what's the english equiv of #===. I'd really like to
have one.

T.

Hugh Sasse

unread,
Oct 28, 2005, 1:04:13 PM10/28/05
to
On Sat, 29 Oct 2005, David A. Black wrote:

> Hi --
>
> [...] But really I'm just puzzling things through.


>
> Over the years and, I think, particularly in recent months, there's
> been a ton of suggestions for changing Ruby syntax. The majority
> involve adding new semantics through new punctuation. Most of the

[...]


> Ruby has always "sold itself" to programmers in large part because it
> looks so good and, in the eyes of many, many people, successfully
> balances expressiveness with clarity. "Readability" is not an
> absolute -- but the empirical evidence suggests that a lot of people
> experience Ruby as very readable.

Agreed.


>
> I'm certainly convinced that if even a few of the punctuation and/or
> condensation things happen to the syntax, Ruby's reputation for
> readability will decline rapidly and permanently. I may be wrong, but
> my belief and working hypothesis is that the "readability margin" is
> quite narrow and easily erased.

And it doesn't take much. I mean, people often object to
pluralization in Perl by means of @collection and
$collection[member]

>
> That leaves me wondering why all these suggestions keep arising.
>
> I think what's happening is that people who've used Ruby for a while
> get used to it, and then they sort of shift their readability
> threshold. In other words, if you've seen this:
>
> a.map {|b| b.meth }
>
> for several years, then even though it looked beautiful and concise
> and transparent to you at first, it will start to look verbose and
> syntactically inefficient. So then you might want to

[Compress the code by moving to a higher base :-)]


>
> And yet... if you had encountered the latter version first, you would
> never have had the feeling of balance and cleanness that you got (or
> at least I did) from the former version.
>
> So I think there's a kind of readability inflation going on: people
> who are acclimatized to Ruby start feeling comfortable about going to
> the "next" level of line-noise and/or compactness.
>

So what is so bad about introducing more keywords? Yes, they can
stamp on existing variables, but what if, just for parameter passing
we introduced "named"

# A factory method
def create_pizza(t=[:pepperoni, :ham] named :toppings,
c=[:thin] named :crust_thickness)
imaginate(:pizza_factory).make_me(c,t) # [1]
end

nice short vars for codeing, then

# My toppings for today
mt=[:ham, :cheese, :pineapple]
pizza = create_pizza(mt named :toppings)

There's no ambiguity with past forms, and the syntax is still fairly
English. (On the basis that the rest of Ruby is fairly English: I'm
not suggesting people should fit to my linguistic bias.)

Ruby has very few keywords now. I know this might upset things that
talk to name daemons, because they already have the named string
inside the code, but if it improves readability it might be a price
worth paying.

Hugh
[1]
http://www.toolshed.com/blog/articles/2004/09/01/imaginate-the-article


why the lucky stiff

unread,
Oct 28, 2005, 1:09:38 PM10/28/05
to
David A. Black wrote:

> Over the years and, I think, particularly in recent months, there's
> been a ton of suggestions for changing Ruby syntax. The majority
> involve adding new semantics through new punctuation. Most of the
> rest involve some kind of distillation of existing syntax into
> something smaller.

So, is your compaint about the suggestions? Or about Matz' own recent
tinkerings with the language? Because although your overall comments
lean toward the first, your specific examples point towards changes Matz
has messed with. Discussions he has encouraged.

I think suggestions from the audience are harmless. Matz rarely gives
credence to these and even accepted RCRs go untouched for upwards of 5
years. Anyway, I'd hate to silence the crowd, these are our people.
These are casual discussions, do they really have the gravity you think
they have?

And the syntax choices that Matz plays with often get shelved. He's
played with the local block variables syntax since I can remember. I
like that Ruby development is slow. He does wait for our comfort.

_why


Daniel Schierbeck

unread,
Oct 28, 2005, 1:14:18 PM10/28/05
to
Trans wrote:

> Case in point, what's the english equiv of #===. I'd really like to
> have one.

"kind of equal to"? :)

Trans

unread,
Oct 28, 2005, 1:14:15 PM10/28/05
to
Or 'as'?

# A factory method
def create_pizza(t=[:pepperoni, :ham] as :toppings,
c=[:thin] as :crust_thickness)


imaginate(:pizza_factory).make_me(c,t) # [1]
end

nice short vars for codeing, then

# My toppings for today
mt=[:ham, :cheese, :pineapple]

pizza = create_pizza(mt as :toppings)

T.

Daniel Schierbeck

unread,
Oct 28, 2005, 1:24:15 PM10/28/05
to
Hugh Sasse wrote:
> # A factory method
> def create_pizza(t=[:pepperoni, :ham] named :toppings,
> c=[:thin] named :crust_thickness)
> imaginate(:pizza_factory).make_me(c,t) # [1]
> end
>
> nice short vars for codeing, then
>
> # My toppings for today
> mt=[:ham, :cheese, :pineapple]
> pizza = create_pizza(mt named :toppings)
>

Looks interesting... I still think this is better, though

class Pizza
def initialize(named toppings, named crust_thickness = :thin)
@toppings = toppings
@crust_thickness = crust_thickness
end
end

pizza = Pizza.new :crust_thickness => :really_thick,
:toppings => [:pepperoni, :ham]


Cheers,
Daniel

James Britt

unread,
Oct 28, 2005, 1:38:21 PM10/28/05
to
why the lucky stiff wrote:
> David A. Black wrote:
>
>> Over the years and, I think, particularly in recent months, there's
>> been a ton of suggestions for changing Ruby syntax. The majority
>> involve adding new semantics through new punctuation. Most of the
>> rest involve some kind of distillation of existing syntax into
>> something smaller.
>
>
> So, is your compaint about the suggestions? Or about Matz' own recent
> tinkerings with the language? Because although your overall comments
> lean toward the first, your specific examples point towards changes Matz
> has messed with. Discussions he has encouraged.
>
> I think suggestions from the audience are harmless. Matz rarely gives
> credence to these and even accepted RCRs go untouched for upwards of 5
> years. Anyway, I'd hate to silence the crowd, these are our people.
> These are casual discussions, do they really have the gravity you think
> they have?

I agree that suggestions and discussion are important, and, with Matz
calling the shots, there is little risk of any sort of Ruby Community
Process goofiness.

Also do not believe that David is in any way trying to silence anyone.
He's offering a voice to a particular point of view, not trying to
discourage discussion.

Joe Van Dyk

unread,
Oct 28, 2005, 1:46:53 PM10/28/05
to
On 10/28/05, David A. Black <dbl...@wobblini.net> wrote:
> Hi --
<snip>

> No, I do not think Ruby should stagnate and be dead. If 1.8.3 were
> the last version, it would not stagnate and be dead, because people
> *use* it and do things with it. The fact that, for me, that counts as
> non-stagnation does perhaps mean that I am quite conservative about
> language change. I don't think the language needs to change, unless
> something is truly broken or missing.

I love the current Ruby syntax.

If 2.0 just contained a faster Ruby, and kept the same syntax, I'd be overjoyed.


Pete

unread,
Oct 28, 2005, 1:55:30 PM10/28/05
to
> pizza = Pizza.new :crust_thickness => :really_thick,
> :toppings => [:pepperoni, :ham]

looks like a hash, if you ask me...

so what the extra keyword for ??

Yukihiro Matsumoto

unread,
Oct 28, 2005, 1:57:30 PM10/28/05
to
Hi,

In message "Re: "Readability" inflation"


on Sat, 29 Oct 2005 02:09:38 +0900, why the lucky stiff <ruby...@whytheluckystiff.net> writes:

|I like that Ruby development is slow. He does wait for our comfort.

Thank you. In fact, I don't like Ruby development is slow. But
unfortunately, I am not smart enough besides being lazy.

matz.


Ron M

unread,
Oct 28, 2005, 2:08:55 PM10/28/05
to
David A. Black wrote:
>
> ...a ton of suggestions for changing Ruby syntax....

>
> That leaves me wondering why all these suggestions keep arising.
>
> I think what's happening is that people who've used Ruby for a while
> get used to it, and then they sort of shift their readability

I'm pretty sure it's the opposite of what you think.

In the past, Ruby appealed to people who were fluent in Perl,
ML, Lisp, Smalltalk, the K language, and a bunch of other
languages with truly horrible readability problems.

Judged against that field, Ruby is beautiful.

Today Ruby is attracting people who may have more experience
in C, VHDL and Fortran (me) or Visual Basic (like marketing
departments for UI prototypes).

> In other words, if you've seen this:
> a.map {|b| b.meth }
>
> for several years, then even though it looked beautiful and concise
> and transparent to you at first, it will start to look verbose and
> syntactically inefficient.

For us people with less broad exposure to esoteric languages, this:
c.map{|b| b.meth}
really isn't as intuitive as you'd think.

If I were to ask people around the office, I'd expect guesses
like these for "c.map{|b| b.meth}":

? It defines a function with the funny name "c.map" that takes
no arguments; that pipes the variable b it's input to b and
then to b.meth (like MSFT's Monad shell's pipe operator)?

? It uses "c" to return a hashtable ("map" sounds like HashMap
in Java) with one element with name "b" and value "b.meth"?

? It takes the locations in the object "c" and plots
the meth labs on the google-map "b"?

In defense of "{|x| ...}", I really like it over C-style for
loops. But readability for new users certainly isn't one of
it's strengths.

Consider Microsoft's Monad's

get-childitem | sort-object extension | foreach { $_.filename}

vs Ruby's

get-childitem.sort_by{|child| child.extension}.map{|child| child.filename}

Msh makes Ruby's 4-time repetition of "child" look quite tedious,
without adding any readability that I can see over the Microsoft version.


> So I think there's a kind of readability inflation going on: people
> who are acclimatized to Ruby start feeling comfortable about going to
> the "next" level of line-noise and/or compactness.

I'd reiterate that I think it's the opposite. Newbies without
the theoretical CS backgrounds are complaining about the parts
that they find confusing or tedious.

The one really great part about Ruby, though; is that almost any
time someone complains, someone else posts some magical addition
to some module that gives the complainer almost exactly what he
wanted -- so I'd tend to agree the language shouldn't need many
of these changes.

But I think what's driving the increased requests are mostly
things that people find hard to read, rather than clean
things that people are getting bored with.

Joel VanderWerf

unread,
Oct 28, 2005, 2:26:16 PM10/28/05
to

"matches" ? or "case-matches", to be explicit?

--
vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407


Brian Schröder

unread,
Oct 28, 2005, 2:38:10 PM10/28/05
to
On 28/10/05, David A. Black <dbl...@wobblini.net> wrote:
> Hi --
>
> [snip concerns]

I totally agree with you. Thanks for summing it up so nicely.

best regards,

Brian

>
> David
>
> --
> David A. Black
> dbl...@wobblini.net
>
>


--
http://ruby.brian-schroeder.de/

Stringed instrument chords: http://chordlist.brian-schroeder.de/


Karl von Laudermann

unread,
Oct 28, 2005, 2:56:06 PM10/28/05
to
Trans wrote:
> Does
>
> def foo(a:, b:, c:)
>
> look any better? Not to me. To me it looks worse b/c of what :a and
> a::b are.

I admit I haven't read all of the posts in the named parameter threads,
so I apologize if my question is answered there, but why does there
even need to be a new syntax for declaring methods with named
parameters at all? My first thought as to what "adding named
parameters to Ruby" means is that *any* method can be called using
named parameters or not. I.e., given a method:

def foo(a, b)
a + b
end

It can be called in any of these ways:

foo(5, 3)
foo(a=5, b=3)
foo(b=3, a=5)

Why can't this be made to work?

David A. Black

unread,
Oct 28, 2005, 3:42:02 PM10/28/05
to
Hi --

On Sat, 29 Oct 2005, why the lucky stiff wrote:

> I think suggestions from the audience are harmless. Matz rarely gives
> credence to these and even accepted RCRs go untouched for upwards of 5 years.
> Anyway, I'd hate to silence the crowd, these are our people. These are
> casual discussions, do they really have the gravity you think they have?

I can't say because I don't know what gravity you think I think they
have :-) I don't really want to get into the meta-meta-... thing,
though. It's just a bunch of observations and comments -- "from the
audience" and hopefully harmless, as you say.

Christophe Grandsire

unread,
Oct 28, 2005, 3:49:41 PM10/28/05
to
Selon Karl von Laudermann :

>
> I admit I haven't read all of the posts in the named parameter threads,
> so I apologize if my question is answered there, but why does there
> even need to be a new syntax for declaring methods with named
> parameters at all? My first thought as to what "adding named
> parameters to Ruby" means is that *any* method can be called using
> named parameters or not. I.e., given a method:
>
> def foo(a, b)
> a + b
> end
>
> It can be called in any of these ways:
>
> foo(5, 3)
> foo(a=5, b=3)
> foo(b=3, a=5)
>
> Why can't this be made to work?
>

Because "a=5" is an expression that returns a value, and is thus allowed
as an argument. That would create an ambiguity between "a=5" as an
expression whose return value is used as argument and "a=5" as a named
argument receiving a value.

Anyway, quite a few people, including myself, don't like the idea of all
arguments being optionally named arguments. It obliges method arguments
to be part of the method interface, and that should only happen *when
the developer explicitly wants it that way.*

I know it's a feature of Python, and maybe it hasn't brought anything
bad to it. However, it's one of the reasons why I quit learning the
language. It wasn't the only syntax feature I disliked, but it didn't
balance things out either.
--
Christophe Grandsire.

http://rainbow.conlang.free.fr

You need a straight mind to invent a twisted conlang.


Brian Schröder

unread,
Oct 28, 2005, 4:21:32 PM10/28/05
to
On 28/10/05, Brian Schröder <ruby....@gmail.com> wrote:
> On 28/10/05, David A. Black <dbl...@wobblini.net> wrote:
> > Hi --
> >
> > [snip concerns]
>
> I totally agree with you. Thanks for summing it up so nicely.
>
> best regards,
>
> Brian

After reading the other posts I wanted to make clear that I understood
davids comment as a reminder not too be too eager with change
proposals, but to weight them on a beauty scale. I did not understood
it as a discouragement for proposals. I think it is a good thing, that
not only matz stands against the tide, but that there are other
conservative people as well.

Nikolai Weibull

unread,
Oct 28, 2005, 5:10:12 PM10/28/05
to
Joe Van Dyk wrote:

I agree. If all Ruby 2.0 brought was a VM I’d be happy. That, and
M17N...and perhaps keyword arguments ;-D,
nikolai

--
Nikolai Weibull: now available free of charge at http://bitwi.se/!
Born in Chicago, IL USA; currently residing in Gothenburg, Sweden.
main(){printf(&linux["\021%six\012\0"],(linux)["have"]+"fun"-97);}


gwt...@mac.com

unread,
Oct 28, 2005, 6:09:56 PM10/28/05
to

On Oct 28, 2005, at 1:07 PM, Trans wrote:
> Case in point, what's the english equiv of #===. I'd really like to
> have one.
>

How about "contains" or "includes"?

String contains "abc"
0..10 contains 5
1,2,3,4 contains 3
/^[a-z]*$/ includes "apple"

It would be nice if Array#=== was aliased to Array#include? So that

somearray === someval

would check for membership. You can "cheat" a bit with the case
statement as follows:

a = [1,2,3,4]
b = 3

case b
when *a
puts "match"
else
puts "no match"
end

This works with any object that responds to to_a but of course
requires that an array be constructed instead of a more efficient
lookup into the object that could be done via a
customized === method.

See my recent posting about this (ruby-talk:162999)


Joel VanderWerf

unread,
Oct 28, 2005, 6:36:10 PM10/28/05
to
Nikolai Weibull wrote:
> Joe Van Dyk wrote:
>
>
>>On 10/28/05, David A. Black <dbl...@wobblini.net> wrote:
>
>
>>>No, I do not think Ruby should stagnate and be dead. If 1.8.3 were
>>>the last version, it would not stagnate and be dead, because people
>>>*use* it and do things with it. The fact that, for me, that counts
>>>as non-stagnation does perhaps mean that I am quite conservative
>>>about language change. I don't think the language needs to change,
>>>unless something is truly broken or missing.
>
>
>>I love the current Ruby syntax.
>>
>>If 2.0 just contained a faster Ruby, and kept the same syntax, I'd be
>>overjoyed.
>
>
> I agree. If all Ruby 2.0 brought was a VM I’d be happy. That, and
> M17N...and perhaps keyword arguments ;-D,
> nikolai
>

And I'd be happy with just native threads. Nothing else.

I find it interesting that before 1.8 was released, I was frequently
installing the latest 1.7.x because it had some new feature I needed. I
kept that up for a while with 1.9.x just out of habit, but didn't really
need anything that was in 1.9 but not 1.8. I'm very happy with 1.8.2, in
fact.

Daniel Schierbeck

unread,
Oct 28, 2005, 7:45:07 PM10/28/05
to
Pete wrote:
>> pizza = Pizza.new :crust_thickness => :really_thick,
>> :toppings => [:pepperoni, :ham]
>
>
> looks like a hash, if you ask me...
>
> so what the extra keyword for ??
>

In my example, the value :really_thick will be assigned to the method's
local variable `crust_thickness', and `[:pepperoni, :ham]' to
`toppings'. Otherwise, you would have to do the following:

def initialize(opts)
opts[:crust_thickness] ||= :thin
@toppings = opts[:toppings]
@crust_thickness = opts[:crust_thickness]
end

Which of course would be even more confusing if there were a great many
keywords.

gabriele renzi

unread,
Oct 28, 2005, 7:45:18 PM10/28/05
to
Trans ha scritto:

> Daniel Schierbeck wrote:
>
>
>>I agree with you that many suggestions have arisen, but many of them are
>>simply a way to think outside the box (I hate myself for using that
>>phrase, but I can't think of anything better.)
>
>
> Ruby the Can-Do langauge :-)
>
>
>>I think one of the many great things about Ruby is that each new
>>addition is carefully considered; does it correspond to the Ruby Way? It
>>it clear to me that `collection.every.method' does not. Neither do I
>>think the `->' lambda syntax does.
>
>
> The { |x| ... } syntax never turned me on about Ruby. In fact, my
> first thought what why not do(x) ... end. But it was the *utility* of
> blocks that made the difference.
>

I agree with David in the general points, but for what is worth, I agree
with TRANS on this, I always thought {|x|...} was unrubyish, even when I
did'nt had a grasp of what rubyish could mean (and probably I still don't)

gabriele renzi

unread,
Oct 28, 2005, 7:47:29 PM10/28/05
to
Nikolai Weibull ha scritto:

>>I love the current Ruby syntax.
>>
>>If 2.0 just contained a faster Ruby, and kept the same syntax, I'd be
>>overjoyed.
>
>
> I agree. If all Ruby 2.0 brought was a VM I’d be happy. That, and
> M17N...and perhaps keyword arguments ;-D,
> nikolai

+1 (ok, I still would like multi methods, but nobody loves them..)

ES

unread,
Oct 29, 2005, 12:30:40 AM10/29/05
to
> Hi --
>
> <5|\|1* |24|\|+>
>

+ |-| 3 |2 3 15 4 |. 5 0 1 |_| + 3 1 _v |\| 0 + |-| 1 |\| 9

|/|/ |2 0 |\| 9 4 |. 0 |_| + 4 |= 3 |/|/ 3 >< + |2 4

5 _v |\/| |. 0 1 5 1 |\| |2 |_| |. _v

> David

3

Robert Klemme

unread,
Oct 29, 2005, 5:40:03 AM10/29/05
to
Ron M <rm_r...@cheapcomplexdevices.com> wrote:

> For us people with less broad exposure to esoteric languages, this:
> c.map{|b| b.meth}
> really isn't as intuitive as you'd think.
>
> If I were to ask people around the office, I'd expect guesses
> like these for "c.map{|b| b.meth}":
>
> ? It defines a function with the funny name "c.map" that takes
> no arguments; that pipes the variable b it's input to b and
> then to b.meth (like MSFT's Monad shell's pipe operator)?
>
> ? It uses "c" to return a hashtable ("map" sounds like HashMap
> in Java) with one element with name "b" and value "b.meth"?
>
> ? It takes the locations in the object "c" and plots
> the meth labs on the google-map "b"?

Well, *did* you actually ask? What about showing your colleagues a short
Ruby program that contains this like of code and collecting their
interpretation? That would certainly be interesting to hear. IMHO context
helps a great deal in understanding previously unknown concepts.

> In defense of "{|x| ...}", I really like it over C-style for
> loops. But readability for new users certainly isn't one of
> it's strengths.
>
>
>
> Consider Microsoft's Monad's
>
> get-childitem | sort-object extension | foreach { $_.filename}
>
> vs Ruby's
>
> get-childitem.sort_by{|child| child.extension}.map{|child|
> child.filename}
> Msh makes Ruby's 4-time repetition of "child" look quite tedious,
> without adding any readability that I can see over the Microsoft
> version.

Well, it depends: your line full of pipe symbols looks like a line from a
bourne shell script to me... :-) I guess you really need some kind of basic
knowledge in either case.

>> So I think there's a kind of readability inflation going on: people
>> who are acclimatized to Ruby start feeling comfortable about going to
>> the "next" level of line-noise and/or compactness.
>
> I'd reiterate that I think it's the opposite. Newbies without
> the theoretical CS backgrounds are complaining about the parts
> that they find confusing or tedious.

It interesting to see how people make different observations: to me it looks
as if I more often read "wow, Ruby is so cool and I can even read it
although I'm a newby".

> The one really great part about Ruby, though; is that almost any
> time someone complains, someone else posts some magical addition
> to some module that gives the complainer almost exactly what he
> wanted -- so I'd tend to agree the language shouldn't need many
> of these changes.

Agreed.

> But I think what's driving the increased requests are mostly
> things that people find hard to read, rather than clean
> things that people are getting bored with.

Maybe it's not exactly boredom but the human drive to constantly improve
things which is especially strong in engineers and similar folks. While
this force is often good there are many places where too much degrades
things (I'm thinking of the over engineered cars of some German
manufacturers...). That hard part is to identify the optimum and stick with
that. Also, the optimum may change over time, as requirements change.

A general advantage of conservatism is that it doesn't create too many
different variants for the same or similar concept thus limiting the overall
size of the playing field. And this in turn helps people a lot to get
started. Just compare learning curves for natural languages with comlex
rules and syntax with those of languages with only few principles applied
consequently.

Kind regards

robert

Martin DeMello

unread,
Oct 29, 2005, 9:16:44 AM10/29/05
to
David A. Black <dbl...@wobblini.net> wrote:
>
> I think what's happening is that people who've used Ruby for a while
> get used to it, and then they sort of shift their readability
> threshold. In other words, if you've seen this:

>
> a.map {|b| b.meth }
>
> for several years, then even though it looked beautiful and concise
> and transparent to you at first, it will start to look verbose and
> syntactically inefficient. So then you might want to have:

I usually come around to agreeing with you that so-and-so change adds
more line noise than is worth it, but this particular one I've disliked
right from the beginning. It's not just the visual clutter, it's the
conceptual overhead of introducing a new variable merely because ruby
has to attach a method to something. Note the progression from

ary.sort {|a,b| a.meth <=> b.meth}
ary.sort_by {|a| a.meth}
ary.sort_by :meth

The |a| adds absolutely nothing to the readability of the code. It's a
case of cluttering the simple case in order to support the complex one,
and ruby usually manages to do a pretty good job of keeping machinery
out of your way until you need it.

martin

Trans

unread,
Oct 29, 2005, 10:07:49 AM10/29/05
to

Martin DeMello wrote:
> David A. Black <dbl...@wobblini.net> wrote:
> >
> > I think what's happening is that people who've used Ruby for a while
> > get used to it, and then they sort of shift their readability
> > threshold. In other words, if you've seen this:
> >
> > a.map {|b| b.meth }
> >
> > for several years, then even though it looked beautiful and concise
> > and transparent to you at first, it will start to look verbose and
> > syntactically inefficient. So then you might want to have:
>
> I usually come around to agreeing with you that so-and-so change adds
> more line noise than is worth it, but this particular one I've disliked
> right from the beginning. It's not just the visual clutter, it's the
> conceptual overhead of introducing a new variable merely because ruby
> has to attach a method to something. Note the progression from
>
> ary.sort {|a,b| a.meth <=> b.meth}
> ary.sort_by {|a| a.meth}
> ary.sort_by :meth

Shall I be so bold:

ary.sort_by.meth

;)

T.

Brian Schröder

unread,
Oct 29, 2005, 11:34:30 AM10/29/05
to

If you are so bold, I have to chime in again to say that

ary.sort_by :meth

reads a lot better than

ary.sort_by.meth

because we don't do method chaining here.

Sorry, could not resist. ;-)

best regards,

Brian

Trans

unread,
Oct 29, 2005, 11:50:03 AM10/29/05
to

Brian Schröder wrote:
> If you are so bold, I have to chime in again to say that
>
> ary.sort_by :meth
>
> reads a lot better than
>
> ary.sort_by.meth
>
> because we don't do method chaining here.
>
> Sorry, could not resist. ;-)

Ahhhhh... but can you do:

ary.sort_by.meth(foo, bar, wack!)

T.

Brian Schröder

unread,
Oct 29, 2005, 12:00:52 PM10/29/05
to
On 29/10/05, Trans <tran...@gmail.com> wrote:
>

And what does that mean and how often do I need it?

David A. Black

unread,
Oct 29, 2005, 12:04:57 PM10/29/05
to
This message is in MIME format. The first part should be readable text,
while the remaining parts are likely unreadable without MIME-aware tools.

Stefan Lang

unread,
Oct 29, 2005, 12:32:43 PM10/29/05
to
On Saturday 29 October 2005 18:00, Brian Schröder wrote:
> On 29/10/05, Trans <tran...@gmail.com> wrote:
> > Brian Schröder wrote:
> > > If you are so bold, I have to chime in again to say that
> > >
> > > ary.sort_by :meth
> > >
> > > reads a lot better than
> > >
> > > ary.sort_by.meth
> > >
> > > because we don't do method chaining here.
> > >
> > > Sorry, could not resist. ;-)
> >
> > Ahhhhh... but can you do:
> >
> > ary.sort_by.meth(foo, bar, wack!)
> >
> > T.
>
> And what does that mean and how often do I need it?

Perhaps he means something like:

% cat sort_by.rb
module Enumerable
alias _core_sort_by sort_by
def sort_by(*args, &block)
if args.empty?
_core_sort_by(&block)
else
_core_sort_by { |a| a.__send__(*args, &block) }
end
end
end

if $0 == __FILE__
class Factor
attr_reader :number
def initialize(number)
@number = number
end
def apply_to(other_number)
@number * other_number
end
end
list = [Factor.new(-2), Factor.new(3)]
p list.sort_by(:number)
p list.sort_by(:apply_to, -1)
end
% ruby sort_by.rb
[#<Factor:0x401c0520 @number=-2>, #<Factor:0x401c050c @number=3>]
[#<Factor:0x401c050c @number=3>, #<Factor:0x401c0520 @number=-2>]

--
Stefan


Dominik Bathon

unread,
Oct 29, 2005, 1:49:51 PM10/29/05
to

So, what we really need is the implicit block variable, because it can do
all that ;-)

ary.sort_by { it.meth }

ary.sort_by { it.meth(foo, bar, wack!) }

and even:

ary.sort_by { some_hash[it] }


Dominik

Brian Schröder

unread,
Oct 29, 2005, 2:02:51 PM10/29/05
to

What is so bad about

ary.sort_by { | it | it.meth(foo, bar, wack!) }

Then you can even make your sourcecode readable by putting information
into the it

playlist.sort_by { | track | track.meth(foo, bar, wack!) }
instead of
playlist.sort_by { it.meth(foo, bar, wack!) }

where it is unclear what the it is.

David A. Black

unread,
Oct 29, 2005, 2:15:09 PM10/29/05
to

Daniel Schierbeck

unread,
Oct 29, 2005, 2:17:10 PM10/29/05
to

I agree. `it' would seem to refer to the playlist itself, not the
playlist item. This would be good too:

playlist.sort_by :track_length


Cheers,
Daniel

Trans

unread,
Oct 29, 2005, 3:03:58 PM10/29/05
to

Dominik Bathon wrote:

> So, what we really need is the implicit block variable, because it can do
> all that ;-)
>
> ary.sort_by { it.meth }
>
> ary.sort_by { it.meth(foo, bar, wack!) }
>
> and even:
>
> ary.sort_by { some_hash[it] }

Uh oh...

ary.whatever_by { |it1, it2| ... }

Now we're one step away from the from "ducking" it all:

ary.whatever_by { %1.foo ... %2.bar }

T.

Dominik Bathon

unread,
Oct 29, 2005, 3:40:39 PM10/29/05
to
On Sat, 29 Oct 2005 20:02:51 +0200, Brian Schröder <ruby....@gmail.com>
wrote:

> What is so bad about
>
> ary.sort_by { | it | it.meth(foo, bar, wack!) }

Nothing, it is just more typing...

> Then you can even make your sourcecode readable by putting information
> into the it
>
> playlist.sort_by { | track | track.meth(foo, bar, wack!) }
> instead of
> playlist.sort_by { it.meth(foo, bar, wack!) }
>
> where it is unclear what the it is.

I know that it is not very clear, you have to get the meaning from the
context.
The implicit version would just be for short blocks, where the meaning is
obvious from the context.
I don't want to remove the named block parameters, just offer an
alternative.


Dominik


Dominik Bathon

unread,
Oct 29, 2005, 3:50:57 PM10/29/05
to

Maybe

ary.whatever_by { it[0].foo ... it[1].bar }

because block variables use multiple assignment anyway.

But I would use the implicit version only for really simple things. If
there are multiple block variables, then please name them.

Dominik


Ryan Leavengood

unread,
Oct 29, 2005, 9:36:50 PM10/29/05
to
On 10/28/05, David A. Black wrote:
>
> I'd like to sound a note of caution about this. I think it has the
> potential to disserve Ruby's interests, by moving the language away
> from the thing that has been proven to be so attractive.

I agree strongly with this, and the rest of David's comments. In fact
I'll go so far as to take the probably unpopular stance that most of
these "syntax discussions" are a big waste of time. Seriously, they
are like giant distributed committee meetings that spend days talking
and arguing and yelling to produce nothing valuable at the end. The
"named arguments" and "block syntax" related threads were just
ridiculous. There have been many others over the years.

Now matz and the other old-timers have never been ones to censure or
otherwise impede discussion on this mailing list, and I certainly
wouldn't do that either. But consider all the time people spend
writing kilobytes of text on this mailing list in fairly frivolous
discussions, and add to that all the time it takes other people to
read those kilobytes. Now what if that time were spent doing something
else? Like, say, coding new Ruby libraries! Or, even more crazy,
helping on YARV!

See, I'm a pragmatist (after all, it was "The Pragmatic Programmer"
that eventually brought me into the Ruby fray back in 2001.) I think
actions speak louder than words, and that the most useful discussions
on this mailing list involve someone posing a problem, and others
solving it in interesting and elegant ways.

So I don't see much value in these syntax discussion threads which
stretch into 100s of messages, especially when in the end, nothing
really valuable comes from them. Well, I'm probably being a little
harsh here...I imagine matz considers some of the ideas people make
and maybe those are things he hasn't thought of. But overall I think a
lot of time is wasted.

So, anyhow, before you decide that this really cool new syntax should
be put into Ruby, or before you decide to add your ever so important
opinion into these infinite threads, stop. Before posting, consider
how else your time could be spent.

Just something to thing about...

Regards,
Ryan


Trans

unread,
Oct 29, 2005, 10:30:31 PM10/29/05
to
Ryan,

All work and no play? :-(

T.

Ryan Leavengood

unread,
Oct 29, 2005, 10:43:49 PM10/29/05
to
On 10/29/05, Trans <tran...@gmail.com> wrote:
> Ryan,
>
> All work and no play? :-(

Hehehe, I'm just saying that I think these discussions get out of hand
occasionally.

I do take part in some Ruby Quizzes which I find both fun and useful.
The recent thread about finding non-unique array elements got pretty
long, but in the end we all learned quite a bit. Work and play can
sometimes be combined.

Ryan


Robert Klemme

unread,
Oct 30, 2005, 7:15:55 AM10/30/05
to

I think it'd rather be

ary.sort_by(:foo, :bar, :wack!)

This is definitely superior to chaining methods. For one, because chaining
causes the wrong perception that the chain is executed once but in fact a
proxy object is created behind the scenes that applies the rest of the chain
to every instance. And also the proxy object might be slower than the
direct execution of the chain. Just because it's possible it doesn't mean
it's better or more readable. My 0.02 EUR...

Kind regards

robert

Robert Klemme

unread,
Oct 30, 2005, 7:26:11 AM10/30/05
to
Ryan Leavengood <leave...@gmail.com> wrote:
> On 10/29/05, Trans <tran...@gmail.com> wrote:
>> Ryan,
>>
>> All work and no play? :-(
>
> Hehehe, I'm just saying that I think these discussions get out of hand
> occasionally.

I think this is nothing to worry about. After all, I'm a big fan of
democracy and still think it's better than other forms of government (please
don't take the discussion down *that* road too far). But the main point
here is that it's everybody's own decision whether he / she participates in
these threads. With a little experience you can easily detect those threads
and ignore them if you feel like it. And since you're using gmail you don't
have to worry about space and or bandwidth either, do you? :-)

> I do take part in some Ruby Quizzes which I find both fun and useful.
> The recent thread about finding non-unique array elements got pretty
> long, but in the end we all learned quite a bit. Work and play can
> sometimes be combined.

Definitely.

To sum up: I'm totally with David and I think we should take his statement
for what it is: a warning notice, a reminder to maybe more often try to keep
some focus but not more - especially not any form of censorship.

Kind regards

robert

Trans

unread,
Oct 30, 2005, 8:38:08 AM10/30/05
to

> ary.sort_by(:foo, :bar, :wack!)

Oh, those weren't method calls, there were parameters to #meth --I know
Enumerable doesn't support args, but I have a module EnumerableArgs
that does (And let me tell you that was a pain --I had to essentially
rewrite Enumerable from scratch!)

T.

Robert Klemme

unread,
Oct 30, 2005, 10:46:01 AM10/30/05
to
Trans <tran...@gmail.com> wrote:
>> ary.sort_by(:foo, :bar, :wack!)
>
> Oh, those weren't method calls, there were parameters to #meth --I

Then I guess this makes a good indication how cryptic that was... :-)

> know Enumerable doesn't support args, but I have a module
> EnumerableArgs that does (And let me tell you that was a pain --I had
> to essentially rewrite Enumerable from scratch!)

What do you mean by "Enumerable doesn't support args"? It's a module not a
method. What do you need those args for?

Cheers

robert

Trans

unread,
Oct 30, 2005, 11:00:22 AM10/30/05
to

A good exmaple is ObjectSpace:

class << ObjectSpace
include EnumerableArgs
alias :each, :each_object
end

ObjectSpace.select(Class) { |c| c.name =~ /^S/ }

You can't do this with regular Enumerable b/c you cannot pass any
arguments through the enumerable methods to the underlying #each
method.

(Sorry if there are any bugs in the code. Ruby's not installed on my
system at the moment.)

T.

Pit Capitain

unread,
Oct 30, 2005, 11:43:39 AM10/30/05
to
Trans schrieb:

> Robert Klemme wrote:
>>What do you mean by "Enumerable doesn't support args"? It's a module not a
>>method. What do you need those args for?
>
> A good exmaple is ObjectSpace:
>
> class << ObjectSpace
> include EnumerableArgs
> alias :each, :each_object
> end
>
> ObjectSpace.select(Class) { |c| c.name =~ /^S/ }
>
> You can't do this with regular Enumerable b/c you cannot pass any
> arguments through the enumerable methods to the underlying #each
> method.

require "enumerator"

ObjectSpace.enum_for(:each_object, Class).select { |c| c.name =~ /^S/ }

Regards,
Pit


Trans

unread,
Oct 30, 2005, 12:20:39 PM10/30/05
to

Pit Capitain wrote:
>
> require "enumerator"
>
> ObjectSpace.enum_for(:each_object, Class).select { |c| c.name =~ /^S/ }

He he! Yep, I'd call that "inflation" alright ;). Better yet, now we've
almost come full circle since #enum_for works in essentially the same
way as #every !

Don't you just love it David!? ;)

Thanks but no thanks. I'll take an Enumerable with args and a
elementwise operator over this any day.

T.

Ryan Leavengood

unread,
Oct 30, 2005, 2:01:47 PM10/30/05
to

Why? Do you have a good reason beyond the fact that you took all the
time to write your Enumerable with args? The enumerator code makes
perfect sense to me, and requires less code than your version. Plus
you are modifying a core class, which is generally looked upon as a
bad practice.

Ryan


Trans

unread,
Oct 30, 2005, 2:20:17 PM10/30/05
to
Hi Ryan,

I didn't modify a core class. EnumerableArgs is a complete rewrite of
Enumerable and stands on it own.

The Enumerator approach lacks for a few reasons.

1. Its' longer and less readable.
2. It's creates an intermedeary object.
4. It means Enumerable remains less useful.

While Enumerator may have it's uses, I do not find it's use here
"Ruby-esque", for much the same reason David disliked #every --I have
to agree.

T.

Ryan Leavengood

unread,
Oct 30, 2005, 3:36:15 PM10/30/05
to
On 10/30/05, Trans <tran...@gmail.com> wrote:
> Hi Ryan,
>
> I didn't modify a core class. EnumerableArgs is a complete rewrite of
> Enumerable and stands on it own.

Sorry I was ambiguous. In the ObjectSpace example you modify a core class:

class << ObjectSpace
include EnumerableArgs
alias :each, :each_object
end

ObjectSpace.select(Class) { |c| c.name =~ /^S/ }

Though this modification is less troublesome than other kinds of changes.

> The Enumerator approach lacks for a few reasons.
>
> 1. Its' longer and less readable.

Here is the code from Pit:

require "enumerator"

ObjectSpace.enum_for(:each_object, Class).select { |c| c.name =~ /^S/ }

How is that longer than your example above? If the unneeded whitespace
is removed from both, your example is about 50 characters longer (this
is ignoring the needed "require" line, since your example lacks it.)

And maybe I'm "in too deep" in understanding Ruby, but I find the
above very readable (but I also find inject easy to understand now
too, so...)

And while your example is also pretty easy to read, it requires some
knowledge as to what EnumerableArgs is, since the name isn't totally
obvious.

> 2. It's creates an intermedeary object.

Fair enough.

> 4. It means Enumerable remains less useful.

What happened to number 3? ;)

I'm not arguing that the code you made doesn't have some merit, I just
don't agree that it is any better than the enumerator example.

> While Enumerator may have it's uses, I do not find it's use here
> "Ruby-esque", for much the same reason David disliked #every --I have
> to agree.

Well it seems the perspective of something being "Ruby-esque" is quite
subjective, since I find the enumerator example quite "Ruby-esque."

Regards,
Ryan


David A. Black

unread,
Oct 30, 2005, 4:23:23 PM10/30/05
to
Hi --

On Sun, 30 Oct 2005, Robert Klemme wrote:

> To sum up: I'm totally with David and I think we should take his statement
> for what it is: a warning notice, a reminder to maybe more often try to keep
> some focus but not more - especially not any form of censorship.

It definitely wasn't a post about netiquette or trying to get people
to stop posting what they want. It was chiefly an analysis of why
there are so many of these suggestions, change requests, etc. that
either add punctuation or attempt to shorten already fairly concise
idioms. I thought others who have been puzzled by the phenomenon
might find it interesting.


David

--
David A. Black
dbl...@wobblini.net


Robert Klemme

unread,
Oct 30, 2005, 4:24:05 PM10/30/05
to
Trans <tran...@gmail.com> wrote:
> Hi Ryan,
>
> I didn't modify a core class. EnumerableArgs is a complete rewrite of
> Enumerable and stands on it own.
>
> The Enumerator approach lacks for a few reasons.
>
> 1. Its' longer and less readable.

Can't see this.

> 2. It's creates an intermedeary object.

As all the "every" approaches that promote method chaining. Those might
even create multiple proxy objects depending on the implementation.

> 4. It means Enumerable remains less useful.

I cannot see this.

> While Enumerator may have it's uses, I do not find it's use here
> "Ruby-esque", for much the same reason David disliked #every --I have
> to agree.

The big advantage of Enumerator is that it implements Enumerable thus
allowing all code created for Enumerables to work with an Enumerator
instance. The big disadvantage of your approach OTOH is that you modify an
Enumerable instance and thus shadowing methods defined in Enumerable. This
may lead to unexpected effects if people rely on the original Enumerable
methods. Also, how many classes do you know that have method #each that
accepts arguments? I'd go even further than Ryan, I think Enumerator is
better in this case than your approach.

Cheers

robert

Trans

unread,
Oct 30, 2005, 5:45:17 PM10/30/05
to
Robert what are you talking about? "You can't see" isn't a useful
argument. And your concept of EnumerableArgs seems distorted. Its just
a Mixin. Use where you want to or don't, it doesn't effect anything
else.

T.

Robert Klemme

unread,
Oct 31, 2005, 4:42:25 AM10/31/05
to
Trans wrote:
> Robert what are you talking about? "You can't see" isn't a useful
> argument.

I didn't want to repeat Ryan's argument and just signal my approval.
Should've been clearer.

> And your concept of EnumerableArgs seems distorted. Its just
> a Mixin. Use where you want to or don't, it doesn't effect anything
> else.

I don't think my concept of EA is distorted: even a mixin can affect other
code. As I said, code that relies on the std Enumerable behavior might be
affected if handed an instance that mixes in EA. I don't say it will but
there's a chance because EA redefines methods from Enumerable.

The other potential issue is that EA's methods may be hidden because it's
a mixin...

What about my last question? How many classes do you know that have


method #each that accepts arguments?

Kind regards

robert

Trans

unread,
Oct 31, 2005, 6:19:20 AM10/31/05
to
>As I said, code that relies on the std Enumerable behavior
>might be affected if handed an instance that mixes in EA.
>I don't say it will but there's a chance because EA
>redefines methods from Enumerable.

Such an argument smakes dead against the whole concept of polymorphism
and duck-typing.

> What about my last question? How many classes do you
> know that have method #each that accepts arguments?

That's a ridiculous question. The reason you don't have ANY #each
taking parameters is becuase it won't work with Enumerable!

This whole discussion is silly. If you really think this is "longer" or
"less readable"

ObjectSpace.select(Class) { |c| c.name =~ /^S/ }

Than this:

ObjectSpace.enum_for(:each_object, Class).select { |c| c.name =~ /^S/
}

Then by all means, type away.

T.

Ryan Leavengood

unread,
Oct 31, 2005, 10:22:12 AM10/31/05
to
On 10/31/05, Trans <tran...@gmail.com> wrote:
>
> This whole discussion is silly. If you really think this is "longer" or
> "less readable"
>
> ObjectSpace.select(Class) { |c| c.name =~ /^S/ }
>
> Than this:
>
> ObjectSpace.enum_for(:each_object, Class).select { |c| c.name =~ /^S/
> }
>
> Then by all means, type away.

But you are cheating here by leaving out the "setup code" that allows
you to call ObjectSpace.select. I would be curious to see other
examples where you use EnumerableArgs, because as Robert says there
aren't many "each" methods that take a parameter. Using ri on my 1.8.2
install, I could only find String#each and IO#each, both of which take
an optional "separator" parameter. I personally don't see many cases
where I would need to override the default, especially when calling
Enumerable methods. Plus since both already include Enumerable, I'm
not sure what kinds of wacky things would happen if you mixed in
EnumerableArgs as well.

Ryan


Trans

unread,
Oct 31, 2005, 1:32:51 PM10/31/05
to

Ryan Leavengood wrote:

> But you are cheating here by leaving out the "setup code" that allows
> you to call ObjectSpace.select.

I don't really see that as cheating since the code is already written
and stored in a reusable lib. EnumerableArgs is not something you'd use
on an existing classes in general, but on something you've created new
--otherwise you'd be redefining #each in a core/standard lib which is
not something you want to do lightly in the first place. It doesn't
really bother ObjectSpace b/c it has no #each method or Enumerable
inclusion, but has an each-like method. So it makes a good example
case.

> I would be curious to see other
> examples where you use EnumerableArgs, because as Robert says there
> aren't many "each" methods that take a parameter. Using ri on my 1.8.2
> install, I could only find String#each and IO#each, both of which take
> an optional "separator" parameter.

And those are poor parameters to beign with --they have bad side effect
b/c they default to a global var. Not a very robust solution. I hope
Matz will be changing that for 2.0.

> I personally don't see many cases
> where I would need to override the default, especially when calling
> Enumerable methods. Plus since both already include Enumerable, I'm
> not sure what kinds of wacky things would happen if you mixed in
> EnumerableArgs as well.

If you did include EnumerableArgs there would be no adverse effects
--assumming I it's working as it was designed to. The design goal was
complete transparency. Of course nothing's perfect. I originally wrote
the code for 1.6 so some things have changed. But I did just spend a
couple hours rewritting it to use Enumerator and dynamically generate
the methods based on Enumerable. That way I no longer need to keep it
up-to-date by hand. (Seems a tad slower though suprisingly) So it
should work nearly flawslessly. There are only two caveats. 1) #inject
and #zip can not pass parameters to #each due to their negative arity,
so they work just as they do in Enumerable. And 2) #find (alias
#detect) has been modified to get rid of the 'ifnone' parameter, and
instead made an optional keyword parameter (:ifnone=>...), which makes
more sense considering what it is and how rare it's usage is (it only
accepts a proc). So only this last caveat would present a compatabilty
issue if you were for some strange reason to try and make it a complete
drop in replacemet for Enumerable.

Now what kind of use real might it have besides ObjectSpace? Simply
imagine any class that might have multipe each methods:

class House
include EnumerableArgs

def each_bedroom ...
def each_closet ...
def each_room ...
def each_hallway ...

def each(which=:room, &blk)
send("each_#{which}", &blk)
end
end

h = House.new
h.select(:bathroom) { |b| ... }

T.

Ryan Leavengood

unread,
Nov 1, 2005, 10:03:45 AM11/1/05
to
On 10/31/05, Trans <tran...@gmail.com> wrote:
>
> Now what kind of use real might it have besides ObjectSpace? Simply
> imagine any class that might have multipe each methods:
>
> class House
> include EnumerableArgs
>
> def each_bedroom ...
> def each_closet ...
> def each_room ...
> def each_hallway ...
>
> def each(which=:room, &blk)
> send("each_#{which}", &blk)
> end
> end
>
> h = House.new
> h.select(:bathroom) { |b| ... }

I see your point, but:

require 'enumerator'

h = House.new
h.enum_for(:each_bathroom).select {|b| ... }

I *really* don't see how yours is much better. In fact, I'd argue the
enumerator one is better because it is more explicit...anyone who
knows how enumerator works can see what is happening. Only you, me and
the people paying attention to this thread would understand what the
EnumeratorArgs thing was doing.

But I guess we will just have to agree to disagree, since we are both
dragging this into one of those endless discussions threads that I
dislike so much ;)

Signing off,
Ryan


James Edward Gray II

unread,
Nov 1, 2005, 10:13:00 AM11/1/05
to
On Nov 1, 2005, at 9:03 AM, Ryan Leavengood wrote:

> I see your point, but:
>
> require 'enumerator'
>
> h = House.new
> h.enum_for(:each_bathroom).select {|b| ... }
>
> I *really* don't see how yours is much better. In fact, I'd argue the
> enumerator one is better because it is more explicit...anyone who
> knows how enumerator works can see what is happening.

Yes, an isn't Enumerator in the core as of 1.9? Time to get use to
seeing it. ;)

James Edward Gray II

Christophe Grandsire

unread,
Nov 1, 2005, 10:54:18 AM11/1/05
to
Selon James Edward Gray II <ja...@grayproductions.net>:

>
> Yes, an isn't Enumerator in the core as of 1.9? Time to get use to
> seeing it. ;)
>

Indeed, check: http://ruby-doc.org/core-1.9/

Not only that, but there is also the plan to have enumerating methods return an
enumerator when they aren't given a block. I don't know if it still will
happen, but it sure is a great idea (that would only be for the methods that
don't already have a defined meaning when they aren't given a block I suppose).
--
Christophe Grandsire.

http://rainbow.conlang.free.fr

It takes a straight mind to create a twisted conlang.


Trans

unread,
Nov 1, 2005, 11:09:21 AM11/1/05
to

Ryan Leavengood wrote:
>
> I see your point, but:
>
> require 'enumerator'
>
> h = House.new
> h.enum_for(:each_bathroom).select {|b| ... }
>
> I *really* don't see how yours is much better. In fact, I'd argue the
> enumerator one is better because it is more explicit...anyone who
> knows how enumerator works can see what is happening. Only you, me and
> the people paying attention to this thread would understand what the
> EnumeratorArgs thing was doing.
>
> But I guess we will just have to agree to disagree, since we are both
> dragging this into one of those endless discussions threads that I
> dislike so much ;)

I see your point too. Enumerator, and things like #every, are starting
to come into their own. I wrote EnumerableArgs some time ago when the
clearest approach was a beefed up Mixin (we didn't even have #inject
yet). Like I said to David easlier, I think we will just have to get
used to this new paradigm of intermediate objects acting as "roles".
(And I have to admit I've propogated it mayself with the Functor
class). So to it's end may I then suggest:

h.enumerate(:each_bathroom).select { ...

;)

ciao,
T.

David A. Black

unread,
Nov 1, 2005, 12:25:49 PM11/1/05
to
Hi --

On Wed, 2 Nov 2005, Christophe Grandsire wrote:

> Selon James Edward Gray II <ja...@grayproductions.net>:
>
>>
>> Yes, an isn't Enumerator in the core as of 1.9? Time to get use to
>> seeing it. ;)
>>
>
> Indeed, check: http://ruby-doc.org/core-1.9/
>
> Not only that, but there is also the plan to have enumerating methods return an
> enumerator when they aren't given a block. I don't know if it still will
> happen, but it sure is a great idea (that would only be for the methods that
> don't already have a defined meaning when they aren't given a block I suppose).

I'm not sure where that stands either. It always looked too
elliptical to me, if I'm remembering it correctly -- too much in the
category of "dot syntax for non-dot semantics". I know that a method
call can return an enumerator as well as anything else, but it just
always looked a little odd to me:

people.each.something...

It looks like chaining but it isn't really.

daz

unread,
Nov 1, 2005, 1:22:06 PM11/1/05
to

Ryan Leavengood wrote:


IMHO, both are just circuitously avoiding:

class House

def bathrooms
@rooms.select {|r| r.typ == :bathroom}
end
def bedrooms ...
def closets ...
def hallways ...

end

h = House.new
h.bathrooms.each { |b| ... }


Yes, Enumerator is available in 1.9 without a /require/.
I think it'll stay because it works and there'll be no cause to
remove it.

It'll be an occasional source of amusement for me to mentally
rewrite any posted usage. I envisage being able to backport
#enum_for and its ilk, in all but the most contrived examples,
instinctively. :p

daz

James Edward Gray II

unread,
Nov 1, 2005, 2:14:48 PM11/1/05
to
On Nov 1, 2005, at 12:27 PM, daz wrote:

> Yes, Enumerator is available in 1.9 without a /require/.
> I think it'll stay because it works and there'll be no cause to
> remove it.
>
> It'll be an occasional source of amusement for me to mentally
> rewrite any posted usage. I envisage being able to backport
> #enum_for and its ilk, in all but the most contrived examples,
> instinctively. :p

I must be one of the few Enumerator fans in this thread. I think
it's just cool. ;)

James Edward Gray II


0 new messages