Pathname#to_str withdrawn in 1.9?

Just getting started experimenting with Ruby 1.9 (1.9.3) and my scripts
are collapsing about my ears - for various reasons, of course, but one
of them turns out be that my code relies heavily on implicit conversion
of Pathname to String in various string contexts. It seems that Pathname
no longer has to_str. My questions are:

(1) Why? Was this regarded as a security issue? Or has it, perhaps,
something to do with encodings? I can see the change happening here:

<* file.c (rb_get_path): get path string via "to_path" method if · shyouhei/ruby@4ded52b · GitHub
156c1fd28>

But I don’t understand the reasons for it - and especially why they
would do this when it causes so much breakage.

(2) Any good reason why I shouldn’t work around this by implementing my
own Pathname#to_str to call to_s? It’s an obvious response, but then one
thinks, there might be something about the answer to (1) which make the
answer to (2) “Yes, just bite the bullet and find all the places where
you do this and call to_s explicitly.” But the real problem is that I
doubt I can find them all; it’s pervasive in my code.

Thx!

m.

On Wed, Sep 12, 2012 at 5:15 PM, Matt N. [email protected] wrote:

156c1fd28>

But I don’t understand the reasons for it - and especially why they
would do this when it causes so much breakage.

I interpret “path object is not a string.” to mean that a Pathname is
not generally considered equivalent to a String. It’s the same
reasoning why some classes have #to_i but not #to_int - they can be
converted to an int - but they do not represent an integer value. A
Pathname is at best a very special form of String (i.e. one with
certain restrictions with regard to the structure).

(2) Any good reason why I shouldn’t work around this by implementing my
own Pathname#to_str to call to_s? It’s an obvious response, but then one
thinks, there might be something about the answer to (1) which make the
answer to (2) “Yes, just bite the bullet and find all the places where
you do this and call to_s explicitly.” But the real problem is that I
doubt I can find them all; it’s pervasive in my code.

My solution would be to use the Pathname instance methods for various
file related operations (e.g. opening of the file) instead of using
File.open(pathname). That is much more OO and also in some cases
probably less error prone.

If you actually need a String somewhere I’d rather explicitly invoke
Pathname#to_s for exactly the reason to make it explicit that a
conversion takes place.

Kind regards

robert

Robert K. [email protected] wrote:

<* file.c (rb_get_path): get path string via "to_path" method if · shyouhei/ruby@4ded52b · GitHub
156c1fd28>

But I don’t understand the reasons for it - and especially why they
would do this when it causes so much breakage.

I interpret “path object is not a string.” to mean that a Pathname is
not generally considered equivalent to a String.

Except that it is. From the core methods section of the Pathname
documentation: “These methods are effectively manipulating a String,
because that’s all a path is.”

The use cases are like this:

require “pathname”
f = Pathname(“howdy”)
p ("well " + f)

Under 1.8.7 that’s “well howdy”. Under 1.9.3 it’s an error, “can’t
convert Pathname into String.” One wants to say: “Sure you can, just
call to_s like you used to!”

It’s the breakage I don’t understand. Why do our Benevolent Masters
think this is just okay? I’ll never find all the code where I’m doing
this sort of thing… m.

It’s definitely a judgment call. Not sure if this helps you, but I think
most people use string interpolation, which calls #to_s implicitly. So I
think this would work just fine in 1.9:

require “pathname”
f = Pathname(“howdy”)
p “well #{f}”

The use cases are like this:

require “pathname”
f = Pathname(“howdy”)
p ("well " + f)

Under 1.8.7 that’s “well howdy”. Under 1.9.3 it’s an error, “can’t
convert Pathname into String.” One wants to say: “Sure you can, just
call to_s like you used to!”

It’s the breakage I don’t understand. Why do our Benevolent Masters
think this is just okay? I’ll never find all the code where I’m doing
this sort of thing… m.

I think that you should report it as a regression on
http://bugs.ruby-lang.org/. #to_str looks like an useful feature.

– Matma R.

On Thu, Sep 13, 2012 at 12:43 PM, Bartosz Dziewoński
[email protected] wrote:

I think that you should report it as a regression on
http://bugs.ruby-lang.org/. #to_str looks like an useful feature.

Well, the method was removed on purpose. And nobody questions that
conversion from Pathname to String is a useful feature. The point is
whether Pathname#to_str is considered wrong or not and how much weight
one attributes to the breakage introduced by the removal.

