Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Should IO::Path be a value type? (i.e. eqv-comparable) #4515

Closed
p6rt opened this issue Sep 5, 2015 · 8 comments
Closed

Should IO::Path be a value type? (i.e. eqv-comparable) #4515

p6rt opened this issue Sep 5, 2015 · 8 comments
Labels
RFC Request For Comments

Comments

@p6rt
Copy link

p6rt commented Sep 5, 2015

Migrated from rt.perl.org#125998 (status was 'rejected')

Searchable as RT125998$

@p6rt
Copy link
Author

p6rt commented Sep 5, 2015

From @dakkar

This​::

  '/tmp'.IO eqv '/tmp'.IO

returns ``False``.

Is this correct? Should IO behave like value objects?

Possible problems​:

- two IO referring to non-existent paths​: should they compare like
  their string representation? or always be different? or what?
- ``/tmp`` and ``/tmp/``​: should they compare as equal? should we
  ``.resolve`` them before comparing?

--
  Dakkar - <Mobilis in mobile>
  GPG public key fingerprint = A071 E618 DD2C 5901 9574
  6FE2 40EA 9883 7519 3F88
  key id = 0x75193F88

Every journalist has a novel in him, which is an excellent place for it.

@p6rt
Copy link
Author

p6rt commented Sep 5, 2015

From @lizmat

On 05 Sep 2015, at 16​:06, dakkar (via RT) <perl6-bugs-followup@​perl.org> wrote​:

# New Ticket Created by dakkar
# Please include the string​: [perl #​125998]
# in the subject line of all future correspondence about this issue.
# <URL​: https://rt-archive.perl.org/perl6/Ticket/Display.html?id=125998 >

This​::

'/tmp'.IO eqv '/tmp'.IO

returns ``False``.

Is this correct? Should IO behave like value objects?

Possible problems​:

- two IO referring to non-existent paths​: should they compare like
their string representation? or always be different? or what?
- ``/tmp`` and ``/tmp/``​: should they compare as equal? should we
``.resolve`` them before comparing?

If they should work as value objects, they should probably compare .abspath.

Liz

@p6rt
Copy link
Author

p6rt commented Sep 5, 2015

The RT System itself - Status changed from 'new' to 'open'

@p6rt
Copy link
Author

p6rt commented Sep 5, 2015

From @bdw

I kind of think that's impossibly complex. What does it even mean for IO
objects to be value-equal? They represent unknowns in any case. Even if
they resolved to the same file, they might be read at different times and
have different contents. Or a write to one object may succeed and another
may not.
No, I don't think IO should be a value object.

Bart

2015-09-05 16​:14 GMT+02​:00 Elizabeth Mattijsen <liz@​dijkmat.nl>​:

On 05 Sep 2015, at 16​:06, dakkar (via RT) <perl6-bugs-followup@​perl.org>
wrote​:

# New Ticket Created by dakkar
# Please include the string​: [perl #​125998]
# in the subject line of all future correspondence about this issue.
# <URL​: https://rt-archive.perl.org/perl6/Ticket/Display.html?id=125998 >

This​::

'/tmp'.IO eqv '/tmp'.IO

returns ``False``.

Is this correct? Should IO behave like value objects?

Possible problems​:

- two IO referring to non-existent paths​: should they compare like
their string representation? or always be different? or what?
- ``/tmp`` and ``/tmp/``​: should they compare as equal? should we
``.resolve`` them before comparing?

If they should work as value objects, they should probably compare
.abspath.

Liz

@p6rt
Copy link
Author

p6rt commented Sep 5, 2015

From @lizmat

Note that we’re talking really about IO​::Path objects here, which is what .IO generates.

And in that context, I think an object $a with a given abspath, would be eqv to $b with the same abspath. Because that *is* the identifier on a file system, is it not?

Liz

On 05 Sep 2015, at 17​:03, Bart Wiegmans <bartwiegmans@​gmail.com> wrote​:

