On Monday, June 06, 2011 03:35:30 AM Ilias Lazaridis wrote:
> > That reminds me Groovy's it.  
> 
> I don't know "Groovy", but I dislike the "it", as it cannot be spoken
> like "each item" or "each value".
> 
> I've just noticed repetitions within code like that:
> 
> names.each { |name| puts name} # 3 times "name(s)"
> 
> names.each { puts item }
> 
> names.each { puts e) # e = entry
> 
> > Currently I have no plan to change the core like that.
> 
> So this would be a low-priority issue?
> 
> Would a thoroughly worked out patch be accepted?

I'm not sure that I have a vote, but I'd also vote against. I like the 
motivation, and that's why we have clever hacks like Symbol#to_proc:

names.map(&:to_s)

But adding a magic variable seems like it would be very surprising in a bad 
way. Suppose I left an empty argument list because I actually don't want any 
arguments? For example:

10.times { puts 'Hello, world!' }

It doesn't really help if it only applies to 'each', either. Then we have the 
very surprising situation where these two lines do different things:

item = 'world'
10.times { puts "Hello, #{item}!" }
10.times.each { puts "Hello, #{item}!" }

And 'item' is a common word. In fact, the suggestion for 'it' seems like it 
would be even worse in this respect. On the other hand, choosing anything 
that's deliberately uncommon, like, say, __item__, would defeat the purpose.

One approach might be to somehow let other variables take precedence, so, for 
example, if I'd defined 'item' elsewhere, it wouldn't be overridden by this. 
But that opens up its own can of worms. Do you consider only local variables? 
Then a local variable would be different than a method call on the current 
object, which is surprising. And if you do consider methods, how do you find 
out whether the current object responds to the method you want? If you only 
look at methods actually defined, you miss any method_missing hacks, which is 
surprising. If you call respond_to?, that's still not foolproof, and it's 
likely to have serious performance implications, unless you cache the result 
-- and if you do, then I can't define methods inside that loop and expect to 
use them immediately, which seems like a reasonable thing to do.

I don't really see a good way to make this work.



One of the more interesting features of Perl is the default variable, $_ -- 
most builtin functions will automatically default to this if you don't provide 
an explicit variable. It certainly prevents some repetitive code, makes some 
things seem shorter and cleaner, and it seems pretty cool. But then you end up 
with code like this:

while(<STDIN>) {
    chomp;
    print "$1\n" if /^Hello, (.*)/;
}

...and that's a short, mostly-readable example because I frankly don't 
remember enough about Perl to make it really dangerous. Even so, look at how 
twisted it is already. If you're not a Perlist already, it's not obvious that 
"while(<STDIN>)" actually loops over each line of standard input. Once you get 
that, you might figure out that chomp and the regex should apply to these 
lines, but it's much more common to find a somewhat larger loop body, with 
actual variables mixed and matched with automagic ones.

And that's only one kind of default variable, and there are all sorts of other 
variables Perl magically defines for you. Ruby's borrowed a few of them, but 
they're all well-defined by now, and generally obviously 'special' in some 
way, like __FILE__ and $1. Adding new ones at this point, especially in such a 
way that they could easily be confused with common variables, seems like a 
very bad idea.

Sometimes, verbosity is good. I'd much rather do a little extra typing from 
time to time than have Perl-like black magic going on behind the scenes.