Alias_method :tap, :affect

file_name = File.basename(input.join.gsub(re, “_”))

Not if re has \A or \Z.

If the Regexp contain such an anchor, we probably shouldn’t be
calling gsub().

We don’t know what’s in re, so we can’t make a judgment about gsub.

My point is that your examples aren’t convincing me. Even if we have
to support the anchor, I prefer your first example. It’s more
obvious to me. But I’ll sleep OK tonight if we just agree to
disagree on that.

Well I’ve used this for several years, and the examples I gave are
simplistic but illustrative. The purpose was to understand the
general idea from the particular examples, even though they are
simplistic.

I’ve already suggested a less trivial example:

files = stems.map { |f|
   f + "." + ext[platform]
}.as { |t|
   z = transform1(t)
   transform2(basenames + transform3(t, z))
}.map { |f|
   File.join(audio_dir, f)
}

Your suggestion was to put the middle block into a method. While that
may be best in certain circumstances, there is still a niche for small-
but-not-trivial cases where keeping the block may be clearer.

On Nov 12, 2007, at 5:30 PM, [email protected] wrote:

file_name = File.basename(input.join.gsub(re, “_”))

Not if re has \A or \Z.

If the Regexp contain such an anchor, we probably shouldn’t be
calling gsub().

We don’t know what’s in re, so we can’t make a judgment about gsub.

If you don’t know the contents of the Regexp and thus you call gsub
(), you are a much braver programmer than I am!

It’s clear we just disagree and I’ve said my peace now. You win. :wink:

James Edward G. II

On Nov 12, 6:39 pm, James Edward G. II [email protected]
wrote:

If you don’t know the contents of the Regexp and thus you call gsub
(), you are a much braver programmer than I am!

You’ve never used a Regexp variable? Always a Regexp literal for
you? That’s why I put a variable there, to make the point that it
can’t just be concatenated.

It’s clear we just disagree and I’ve said my peace now. You win. :wink:

In my previous post, I did however make a valid argument with a valid
example, to which you did not respond.

On Nov 12, 2007, at 2:15 PM, Joel VanderWerf wrote:

Really?

There is the scope issue. I use this construct sometimes:

quite true. still, i personally think such a cozy method as tap/
whatever should be in the instance scope - otherwise it is just eye
candy.

cheers.

a @ http://codeforpeople.com/

On Nov 12, 7:31 pm, Raul P. [email protected] wrote:

But the point that JGII is making about ‘re’ is not that he prefers
Regexp literals vs variables! it is that if the regexp variable
contained an anchor like \A it does not make a lot of sense to call
gsub… because it would at most match once!

So while we may not know the exact content of the regexp (eg, it is
provided by another component, etc), it makes sense to think that at
least we know it is suited to a global replace (if not, what exactly are
we doing? the whole thing loses any sense).

Of course I understand JGII’s point, but he does not understand mine.
The regexp gsub example is totally irrelevant in its particularity —
the whole point was the use of Object#as with a block which cannot
be replaced with a standard method. It could be any block at all —
it doesn’t matter what it is.

Instead of trying to understand the overall aim, which was the use of
Object#as, JGII decided to be pedantic about the contents of the
block. Well, two can play the pedantry game. He wanted to replace
the block with concat(), which is simply incorrect. But, again,
nonetheless irrelevant.

Due to the distracting cruft in this thread, I’ll start another one.

On Nov 12, 2007 10:55 PM, [email protected] wrote:

  end

context. Why would I even risk doing that? What if I want to use the
special name. It should be given a temporary name (e.g. “t”) which
communicates its temporal non-specialness. Object#instance_eval is
the former, Object#as is the latter.

Understood, I actually just started to grasp the concept of “this”, thx.
R.

On Nov 13, 2007, at 12:20 AM, [email protected] wrote:

exactly are
we doing? the whole thing loses any sense).

Of course I understand JGII’s point, but he does not understand mine.

Careful there. Let’s not turn this into name calling.

Instead of trying to understand the overall aim, which was the use of
Object#as, JGII decided to be pedantic about the contents of the
block.

I remember this going down as:

  1. You showed as() and said you could provide examples of why it’s
    so important
  2. I said I didn’t get it an would like to see those examples
  3. You showed examples
  4. I said that I felt those examples didn’t properly show as() to be
    a must have, for various reasons
  5. It became clear we just disagreed about that

He wanted to replace the block with concat(), which is simply
incorrect.

