[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

[OT] sh command that ascends dir tree for executable

Trans

8/12/2006 1:13:00 PM

Before I do and implement this myself, want to make sure it doesn;t
already exist in some fashion: A command line utility like 'sh' but one
that will ascend the directory tree to find the executable.

Thanks,
T.

21 Answers

Jeff Schwab

8/12/2006 5:43:00 PM

0

Trans wrote:
> Before I do and implement this myself, want to make sure it doesn;t
> already exist in some fashion: A command line utility like 'sh' but one
> that will ascend the directory tree to find the executable.

# Caution: On Windows, File.executable? is roughly equivalent to
File.exist?.

def find_program_hierarchically(p)
d = File.expand_path('.')

# Remove drive letter for Windows paths.
d.gsub!(/^[^\/]*/, '')

while d.length != 0
f = "#{d}/#{p}"
return f if File.executable?(f)
d.gsub!(/\/[^\/]*$/, '')
end

return nil
end

puts find_program_hierarchically('main.rb')
puts find_program_hierarchically('nonesuch')
puts find_program_hierarchically('hello.txt')

Ken Bloom

8/13/2006 10:06:00 PM

0

On Sat, 12 Aug 2006 17:43:02 +0000, Jeffrey Schwab wrote:

> Trans wrote:
>> Before I do and implement this myself, want to make sure it doesn;t
>> already exist in some fashion: A command line utility like 'sh' but one
>> that will ascend the directory tree to find the executable.
>
> # Caution: On Windows, File.executable? is roughly equivalent to
> File.exist?.
>
> def find_program_hierarchically(p)
> d = File.expand_path('.')
>
> # Remove drive letter for Windows paths.
> d.gsub!(/^[^\/]*/, '')
>
> while d.length != 0
> f = "#{d}/#{p}"
> return f if File.executable?(f)
> d.gsub!(/\/[^\/]*$/, '')
> end
>
> return nil
> end
>
> puts find_program_hierarchically('main.rb')
> puts find_program_hierarchically('nonesuch')
> puts find_program_hierarchically('hello.txt')

Yuck. Try this simpler code:

require 'pathname'

class Pathname
def ancestors
return [self] if self==parent
return [self] + parent.ancestors
end
end

def find_program_hierarchically(p)
dir=Pathname.getwd.ancestors.find {|d| (d+p).executable?} + p
end

--
Ken Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology.
http://www.iit.edu...

Trans

8/13/2006 10:15:00 PM

0


Thanks Jeffrey and Ken. I was thinking maybe there was a util for this
already but I suppose not. I wrote code like this:

Dir.chdir('..') until File.exectuable?( file )

It does change the directory, but for my purposes that's okay. See any
problems with that? Work with Windows okay?

Thanks,
T.

Jeff Schwab

8/13/2006 10:56:00 PM

0

Trans wrote:
> Thanks Jeffrey and Ken. I was thinking maybe there was a util for this
> already but I suppose not. I wrote code like this:
>
> Dir.chdir('..') until File.exectuable?( file )
>
> It does change the directory, but for my purposes that's okay. See any
> problems with that? Work with Windows okay?

It'll loop forever if the file doesn't exist.

Jeff Schwab

8/13/2006 11:01:00 PM

0

Ken Bloom wrote:
> On Sat, 12 Aug 2006 17:43:02 +0000, Jeffrey Schwab wrote:
>
>> Trans wrote:
>>> Before I do and implement this myself, want to make sure it doesn;t
>>> already exist in some fashion: A command line utility like 'sh' but one
>>> that will ascend the directory tree to find the executable.
>> # Caution: On Windows, File.executable? is roughly equivalent to
>> File.exist?.
>>
>> def find_program_hierarchically(p)
>> d = File.expand_path('.')
>>
>> # Remove drive letter for Windows paths.
>> d.gsub!(/^[^\/]*/, '')
>>
>> while d.length != 0
>> f = "#{d}/#{p}"
>> return f if File.executable?(f)
>> d.gsub!(/\/[^\/]*$/, '')
>> end
>>
>> return nil
>> end
>>
>> puts find_program_hierarchically('main.rb')
>> puts find_program_hierarchically('nonesuch')
>> puts find_program_hierarchically('hello.txt')
>
> Yuck.

Thanks. :)

