Easy Pathname

I find myself always using File.join, and never utilizing Pathname b/c
it's not as convenient to construct. This snippet occured to me to make
it more paletable:

class String
    def /(dir)
      Pathname.new( File.join(self,dir) )
    end
  end

  class Pathname
    def /(dir)
      join(dir)
    end
  end

  path = '' / 'usr' / 'local' #=> #<Pathname:/usr/local>

Good idea? Improvements? Better alternatives?

T.

It's neat but I've always thought that this should be the definition of String#/:

class String
   alias_method :/, :split
end

···

On Jul 6, 2006, at 6:39 PM, transfire@gmail.com wrote:

I find myself always using File.join, and never utilizing Pathname b/c
it's not as convenient to construct. This snippet occured to me to make
it more paletable:

class String
    def /(dir)
      Pathname.new( File.join(self,dir) )
    end
  end

  class Pathname
    def /(dir)
      join(dir)
    end
  end

  path = '' / 'usr' / 'local' #=> #<Pathname:/usr/local>

Good idea? Improvements? Better alternatives?

T.

transfire@gmail.com wrote:

I find myself always using File.join, and never utilizing Pathname b/c
it's not as convenient to construct. This snippet occured to me to make
it more paletable:

class String
    def /(dir)
      Pathname.new( File.join(self,dir) )
    end
  end

  class Pathname
    def /(dir)
      join(dir)
    end
  end

  path = '' / 'usr' / 'local' #=> #<Pathname:/usr/local>

What about

path = Pathname[''] / 'usr' / 'local' #=> #<Pathname:/usr/local>

A bit more palatable (?) without affecting String.

I wonder why Pathname. and Pathname#/ are not defined this way? The former seems safe and conservative, at least. Maybe #/ is not defined because #+ already has that behavior and it would be strange for + and / to be the same.

···

--
       vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

transfire@gmail.com wrote:

I find myself always using File.join, and never utilizing Pathname b/c
it's not as convenient to construct. This snippet occured to me to make
it more paletable:

class String
    def /(dir)
      Pathname.new( File.join(self,dir) )
    end
  end

  class Pathname
    def /(dir)
      join(dir)
    end
  end

  path = '' / 'usr' / 'local' #=> #<Pathname:/usr/local>

Good idea? Improvements? Better alternatives?

T.

Think about MS Windows. Then think about UNC paths.

Have fun.

- Dan

Logan Capaldo wrote:

It's neat but I've always thought that this should be the definition of String#/:

class String
  alias_method :/, :split
end

Yeah, why isn't it?

irb(main):015:0> "now is the time" / " "
=> ["now", "is", "the", "time"]
irb(main):016:0> ("now is the time" / " ") * " "
=> "now is the time"
irb(main):017:0> ("now is the time" / " ") * "-"
=> "now-is-the-time"

Since Array#* is the same as Array#join when the arg is a string, it's a no-brainer to define String#/ like you did.

···

--
       vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

Even better would be for to split on "/" itself for literal paths:

path = Pathname['/usr/local/src']
path = Pathname['/usr']/foo/bar

martin

···

On 7/7/06, Joel VanderWerf <vjoel@path.berkeley.edu> wrote:

What about

path = Pathname[''] / 'usr' / 'local' #=> #<Pathname:/usr/local>

A bit more palatable (?) without affecting String.

Joel VanderWerf wrote:

path = Pathname[''] / 'usr' / 'local' #=> #<Pathname:/usr/local>

A bit more palatable (?) without affecting String.

Except, what about paths not starting with root?

I wonder why Pathname. and Pathname#/ are not defined this way? The
former seems safe and conservative, at least. Maybe #/ is not defined
because #+ already has that behavior and it would be strange for + and /
  to be the same.

#+ does? I would rathe plus did a straight concat like string.

T.

Daniel Berger wrote:

Think about MS Windows. Then think about UNC paths.

What's problem there?

T.

They work differently than most people expect. Remember, on most
Windows paths, you need a drive: C:\Foo\Bar\Baz. But on UNC paths, you
need \\server\share\Foo\Bar\Baz.

C:\ is like / and so is \\server\share.

-austin

···

On 7/7/06, transfire@gmail.com <transfire@gmail.com> wrote:

Daniel Berger wrote:

Think about MS Windows. Then think about UNC paths.

What's problem there?

--
Austin Ziegler * halostatue@gmail.com * http://www.halostatue.ca/
               * austin@halostatue.ca * You are in a maze of twisty little passages, all alike. // halo • statue
               * austin@zieglers.ca

In article <f93a6bcc0607070018l42ea93a1u10a57c6ad4cb3a76@mail.gmail.com>,
  "Martin DeMello" <martindemello@gmail.com> writes:

Even better would be for to split on "/" itself for literal paths:

path = Pathname['/usr/local/src']
path = Pathname['/usr']/foo/bar

I added Pathname() few weeks ago.

% ./ruby -rpathname -ve 'p Pathname("foo/bar")'
ruby 1.8.5 (2006-07-07) [i686-linux]
#<Pathname:foo/bar>

···

--
Tanaka Akira

Austin Ziegler wrote:

···

On 7/7/06, transfire@gmail.com <transfire@gmail.com> wrote:
> Daniel Berger wrote:
>> Think about MS Windows. Then think about UNC paths.
> What's problem there?

They work differently than most people expect. Remember, on most
Windows paths, you need a drive: C:\Foo\Bar\Baz. But on UNC paths, you
need \\server\share\Foo\Bar\Baz.

C:\ is like / and so is \\server\share.

Okay, I realize that. But how is this not taking that into account
where as File.join or Pathname does?

T.

I don't want to hijack this thread but I do think it would be nice if
Klass() were a synonym for Klass.new(). As far as I know, this
wouldn't conflict with anything in the Ruby standard lib (apart from
Array(), String() and maybe some others which I forget). I personally
use it all the time for my own classes.

Regards,
Sean

···

On 7/7/06, Tanaka Akira <akr@fsij.org> wrote:

In article <f93a6bcc0607070018l42ea93a1u10a57c6ad4cb3a76@mail.gmail.com>,
  "Martin DeMello" <martindemello@gmail.com> writes:

> Even better would be for to split on "/" itself for literal paths:
>
> path = Pathname['/usr/local/src']
> path = Pathname['/usr']/foo/bar

I added Pathname() few weeks ago.

% ./ruby -rpathname -ve 'p Pathname("foo/bar")'
ruby 1.8.5 (2006-07-07) [i686-linux]
#<Pathname:foo/bar>
--
Tanaka Akira

... I do think it would be nice if Klass() were a synonym for
Klass.new(). As far as I know, this wouldn't conflict with anything
in the Ruby standard lib ...

Yes it would:

$ irb
irb(main):001:0> x = Object.new
=> #<Object:0xb7c8c7a8>
irb(main):002:0> def x.to_i ; 42 ; end
=> nil
irb(main):003:0> Integer(x)
=> 42
irb(main):004:0> Integer
=> Integer
irb(main):005:0> Integer.new
NoMethodError: undefined method `new' for Integer:Class
        from (irb):5
irb(main):006:0>

Regards,

Jeremy Henty

···

On 2006-07-08, Sean O'Halpin <sean.ohalpin@gmail.com> wrote:
        from :0

Sean O'Halpin wrote:

I don't want to hijack this thread but I do think it would be nice if
Klass() were a synonym for Klass.new(). As far as I know, this
wouldn't conflict with anything in the Ruby standard lib (apart from
Array(), String() and maybe some others which I forget). I personally
use it all the time for my own classes.

I think its an elegant practice. I know others have argured that it is
too implicit, but if it were standard it would quickly seem rather
explicit. And the current Array(), Integer(), etc. methods really just
help you're case, since they set the precedent. They just happen to
work slightly different than the normal #new counterparts. For even if
Ruby were to make it automatic, they should still be overridable, BUT
in that case they could take on a special existance as a
"constant-method", rather than a method of Kernel, which would be more
robust.

T.

Sean O'Halpin wrote:

I don't want to hijack this thread but I do think it would be nice if
Klass() were a synonym for Klass.new(). As far as I know, this
wouldn't conflict with anything in the Ruby standard lib (apart from
Array(), String() and maybe some others which I forget). I personally
use it all the time for my own classes.

Right now those functions are used as casting/conversion operators, and I think you should continue that "standard" if you defined your own Klass() methods. There's little point in having 2 ways of doing MyClass.new really.

Daniel

You left out the qualification I made - "(apart from Array(), String()
and maybe some others which I forget)". It might have been more
gentlemanly to expand on the "maybe some others" than to make me
appear to have made an incorrect assertion by selectively quoting from
what I said.

Sean

···

On 7/8/06, Jeremy Henty <jeremy@chaos.org.uk> wrote:

On 2006-07-08, Sean O'Halpin <sean.ohalpin@gmail.com> wrote:

> ... I do think it would be nice if Klass() were a synonym for
> Klass.new(). As far as I know, this wouldn't conflict with anything
> in the Ruby standard lib ...

Yes it would:

Sorry about that. I was just trying to be concise. The point I was
making (which Daniel DeLorme also makes elsewhere in the thread) is
that the convention already exists that Klass(x) means "coerce x to an
instance of Klass", rather than "call Klass.new()". As least it does
for many values of Klass, so to make all instances of Klass() synonyms
for Klass.new() would be seriously incompatible. I'm sure there's no
chance of it happening in Ruby 1 . I don't know if anyone's suggested
making Ruby 2 more consistent about this.

Regards,

Jeremy Henty

···

On 2006-07-08, Sean O'Halpin <sean.ohalpin@gmail.com> wrote:

On 7/8/06, Jeremy Henty <jeremy@chaos.org.uk> wrote:

On 2006-07-08, Sean O'Halpin <sean.ohalpin@gmail.com> wrote:

> ... I do think it would be nice if Klass() were a synonym for
> Klass.new(). As far as I know, this wouldn't conflict with anything
> in the Ruby standard lib ...

Yes it would:

You left out the qualification I made - "(apart from Array(),
String() and maybe some others which I forget)". It might have been
more gentlemanly to expand on the "maybe some others" than to make
me appear to have made an incorrect assertion by selectively quoting
from what I said.

Jeremy Henty wrote:

Sorry about that. I was just trying to be concise. The point I was
making (which Daniel DeLorme also makes elsewhere in the thread) is
that the convention already exists that Klass(x) means "coerce x to an
instance of Klass", rather than "call Klass.new()". As least it does
for many values of Klass, so to make all instances of Klass() synonyms
for Klass.new() would be seriously incompatible. I'm sure there's no
chance of it happening in Ruby 1 . I don't know if anyone's suggested
making Ruby 2 more consistent about this.

Not so. Just becaue they would default to Klass.new does not mean they
could not be overriden with a variation of functionality -- as is the
case with some of those built in.

T.

Maybe, but how would it work? On what criterion would you override?
You'd want all calls to Klass() with a single argument to be
interpreted as coercion, since one might in principle want to coerce
any object to a <#Klass>. So what do you do when it's natural to call
Klass.new with one argument? Maybe you could work around it, but I'd
be worried you'd be making a messy situation even worse.

I don't object to you doing this with your own classes, I just don't
see a good way of extending this convention to *all* Ruby classes, at
least not without breaking compatibility enough to rule it out for
Ruby 1.x .

Regards,

Jeremy Henty

···

On 2006-07-08, transfire@gmail.com <transfire@gmail.com> wrote:

Jeremy Henty wrote:

... the convention already exists that Klass(x) means "coerce x to
an instance of Klass", rather than "call Klass.new()". As least it
does for many values of Klass, so to make all instances of Klass()
synonyms for Klass.new() would be seriously incompatible.

Not so. Just becaue they would default to Klass.new does not mean
they could not be overriden with a variation of functionality -- as
is the case with some of those built in.

There's no need to introduce complicated rules for this. Just have
Klass() be a synonym for Klass.new() except for the built-in Kernel
methods. Even those could do with some rationalisation.

There are exactly four such methods in Kernel: String(), Integer(),
Float() and Array().

String(), Integer() and Float() coerce their arguments using to_s,
to_i and to_f respectively.

Array() is slightly more complicated trying to_ary, then to_a then
creating a single element array from the arg if the first two fail.

String.new accepts only strings. Integer and Float have no
corresponding new() method (as you yourself pointed out).

I see no reason why String.new couldn't use to_s on its args and why
there couldn't be Integer.new and Float.new with the same
functionality as Integer() and Float().

That only leaves Array.new, which to my mind is not the most intuitive
of methods anyway.
I would argue that it's a source of confusion that Array() and
Array.new behave so differently. However, changing this would break a
lot of code so it's probably best left alone.

I seriously doubt whether having Klass() = Klass.new() would break
much code. I think most people would be surprised to find out you can
even define a method with the same name as a class (I was).

With the scheme I've laid out, the only exception would be Array which
is already somewhat out on its own.

However, as you said, I can do this myself if I want to. I do and I
find it very convenient.

Regards,
Sean

···

On 7/9/06, Jeremy Henty <jeremy@chaos.org.uk> wrote:

On 2006-07-08, transfire@gmail.com <transfire@gmail.com> wrote:
>
> Jeremy Henty wrote:
>
>> ... the convention already exists that Klass(x) means "coerce x to
>> an instance of Klass", rather than "call Klass.new()". As least it
>> does for many values of Klass, so to make all instances of Klass()
>> synonyms for Klass.new() would be seriously incompatible.
>
> Not so. Just becaue they would default to Klass.new does not mean
> they could not be overriden with a variation of functionality -- as
> is the case with some of those built in.

Maybe, but how would it work? On what criterion would you override?
You'd want all calls to Klass() with a single argument to be
interpreted as coercion, since one might in principle want to coerce
any object to a <#Klass>. So what do you do when it's natural to call
Klass.new with one argument? Maybe you could work around it, but I'd
be worried you'd be making a messy situation even worse.

I don't object to you doing this with your own classes, I just don't
see a good way of extending this convention to *all* Ruby classes, at
least not without breaking compatibility enough to rule it out for
Ruby 1.x .

Regards,

Jeremy Henty