Special Array method about Unix pathes

here is the goal:

i’ve an Array of Unix pathes :
forbidden = ["/Volumes/U3 System",
“/Volumes/EMTEC KEY/emtec_dl”,
“/Volumes/EMTEC KEY/emtec_dl/Win98SE new driver.exe”,
“/Volumes/EMTEC KEY/emtec_dl/v233r001”
]

i want to forbid access to those pathes BUT since, for example,
“/Volumes/EMTEC KEY/emtec_dl/Win98SE new driver.exe” « belongs »
to the path (it’s below this path) “/Volumes/EMTEC KEY/emtec_dl”
it is unusefull to have it in the Array.

in the case above i’d like to return :

forbidden = ["/Volumes/U3 System",
“/Volumes/EMTEC KEY/emtec_dl”
]

what i’ve done :

class Array
def includePath?(path)
self.each { | x |
return true if path.startsWith?(x)
}
return false
end
def getContainers!
self.delete_if { | x | ( self - [ x ] ).includePath?( x ) }
end
end

class String
def startsWith?(dir)
self.index(dir) === 0
end
end

then forbidden.getContainers! gives me the expected result.

what do you think about this solution ?
could you propose a better one ?

also, because english isn’t my mother tongue, are my methods naming
correct ?

Une Bévue wrote:

“/Volumes/EMTEC KEY/emtec_dl/Win98SE new driver.exe” « belongs »

end
what do you think about this solution ?
could you propose a better one ?

also, because english isn’t my mother tongue, are my methods naming
correct ?

Array doesn’t seem the proper class to have a includePath? method,
otherwise the names look reasonable. If the method is in Array, then a
reasonable name might be includesStart?

Charles D Hixson wrote:

 self.each { | x |
   return true if path.startsWith?(x)
 }
 return false

self.any? {|x| path.starts_with?(x) }

HTH,
Sebastian

Sebastian H. [email protected] wrote:

self.any? {|x| path.starts_with?(x) }

fine thanks, i didn’t know the #any?

Charles D Hixson [email protected] wrote:

Array doesn’t seem the proper class to have a includePath? method,
otherwise the names look reasonable.

i’ll lokk if there is something more related to Unix pathes…

If the method is in Array, then a
reasonable name might be includesStart?

OK, thanks!

Alle mercoledì 19 settembre 2007, Une Bévue ha scritto:

“/Volumes/EMTEC KEY/emtec_dl/Win98SE new driver.exe” « belongs »

end
what do you think about this solution ?
could you propose a better one ?

also, because english isn’t my mother tongue, are my methods naming
correct ?

This is my alternative solution:

def select_toplevel_paths arg
a = arg.dup.sort_by{|i| i.size}
a.inject([]) do |res, i|
res.any?{|j| i.index(j) == 0 } ? res : (res << i)
end
end

It doesn’t change the contents of the array and it’s not a method of
class
Array, because, in my opinion, it’s a too specialized method to be put
in a
core class.

Regarding your code, I’d say names are correct, as far as English is
concerned. I’d like to give you a copule of suggestions:

  • use underscores instead of camel-case (include_path? instead of
    includePath,
    for example), because it’s the more common style in the ruby community
  • use start_with? instead of starts_with?. In the ruby standard library,
    there
    are several cases in which both methods exist, with the ones ending in s
    being
    obsolete (for example, File.exists? and File.exist?) For consistency, I
    think
    it’s better to follow the same convention.

Stefano

Hi,

At Thu, 20 Sep 2007 03:24:58 +0900,
Stefano C. wrote in [ruby-talk:269890]:

def select_toplevel_paths arg
a = arg.dup.sort_by{|i| i.size}
a.inject([]) do |res, i|
res.any?{|j| i.index(j) == 0 } ? res : (res << i)

i.rindex(j, 0) is faster than i.index(j) == 0 when j matches in
the middle.

  • use start_with? instead of starts_with?. In the ruby standard library, there
    are several cases in which both methods exist, with the ones ending in s being
    obsolete (for example, File.exists? and File.exist?) For consistency, I think
    it’s better to follow the same convention.

And ruby 1.9 has String#start_with? already in fact.

Stefano C. [email protected] wrote:

This is my alternative solution:

def select_toplevel_paths arg
a = arg.dup.sort_by{|i| i.size}
a.inject([]) do |res, i|
res.any?{|j| i.index(j) == 0 } ? res : (res << i)
end
end