> Try this simpler code:
>
> require 'pathname'
>
> class Pathname
> def ancestors
> return [self] if self==parent
> return [self] + parent.ancestors
> end
> end
>
> def find_program_hierarchically(p)
> dir=Pathname.getwd.ancestors.find {|d| (d+p).executable?} + p
> end

I'm not convinced that's simpler. It's the same number of lines, brings
in an extra module, is recursive, and stuffs seven distinct identifiers
onto a single line. It does look nicer at first glance, though, since
it uses much less punctuation.

Trans

8/13/2006 11:14:00 PM

0


Jeffrey Schwab wrote:
> Trans wrote:
> > Thanks Jeffrey and Ken. I was thinking maybe there was a util for this
> > already but I suppose not. I wrote code like this:
> >
> > Dir.chdir('..') until File.exectuable?( file )
> >
> > It does change the directory, but for my purposes that's okay. See any
> > problems with that? Work with Windows okay?
>
> It'll loop forever if the file doesn't exist.

Dir.chdir('..') until File.exectuable?( file ) or Dir.pwd == '/'

Will that work on Windows? If not what do I need to match?

Thanks,
T.

Jeff Schwab

8/13/2006 11:37:00 PM

0

Trans wrote:
> Jeffrey Schwab wrote:
>> Trans wrote:
>>> Thanks Jeffrey and Ken. I was thinking maybe there was a util for this
>>> already but I suppose not. I wrote code like this:
>>>
>>> Dir.chdir('..') until File.exectuable?( file )
>>>
>>> It does change the directory, but for my purposes that's okay. See any
>>> problems with that? Work with Windows okay?
>> It'll loop forever if the file doesn't exist.
>
> Dir.chdir('..') until File.exectuable?( file ) or Dir.pwd == '/'
>
> Will that work on Windows? If not what do I need to match?

'Fraid not. Windows filesystems don't allow mounting the way Unix
filesystems do, so you end up with multiple "root" directories whose
names include letters and colons. E.g., you probably know that the hard
drive of most PCs is called "C:\".