I kind of think that's impossibly complex. What does it even mean for IO objects to be value-equal? They represent unknowns in any case. Even if they resolved to the same file, they might be read at different times and have different contents. Or a write to one object may succeed and another may not.
No, I don't think IO should be a value object.

Bart

2015-09-05 16​:14 GMT+02​:00 Elizabeth Mattijsen <liz@​dijkmat.nl>​:

On 05 Sep 2015, at 16​:06, dakkar (via RT) <perl6-bugs-followup@​perl.org> wrote​:

# New Ticket Created by dakkar
# Please include the string​: [perl #​125998]
# in the subject line of all future correspondence about this issue.
# <URL​: https://rt-archive.perl.org/perl6/Ticket/Display.html?id=125998 >

This​::

'/tmp'.IO eqv '/tmp'.IO

returns ``False``.

Is this correct? Should IO behave like value objects?

Possible problems​:

- two IO referring to non-existent paths​: should they compare like
their string representation? or always be different? or what?
- ``/tmp`` and ``/tmp/``​: should they compare as equal? should we
``.resolve`` them before comparing?

If they should work as value objects, they should probably compare .abspath.

Liz

@p6rt
Copy link
Author

p6rt commented May 6, 2016

From @smls

In current Rakudo, the original example prints True now​:

  ➜ say "/tmp".IO eqv "/tmp".IO;
  True

However, it seems to use .Str rather than .abspath to compare them, so IO​::Path objects that refer to the same path but constructed from different strings, are not considered the same​:

  ➜ chdir "/tmp"; say "foo".IO eqv "/tmp/foo".IO;
  False

  ➜ say "a/b".IO eqv "a/b/c/..".IO;
  False

  ➜ ~ 6 'say "a".IO eqv "./a".IO'
  False

@p6rt
Copy link
Author

p6rt commented Jun 9, 2017

From @zoffixznet

Should IO behave like value objects?

The current behaviour is what we want to keep (this also now being far on the other side
of The Christmas), so I'll close this RFC.

However, it seems to use .Str rather than .abspath to compare them

Currently, we go through the default Mu `eqv` and so it compares *all* of IO​::Path's attributes.
The reason `say "foo".IO eqv "/tmp/foo".IO;` compares False is because the objects contain
different $.path attributes.

All the other proposals in the ticket talk about different ways of verifying the two IO​::Path objects
point to the same filesystem object. However, there's no good way of doing that while guaranteeing
the comparison will hold true after the comparison (i.e. when the user wishes to use that result).
So it's not really a generalizable behaviour that we want to do under the hood, but rather something that
the user should be explicitly doing.

- .abspath (now .absolute) doesn't access the filesystem, so two paths with different .abspaths can
  still reference the same filesystem object. The user can still use this behaviour via smartmatching
- we can kick it up a notch and do .resolve, but by default that will stop as soon as it hits an path part
  that doesn't exist, and from that point we're back to the same issue as with .absolute
- we can use .resolve with :completely arg, but that will make paths that reference non-existent objects
  uncomparable
- but even with paths that do .resolve(​:completely) we hit the temporal issue Bart mentioned. The filesystem
  condition may change the moment we finish doing our checks, or even in the middle of our check, resulting
  in incorrect answers.

While the same issue exists with methods such as IO​::Path.e, I think eqv comparison should go further than
just ensuring resolved path point to the same filesystem object, as there are cases where it matters. For example,
stringification via .Str method ignores .CWD attribute or stuff like $*CWD variable often needs objects with
absolute $.path attributes. So the values of individual attributes are more important than what the IO​::Path points to.

So in summation, I think the current behaviour of treating IO​::Path as any other object, as we've been doing
since first release in this case is most desirable behaviour.

@p6rt p6rt closed this as completed Jun 9, 2017
@p6rt
Copy link
Author

p6rt commented Jun 9, 2017

@zoffixznet - Status changed from 'open' to 'rejected'

@p6rt p6rt added the RFC Request For Comments label Jan 5, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
RFC Request For Comments
Projects
None yet
Development

No branches or pull requests

1 participant