Kind regards

robert

On Thu, Sep 13, 2012 at 12:34 AM, Matt N. [email protected] wrote:

Robert K. [email protected] wrote:

I interpret “path object is not a string.” to mean that a Pathname is
not generally considered equivalent to a String.

Except that it is. From the core methods section of the Pathname
documentation: “These methods are effectively manipulating a String,
because that’s all a path is.”

Well then… I don’t know.

The use cases are like this:

require “pathname”
f = Pathname(“howdy”)
p ("well " + f)

Under 1.8.7 that’s “well howdy”. Under 1.9.3 it’s an error, “can’t
convert Pathname into String.” One wants to say: “Sure you can, just
call to_s like you used to!”

I’d rather recommend to use string interpolation for these kinds of
things. I believe this might even be faster.

p “well #{f}”

It’s the breakage I don’t understand. Why do our Benevolent Masters
think this is just okay? I’ll never find all the code where I’m doing
this sort of thing… m.

Obviously “they” (probably this translates to “Matz”) judged that
fixing this issue in the library was more important than to prevent
breakage. But as to the “why” I can only speculate.

Kind regards

robert

I’d hazard a guess that the reasoning is because the ‘+’ behavior was
confusing and potentially surprising. Pathname defines ‘+’ as a filename
join, so Pathname(’/foo’) + Pathname(‘bar’) == Pathname(’/foo/bar’). But
‘/foo’ + Pathname(‘bar’) == ‘/foobar’. This is surprising and bug-prone
if
you have code that mixes pathnames and strings.

I’d recommend sticking to interpolation for pathname/string
concatenation;
then it doesn’t matter which object is what.

Avdi G. [email protected] wrote:

I’d hazard a guess that the reasoning is because the ‘+’ behavior was
confusing and potentially surprising. Pathname defines ‘+’ as a filename
join, so Pathname(‘/foo’) + Pathname(‘bar’) == Pathname(‘/foo/bar’). But
‘/foo’ + Pathname(‘bar’) == ‘/foobar’. This is surprising and bug-prone if
you have code that mixes pathnames and strings.

Interesting point. The amazing thing is how fast I’d internalized this,
almost subconsciously. Indeed, I was doing all sorts of tricky things,
like saying

/myregex/ =~ mypathname

(note the unusual order) in order to get the implicit coercion. We are
curious animals! Thx - m.

Am Thu, 13 Sep 2012 20:37:39 +0900
schrieb Avdi G. [email protected]:

I’d recommend sticking to interpolation for pathname/string
concatenation; then it doesn’t matter which object is what.
On Sep 12, 2012 11:06 PM, “Jonathan T.” [email protected]
wrote:

I agree, but #+ for Pathname/Pathname concatanation seems a bad choice
IMHO. As paths are usually separated by / in Ruby (even on Windows),
why not provide a #/ method for concatenating paths?

Valete,
Marvin


Blog: http://pegasus-alpha.eu/blog

ASCII-Ribbon-Kampagne () | ASCII Ribbon Campaign ()

On Thu, Sep 13, 2012 at 11:11 PM, Quintus [email protected]
wrote:

why not provide a #/ method for concatenating paths?
Interesting idea! That looks interesting

config = home / “.myprog” / “config.xml”

OTOH operator + is far more common among programming languages for
string concatenation which the combination of paths resembles…

Kind regards

robert

On Fri, Sep 14, 2012 at 2:01 AM, Robert K.
[email protected] wrote:

IMHO. As paths are usually separated by / in Ruby (even on Windows),
why not provide a #/ method for concatenating paths?

Interesting idea! That looks interesting

config = home / “.myprog” / “config.xml”

cringe

Bartosz Dziewo?ski [email protected] wrote:

I think that you should report it as a regression on
http://bugs.ruby-lang.org/. #to_str looks like an useful feature.

See:

<https://groups.google.com/d/msg/ruby-core-google/2B9CN17ayWs/cea_zdFPgA
oJ>

It was reported immediately by no less an eminence than the mighty
Yehuda K… If they told_him_ it’s deliberate, it’s deliberate. My
question was more philosophical, not practical. There’s nothing to be
done; I was just trying to wrap my head around the possible thinking
behind the change. And I got some interesting suggestions here, as
expected. :slight_smile: Thx to all - m.