Can you show how my concat() solution was “incorrect?” You had code
like:

(1…3).map { |n| n * 2 } + [4, 5]
=> [2, 4, 6, 4, 5]

I suggested using:

(1…3).map { |n| n * 2 }.concat([4, 5])
=> [2, 4, 6, 4, 5]

They look equivalent to me.

Under the hood concat() is a destructive change to the original Array
whereas the + operator creates a new Array. However, since we used
map() first to generate an Array, that doesn’t affect us here.

James Edward G. II

On Nov 13, 8:35 am, James Edward G. II [email protected]
wrote:

Can you show how my concat() solution was “incorrect?” You had code
like:

I’m sorry, I meant your removal of the gsub block was incorrect.

class Object
def as
yield self
end
end

input = %w(a b)
re = %r!a\Z!

filename = input.map { |t|
t.gsub(re, “_”)
}.join.as { |t|
File.basename(t)
}

puts filename

=> _b

file_name = File.basename(input.join.gsub(re, “_”))

puts file_name

=> ab

It is not name-calling to observe that you don’t understand my
argument. My apologies; no offense was intended. Nonetheless I still
believe that you haven’t followed what I’ve said in this thread.

On Nov 13, 2007, at 8:15 AM, [email protected] wrote:

  t.gsub(re, "_")

}.join.as { |t|
File.basename(t)
}

puts filename

=> _b

Just for the sake of the archives, note that the above should use sub
() instead of gsub().

Thanks for the explanation.

James Edward G. II

On Nov 13, 9:18 am, James Edward G. II [email protected]
wrote:

Just for the sake of the archives, note that the above should use sub
() instead of gsub().

But that is part of what you are not understanding. ‘input’ and ‘re’
were originally presented as unknowns. You can’t change gsub to sub,
just like you can’t take out the block.

unknown wrote:

On Nov 12, 6:39 pm, James Edward G. II [email protected]
wrote:

If you don’t know the contents of the Regexp and thus you call gsub
(), you are a much braver programmer than I am!

You’ve never used a Regexp variable? Always a Regexp literal for
you? That’s why I put a variable there, to make the point that it
can’t just be concatenated.

It’s clear we just disagree and I’ve said my peace now. You win. :wink:

In my previous post, I did however make a valid argument with a valid
example, to which you did not respond.

The exchange was great from both sides.

But the point that JGII is making about ‘re’ is not that he prefers
Regexp literals vs variables! it is that if the regexp variable
contained an anchor like \A it does not make a lot of sense to call
gsub… because it would at most match once!

So while we may not know the exact content of the regexp (eg, it is
provided by another component, etc), it makes sense to think that at
least we know it is suited to a global replace (if not, what exactly are
we doing? the whole thing loses any sense).

On Nov 13, 2007, at 8:35 AM, [email protected] wrote:

On Nov 13, 9:18 am, James Edward G. II [email protected]
wrote:

Just for the sake of the archives, note that the above should use sub
() instead of gsub().

But that is part of what you are not understanding. ‘input’ and ‘re’
were originally presented as unknowns. You can’t change gsub to sub,
just like you can’t take out the block.

I’m uncomfortable with that line of thinking. When I don’t know what
something contains, I don’t default to the most damaging choice.

James Edward G. II

On Nov 13, 9:38 am, James Edward G. II [email protected]
wrote:

just like you can’t take out the block.

I’m uncomfortable with that line of thinking. When I don’t know what
something contains, I don’t default to the most damaging choice.

The code was given as is, with unspecified variables ‘input’ and
‘re’. You suggested removing the block. That is wrong because the
behavior is not equivalent, as I just demonstrated. You suggested
changing gsub to sub. That is also wrong because the behavior is not
equivalent (and I assume this needs no demonstration).

On Nov 13, 2007, at 8:50 AM, [email protected] wrote:

You suggested changing gsub to sub. That is also wrong because the
behavior is not equivalent (and I assume this needs no demonstration).

Your code:

class Object
def as
yield self
end
end

input = %w(a b)
re = %r!a\Z!

filename = input.map { |t|
t.gsub(re, “_”)
}.join.as { |t|
File.basename(t)
}

puts filename

=> _b

Switching to sub():

class Object
def as
yield self
end
end

input = %w(a b)
re = %r!a\Z!

filename = input.map { |t|
t.sub(re, “_”)
}.join.as { |t|
File.basename(t)
}