clever solution, thanks a lot !

however with the following (part of a yaml file) :

forbiddenList:

  • /Volumes/EMTEC KEY/emtec_dl
  • /Volumes/EMTEC KEY/emtec_dl/v233r001/Setup.exe
  • /Volumes/U3 System
  • /Volumes/U3 System/Launchpad.zip

your select_toplevel_paths don’t remove /Volumes/EMTEC
KEY/emtec_dl/v233r001/Setup.exe and /Volumes/U3 System/Launchpad.zip

It doesn’t change the contents of the array and it’s not a method of class
Array, because, in my opinion, it’s a too specialized method to be put in a
core class.

U’re right, i was embarassed with that point.

Regarding your code, I’d say names are correct, as far as English is
concerned. I’d like to give you a copule of suggestions:

  • use underscores instead of camel-case (include_path? instead of includePath,
    for example), because it’s the more common style in the ruby community
  • use start_with? instead of starts_with?. In the ruby standard library, there
    are several cases in which both methods exist, with the ones ending in s being
    obsolete (for example, File.exists? and File.exist?) For consistency, I think
    it’s better to follow the same convention.

OK, done !

2007/9/19, Sebastian H. [email protected]:

Charles D Hixson wrote:

self.each { | x |
return true if path.startsWith?(x)
}
return false

self.any? {|x| path.starts_with?(x) }

You can even leave the “self.” out. :slight_smile:

I can think of several approaches to solve this:

  1. order the array and do a second iteration where each item is
    checked against the last seen prefix; the idea is that every string
    comes before the strings that contain it as prefix.

  2. insert names into a tree and output only prefixes during a tree walk.

Bévue, the only issue I see with your method naming is that in Ruby
methods typically use under_scores and not CamelCase as in Java.

Kind regards

robert

Robert K. [email protected] wrote:

You can even leave the “self.” out. :slight_smile:

OK !

I can think of several approaches to solve this:

  1. order the array and do a second iteration where each item is
    checked against the last seen prefix; the idea is that every string
    comes before the strings that contain it as prefix.

fine, the Array is allready ordered elsewhere, i thought putting sort!
in this method ))

  1. insert names into a tree and output only prefixes during a tree walk.

ok, i see what you mean, may be better not to do that when output rather
than when building the three having a means to compare three deepness.

Bévue, the only issue I see with your method naming is that in Ruby
methods typically use under_scores and not CamelCase as in Java.

Yes i’ve corrected that, it’s an habit coming from java, as the getter
“getContainers!”…

Alle mercoledì 19 settembre 2007, Une Bévue ha scritto:

forbiddenList:

  • /Volumes/EMTEC KEY/emtec_dl
  • /Volumes/EMTEC KEY/emtec_dl/v233r001/Setup.exe
  • /Volumes/U3 System
  • /Volumes/U3 System/Launchpad.zip

your select_toplevel_paths don’t remove /Volumes/EMTEC
KEY/emtec_dl/v233r001/Setup.exe and /Volumes/U3 System/Launchpad.zip

It works for me:

irb: 001> def select_toplevel_path arg
irb: 002+> a = arg.dup.sort_by{|i| i.size}
irb: 003+> a.inject([]) do |res, i|
irb: 004*> res.any?{|j| i[0, j.size] == j} ? res : (res << i)
irb: 005+> end
irb: 006+> end
nil
irb: 007> forbidden = ["/Volumes/EMTEC KEY/emtec_dl",
irb: 008*> “/Volumes/EMTEC KEY/emtec_dl/v233r001/Setup.exe”,
irb: 009*> “/Volumes/U3 System”,
irb: 010*> “/Volumes/U3 System/Launchpad.zip”
irb: 011+> ]
["/Volumes/EMTEC KEY/emtec_dl", “/Volumes/EMTEC
KEY/emtec_dl/v233r001/Setup.exe”, “/Volumes/U3 System”, “/Volumes/U3
System/Launchpad.zip”]
irb: 012> select_toplevel_path forbidden
["/Volumes/U3 System", “/Volumes/EMTEC KEY/emtec_dl”]

Notice that this doesn’t change the forbidden array, but creates a new
one.

Stefano

Une Bévue [email protected] wrote:

KEY/emtec_dl/v233r001/Setup.exe and /Volumes/U3 System/Launchpad.zip
sorry, in fact that works wheb used as :

forbidden = [
“/Volumes/U3 System”,
“/Volumes/EMTEC KEY/emtec_dl”,
“/Volumes/EMTEC KEY/emtec_dl/Win98SE new driver.exe”,
“/Volumes/EMTEC KEY/emtec_dl/v233r001/Setup.exe”,
“/Volumes/EMTEC KEY/emtec_dl/v233r001”,
“/Volumes/U3 System/LaunchU3.exe”,
“/Volumes/U3 System/Launchpad.zip”
]

p forbidden
forbidden = select_toplevel_paths( forbidden )
p forbidden

but not when used in a class :

class SyncDataSource < OSX::NSObject

def initialize

[…]

    @forbiddenList = [ ]

[…]

end

[…]

def addForbidden( notification )

[…]

    p @forbiddenList
    @forbiddenList = select_toplevel_paths( @forbiddenList )
    p @forbiddenList

[…]

end

end

i don’t understand why for the time being…

On 19.09.2007 21:26, Une Bévue wrote:

Robert K. [email protected] wrote:

I can think of several approaches to solve this:

  1. order the array and do a second iteration where each item is
    checked against the last seen prefix; the idea is that every string
    comes before the strings that contain it as prefix.

fine, the Array is allready ordered elsewhere, i thought putting sort!
in this method ))

If it’s sorted anyway that’s probably the approach I’d take.

  1. insert names into a tree and output only prefixes during a tree walk.

ok, i see what you mean, may be better not to do that when output rather
than when building the three having a means to compare three deepness.

I am not sure what you mean here. You have to build the tree first
before you can decide which branches you can omit. With “output” I did
not necessarily mean output to screen, but rather output from the
method. Maybe I should have chosen a different wording. I am sorry if
that caused confusion.

Bévue, the only issue I see with your method naming is that in Ruby
methods typically use under_scores and not CamelCase as in Java.

Yes i’ve corrected that, it’s an habit coming from java, as the getter
“getContainers!”…

Different languages, different conventions. :slight_smile:

Kind regards

robert

Une Bévue <unbewusst.sein wortanschahung.com.invalid> writes:

 self.delete_if { | x | ( self - [ x ] ).includePath?( x ) }

end
end

In contrast to everyone else’s points about your naming, I’m not happy
with your
implementation.

/home/gareth/files/my_file
is not a child of
/home/gareth/fil

Gareth

Robert K. [email protected] wrote:

ok, i see what you mean, may be better not to do that when output rather
than when building the three having a means to compare three deepness.

I am not sure what you mean here. You have to build the tree first
before you can decide which branches you can omit. With “output” I did
not necessarily mean output to screen, but rather output from the
method. Maybe I should have chosen a different wording. I am sorry if
that caused confusion.

i’ve found a simpler approach, in fact, this list of pathes is entered
by the user using a File/folder chooser window, then instead of walking
a three or something else, xhen the user enter a new path right now i
check only if this path is allready taken into account by :

files.each { |f|
f_to_s = f.to_s
@forbiddenList << f_to_s unless @forbiddenList.include_path?( f_to_s )
}

with :
files the File(s)/Folder(s) entered by the user ;
f.to_s converting NSString to Ruby String (NS stands for NextStep) ;
Array#include_path?( a_path ) being :
class Array
def include_path?(path)
self.any? { | x | a_path.rindex( x, 0 ) }
end
end

the only thing i dislike is in that pathes have nothing to do with
Array,i must rexrite this part.

Bévue, the only issue I see with your method naming is that in Ruby
methods typically use under_scores and not CamelCase as in Java.

Yes i’ve corrected that, it’s an habit coming from java, as the getter
“getContainers!”…

Different languages, different conventions. :slight_smile:

yes right, here i’m embarassed because my code isn’t “pure” Ruby, it’s
RubyCocoa (a bridge between Cocoa/ObjC on Mac OS X) and in RubyCocoa the
Cocoa methods like :

NSOpenPanel#beginSheetForDirectory:file:types:modalForWindow:modalDelega
te:didEndSelector:contextInfo:

are translated, on the Ruby side, in :

beginSheetForDirectory_file_types_modalForWindow_modalDelegate_didEndSel
ector:contextInfo( … )

then “_” replaces “:” and still camelized…