Pathname.root? seemed promising, but it doesn't work properly on
Windows, either. :( Windows isn't a very good collection of operating
systems, and I think most Ruby developers are smart enough to avoid it.

Ken Bloom

8/14/2006 4:58:00 AM

0

On Sun, 13 Aug 2006 23:36:51 +0000, Jeffrey Schwab wrote:

> Trans wrote:
>> Jeffrey Schwab wrote:
>>> Trans wrote:
>>>> Thanks Jeffrey and Ken. I was thinking maybe there was a util for this
>>>> already but I suppose not. I wrote code like this:
>>>>
>>>> Dir.chdir('..') until File.exectuable?( file )
>>>>
>>>> It does change the directory, but for my purposes that's okay. See any
>>>> problems with that? Work with Windows okay?
>>> It'll loop forever if the file doesn't exist.
>>
>> Dir.chdir('..') until File.exectuable?( file ) or Dir.pwd == '/'
>>
>> Will that work on Windows? If not what do I need to match?
>
> 'Fraid not. Windows filesystems don't allow mounting the way Unix
> filesystems do, so you end up with multiple "root" directories whose
> names include letters and colons. E.g., you probably know that the hard
> drive of most PCs is called "C:\".
>
> Pathname.root? seemed promising, but it doesn't work properly on
> Windows, either. Windows isn't a very good collection of operating
> systems, and I think most Ruby developers are smart enough to avoid it.

Does Pathname.getwd.parent==Pathname.getwd work on Windows?
I didn't realize there was Pathname.root? for me to use it would probably
have simplified things in my code a lot.

--Ken

--
Ken Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology.
http://www.iit.edu...

Ken Bloom

8/14/2006 4:59:00 AM

0

On Sun, 13 Aug 2006 23:01:19 +0000, Jeffrey Schwab wrote:

> Ken Bloom wrote:
>> On Sat, 12 Aug 2006 17:43:02 +0000, Jeffrey Schwab wrote:
>>
>>> Trans wrote:
>>>> Before I do and implement this myself, want to make sure it doesn;t
>>>> already exist in some fashion: A command line utility like 'sh' but one
>>>> that will ascend the directory tree to find the executable.
>>> # Caution: On Windows, File.executable? is roughly equivalent to
>>> File.exist?.
>>>
>>> def find_program_hierarchically(p)
>>> d = File.expand_path('.')
>>>
>>> # Remove drive letter for Windows paths.
>>> d.gsub!(/^[^\/]*/, '')
>>>
>>> while d.length != 0
>>> f = "#{d}/#{p}"
>>> return f if File.executable?(f)
>>> d.gsub!(/\/[^\/]*$/, '')
>>> end
>>>
>>> return nil
>>> end
>>>
>>> puts find_program_hierarchically('main.rb')
>>> puts find_program_hierarchically('nonesuch')
>>> puts find_program_hierarchically('hello.txt')
>>
>> Yuck.
>
> Thanks.
>
>> Try this simpler code:
>>
>> require 'pathname'
>>
>> class Pathname
>> def ancestors
>> return [self] if self==parent
>> return [self] + parent.ancestors
>> end
>> end
>>
>> def find_program_hierarchically(p)
>> dir=Pathname.getwd.ancestors.find {|d| (d+p).executable?} + p
>> end
>
> I'm not convinced that's simpler. It's the same number of lines, brings
> in an extra module, is recursive, and stuffs seven distinct identifiers
> onto a single line. It does look nicer at first glance, though, since
> it uses much less punctuation.

I have a habit of writing really really long one-liners.

--Ken

--
Ken Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology.
http://www.iit.edu...

Jeff Schwab

8/14/2006 12:17:00 PM

0

Ken Bloom wrote:
> On Sun, 13 Aug 2006 23:36:51 +0000, Jeffrey Schwab wrote:
>
>> Trans wrote:
>>> Jeffrey Schwab wrote:
>>>> Trans wrote:
>>>>> Thanks Jeffrey and Ken. I was thinking maybe there was a util for this
>>>>> already but I suppose not. I wrote code like this:
>>>>>
>>>>> Dir.chdir('..') until File.exectuable?( file )
>>>>>
>>>>> It does change the directory, but for my purposes that's okay. See any
>>>>> problems with that? Work with Windows okay?
>>>> It'll loop forever if the file doesn't exist.
>>> Dir.chdir('..') until File.exectuable?( file ) or Dir.pwd == '/'
>>>
>>> Will that work on Windows? If not what do I need to match?
>> 'Fraid not. Windows filesystems don't allow mounting the way Unix
>> filesystems do, so you end up with multiple "root" directories whose
>> names include letters and colons. E.g., you probably know that the hard
>> drive of most PCs is called "C:\".
>>
>> Pathname.root? seemed promising, but it doesn't work properly on
>> Windows, either. Windows isn't a very good collection of operating
>> systems, and I think most Ruby developers are smart enough to avoid it.
>
> Does Pathname.getwd.parent==Pathname.getwd work on Windows?
> I didn't realize there was Pathname.root? for me to use it would probably
> have simplified things in my code a lot.

Not quite, but it's a great idea! You might want to sit down for this one:

C:\>ruby -rpathname -e 'puts Pathname.getwd'
C:/

C:\>ruby -rpathname -e 'puts Pathname.getwd.parent'
C:/..

Could you live with something like this, or are the regex/string
manipulation/punctuation just too ugly?

file = ARGV.shift

Dir.chdir('..') until File.executable?(file) or
Dir.getwd =~ /^(?:\w:)?[\/\.]*$/

puts Dir.getwd.gsub(/\/$/, '') + '/' + file if File.executable?(file)