puts filename

=> _b

The results were the same.

James Edward G. II

On Nov 13, 10:04 am, James Edward G. II [email protected]
wrote:

The results were the same.

Not for all cases of ‘re’ and ‘input’. Those variables were
unspecified. If you wish to suggest an improvement to the code, it
must at least be equivalent to what was given. It must produce the
same results for all such ‘re’ and all such ‘input’. Sorry, the best
I can do is say it again:

The code was given as is, with unspecified variables ‘input’ and
‘re’. You suggested removing the block. That is wrong because the
behavior is not equivalent, as I just demonstrated. You suggested
changing gsub to sub. That is also wrong because the behavior is not
equivalent (and I assume this needs no demonstration).

But I guess it does need a demonstration:

class Object
def as
yield self
end
end

input = %w(aa bb)
re = %r!a!

filename = input.map { |t|
t.gsub(re, “_”)
}.join.as { |t|
File.basename(t)
}

puts filename

=> __bb

filename = input.map { |t|
t.sub(re, “_”)
}.join.as { |t|
File.basename(t)
}

puts filename

=> _abb

Not equivalent.

On Nov 13, 2007 4:30 PM, [email protected] wrote:
I believe Object#as is a nice idea, I might even use it with your
permission;)
However there is no need to make all that fuss about people who do not
agree, it is their choice and I feel that you kind of kill a nice
threat.
Just my 0.02€

Robert

On Mon, 12 Nov 2007 19:31:08 -0500, Raul P. wrote:

contained an anchor like \A it does not make a lot of sense to call
gsub… because it would at most match once!

So while we may not know the exact content of the regexp (eg, it is
provided by another component, etc), it makes sense to think that at
least we know it is suited to a global replace (if not, what exactly are
we doing? the whole thing loses any sense).

OK. But if re isn’t suited to a global replace, then we’re using sub
instead of gsub. If we take the following examples,

filename = File.basename(input.map { |t|
t.sub(re, “_”)
}.join)

filename = input.map { |t|
t.sub(re, “_”)
}.join.as { |t|
File.basename(t)
}

then neither of the following are equivalent

file_name = File.basename(input.join.sub(re, “"))
file_name = File.basename(input.join.gsub(re, "
”))

–Ken

On Nov 13, 1:03 pm, Robert D. [email protected] wrote:

I believe Object#as is a nice idea, I might even use it with your permission;)
However there is no need to make all that fuss about people who do not
agree, it is their choice and I feel that you kind of kill a nice
threat.
Just my 0.02€

There is nothing wrong with disagreement — but one has to understand
the issue on the table before taking a position. The difficult part
of the thread was that James insisted he disagreed with me when he
clearly didn’t understand what I was saying, as especially the last
few posts show.

Also, an example is meant to illustrate a point, and it is difficult
when a person focuses on irrelevant parts of the example instead of
asking what the example is meant to illustrate. My remark about
pedantry was not meant as derogatory but descriptive: “adj. overly
concerned with minute details or formalisms.” That is exactly what
was happening — the forest for the trees.

Perhaps one of my character flaws is my high tolerance for technical
exchanges in really trying to nail down the issues and to clarify the
arguments: at times I keep going while others see it as excessive or
diminutive. It is very hard for me to allow misunderstandings to be
applied toward a position of agreement or disagreement.

I apologize again — I was not feeling spiteful or malicious in this
exchange, contrary to what it may have appeared like. It is just my
obsessive nature. Cheers to all, and to all a good night.

–FC

On Nov 12, 2007, at 11:20 PM, [email protected] wrote:

Object#as, JGII decided to be pedantic about the contents of the

highly unlikely: james is about as nice a guy as you’ll meet online.
email isn’t the greatest medium to attempt to determine tone and i
doubt he intended to come across like that - people rarely do.

thought i’d mention that as it’s worth considering, on this list more
that others.

kind regards.

a @ http://codeforpeople.com/

Robert D. wrote:

On Nov 13, 2007 4:30 PM, [email protected] wrote:
I believe Object#as is a nice idea, I might even use it with your permission;)
However there is no need to make all that fuss about people who do not
agree, it is their choice and I feel that you kind of kill a nice
threat.

“These are not bad people, they’re just programmers, and programming
requires you to dot every i and cross every t, so you get into a frame
of mind where you can’t leave any argument unanswered any more than you
would ignore an error from your compiler.” – Joel Spolsky

:slight_smile: