Does an Array#apply make any sense at all?

W

William James

2007/8/14 said:
I wanted to write a simple method for comparing two paths on a Windows
system. My initial algorithm felt very contrived:
def same_path?(a, b)
a, b = [a, b].map{ |p| File.expand_path(p).downcase }
a == b
end
It felt like saving the result from #map and then doing the comparison
shouldn't be necessary. So I came up with the following solution:
class Array
def apply(method)
shift.send(method, *self)
end
end
This allowed me to define #same_path? thusly:
def same_path?(a, b)
[a, b].map{ |p| File.expand_path(p).downcase }.apply:)==)
end
which, to me, looks a lot nicer. Array#apply takes a method (in a
symbolic manner) and applies it to its first element, passing the rest
of the elements as arguments to the given method.
Any thoughts? Is Array#apply a method that could potentially have
other uses than my specific example above?

Your method should be called "apply!" because it's destructive. I'd
rather not do it that way, i.e. without changing the array at hand.You
can use inject for that.

I'd use #inject for your problem:

match = [a,b].map {|x| File.expand_path(x).downcase}.inject {|x,y| x==y}

match = [a,b].map {|x| File.expand_path(x).downcase}.uniq.size == 1
 
S

Simon Krahnke

* said:
! does not mean modifying; it means "dangerous".

Most methods flagged with a ! are dangerous because they modify their
receiver.
I would never add a ! to a method name solely because it changes the
receiver. That's a re-invention of what ! is for.

No, you add it because someone might else assume it is a non-modifying
method, that is what makes it dangerous.

Array#pop is modifying but not dangerous, because everyone expects it to
be modifying.
I think that's a solution in search of a problem.

No, that's a problem.
Just name your methods clearly, without !. Then, if you (or someone
else) want to add a "dangerous" version, you can write the ! method.

You are the one who's proposing that something isn't dangerous because
there currently isn't a less dangerous version.

mfg, simon .... l
 
D

dblack

Hi --

Most methods flagged with a ! are dangerous because they modify their
receiver.

Many of them are, but there's no cause-and-effect between modifying
and !. If there were, there would be !'s on all modifying methods. I
think we should really put that to rest; the convention just doesn't
work that way, and never has.
No, you add it because someone might else assume it is a non-modifying
method, that is what makes it dangerous.

Array#pop is modifying but not dangerous, because everyone expects it to
be modifying.

If the name doesn't connote destructiveness, then you should change
the name. For example, I would not use the name "last" instead of
"pop", because "last" does not connote destructiveness.

But I also wouldn't use "last!". Just adding a ! does not change a bad
name for a destructive method into a good name. It just adds a !.
No, that's a problem.

Not really. If I have a "pop" method, and someone wants to write
"last" (i.e., return the last element but not destructively), they
don't have to write "pop!-minus-!". They should choose the best name,
which may have nothing to do with the name I gave the destructive
method.

In other words, m/m! is not the only possible ratio between methods.
There's also m/n, which can be just as close as m/m!. pop/last is an
example; so is concat/+ (also for arrays).
You are the one who's proposing that something isn't dangerous because
there currently isn't a less dangerous version.

I don't think I can quite follow all the convolutions we're getting
into :) I've posted something about the ! on my blog, if anyone's
interested:

http://dablog.rubypal.com/2007/8/15/bang-methods-or-danger-will-rubyist


David

--
* Books:
RAILS ROUTING (new! http://www.awprofessional.com/title/0321509242)
RUBY FOR RAILS (http://www.manning.com/black)
* Ruby/Rails training
& consulting: Ruby Power and Light, LLC (http://www.rubypal.com)
 
E

Eric Hodel

Just thought that I'd mention the usual example of the difference
is exit
vs. exit! Neither is a "modifying" version of each other.

Instead of modifying anything, #exit! doesn't clean up after itself
(run at_exit handlers, attempt to run finalizers, raise SystemExit,
close file descriptors). All of these things may be dangerous.

It is #exit that does the modifying of things.
 
N

nikolai.weibull

2007/8/14, (e-mail address removed) <[email protected]>:
Hi!
I wanted to write a simple method for comparing two paths on a Windows
system. My initial algorithm felt very contrived:
def same_path?(a, b)
a, b = [a, b].map{ |p| File.expand_path(p).downcase }
a == b
end
It felt like saving the result from #map and then doing the comparison
shouldn't be necessary. So I came up with the following solution:
class Array
def apply(method)
shift.send(method, *self)
end
end
This allowed me to define #same_path? thusly:
def same_path?(a, b)
[a, b].map{ |p| File.expand_path(p).downcase }.apply:)==)
end
which, to me, looks a lot nicer. Array#apply takes a method (in a
symbolic manner) and applies it to its first element, passing the rest
of the elements as arguments to the given method.
Any thoughts? Is Array#apply a method that could potentially have
other uses than my specific example above?
Your method should be called "apply!" because it's destructive. I'd
rather not do it that way, i.e. without changing the array at hand.You
can use inject for that.
I'd use #inject for your problem:
match = [a,b].map {|x| File.expand_path(x).downcase}.inject {|x,y| x==y}

match = [a,b].map {|x| File.expand_path(x).downcase}.uniq.size == 1

Very nice.

nikolai
 
S

Simon Krahnke

* said:
Many of them are, but there's no cause-and-effect between modifying
and !.

You are hitting a strawman.
If the name doesn't connote destructiveness, then you should change
the name.

Obviously the many examples of pairs with and without ! don't follow
that guideline.
Not really. If I have a "pop" method,

We have an "apply" method.
In other words, m/m! is not the only possible ratio between methods.

Who said it was?
There's also m/n, which can be just as close as m/m!. pop/last is an
example; so is concat/+ (also for arrays).

And there is m/m!. If you write m!, name it m!, not m.
I don't think I can quite follow all the convolutions we're getting
into :) I've posted something about the ! on my blog, if anyone's
interested:

http://dablog.rubypal.com/2007/8/15/bang-methods-or-danger-will-rubyist

You write "create the traditional pair of methods", that's right. But now
I'm too lazy to write the simple non-modifying wrapper. That's not a good
reason to omit the !.

BTW: Is there any reason you don't mention your whole name in your posts?

mfg, simon .... someone wrote a blog because of my posts
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,280
Latest member
BGBBrock56

Latest Threads

Top