(replying via google groups - sorry for any formatting issues)


>
> I have not had such problems with exception traces.  Emacs parses the
> trace, so I've never had a problem tracking exceptions down.
>

well although that may sound heretical to me (vim user ;-)) i was
thinking more along the lines of debugging production code where you
typically just have some logs or, as i'm currently doing, debugging
stacktraces hand written and walked out of a classified facility!
(seriously)


> You said you disagreed about variable names, but I didn't make an
> argument about variable names.  The argument was about needless
> temporaries lying around and mucking up at-a-glance comprehension.
> Those temporaries can be culled away nicely with Object#as.
>
>    expanded = stems.map { |stem|
>       "#{ stem }.#{ guess_extension stem }"
>    }.as { |guesses|
>       transform2(source_files + transform1(guesses))
>    }.as { |basenames|
>       basenames.map { |basename|
>          File.join dir, basename
>       }
>    }
>
> Of course transform1 and transform2 are bad names --- they are meant
> to be bad!  They are intentionally generic for the purpose of the
> example.  They stand for any function.

i know.  still, i couldn't resist.

>
> You gave the Filelist example as the preferred code, which is exactly
> right.  However we are not talking about Filelist, but the
> *implementation* of Filelist.
>

fair enough.

> Could you clarify how the above code lends "strong support to bad
> programming practices"?  That seems unfounded.  On the contrary, I
> find it more appealing at least because (1) the intent of the code ---
> to produce a value for 'expanded' --- is more obvious; (2) there are
> no temporaries lying around which may potentially cause confusion in
> future maintenance; (3) the logic flow is more obvious: three
> consecutive operations, with the output of one fed into the input of
> the next.

for the record, i would use #as just as i use #eval and co.  as far as
clarity goes, maybe you come from a functional background, but i've
never found stringing lambdas together as very clear.  i also
typically prefer

  response = http.response
  response.foo
  response.bar

to

  http.response.foo
  http.response.bar

for two reasons

 1) error reporting
 2) vars are cheap in ruby, function calls are not

although for simple/short code i do use the second often, reserving
the former for 'real' code i anticipate maintaining and debugging.  i
suspect i'm in the minority here.

anyhow - eval, instance_eval, class << self, are all tools that are
fugly, dangerous, and let us do things that probably should not be
aired in the open.  #as, #returning, and company seem, to me, are
meant more as annotations, for example,

  def foobar
    returning Object.new do |object|  ### hey!  i'm returning an
object

but can easily obscure code too as scopes (potentially) and names
mogrify a few times in a line or two when they are chained.

i guess in the end i'm being more critical of the particular example
you gave rather than #as on the whole - but #as just seems to have a
little code smell too it since it loses much of it's power inside a
small method where local vars get popped anyhow

so

  def foobar
    tmp = self
    someting_with tmp
  end

vs

  def foobar
    self.as{|tmp| something_with tmp}
  end

is obviously not much in the way of gained clarity.

it just seems like it's *only* in longish method chains begging for a
re-factoring that it really shines.  i'd really have to use it anger
to decide.


cheers.