[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

Handling of arrays

Clement Ow

5/12/2008 9:00:00 AM

A snippet of my code are as follows:
$selections = ["*","*"]
$file_exception = ["RiskViewer*","*.xls"]

$source = ["C:/Test", "C:/Test"]

$dest = ["U:/Test","U:/Test"]


sd_a=$source.zip($dest,$selections,$file_exception)

sd_a.each do |sd|
$source, $destination, $selections, $file_exception = sd
src = File.join $source, $selections
puts src
d= $d1
dst= File.join $destination, d
test = File.join $source, $file_exception
src1 = Dir.glob(src) - Dir.glob(test)

Dir.glob(src1) do |file|
FileUtils.mv file, dst

I'm developing a script to move files to the dest paths. But however, i
only can put one exception for each file path, but sometimes on some
scenarios I'll need to to have 2 exceptions in one file path, hence the
above code.
But the problem with the code is that it executes it twice and by doin
that moves everything already except for the riskviewer files. And on
the 2nd time it runs, all the files have been moved already.

So is there any way whereby the script will check for 2 or more
exceptions before executing the move command, presume that we still use
arrays? Thanks in advance for any help rendered!
--
Posted via http://www.ruby-....

14 Answers

Jesús Gabriel y Galán

5/12/2008 12:32:00 PM

0

On Mon, May 12, 2008 at 11:00 AM, Clement Ow
<clement.ow@asia.bnpparibas.com> wrote:
> A snippet of my code are as follows:
> $selections = ["*","*"]
> $file_exception = ["RiskViewer*","*.xls"]
>
> $source = ["C:/Test", "C:/Test"]
>
> $dest = ["U:/Test","U:/Test"]
>
>
> sd_a=$source.zip($dest,$selections,$file_exception)
>
> sd_a.each do |sd|
> $source, $destination, $selections, $file_exception = sd
> src = File.join $source, $selections
> puts src
> d= $d1
> dst= File.join $destination, d
> test = File.join $source, $file_exception

Untested but change this:

> src1 = Dir.glob(src) - Dir.glob(test)

to:

src1 = $file_exception.inject(Dir.glob(src)) {|result, ex| result -
Dir.glob(ex)}

Also, doing a Dir.glob for each exception can be a lot, why not use
regular expressions
to remove from the result of the first glob? You will have to change
the exceptions
a little bit, but it might be worth it:

["\.txt", "\.sql"].inject(Dir.glob("/home/jesus/*")) {|result, ex|
result.reject{|x| x =~ Regexp.new(ex)}}

This removes from my home folder all files that match ".txt" and ".sql"

Hope this helps,

Jesus.

Clement Ow

5/13/2008 3:22:00 AM

0

Jesús Gabriel y Galán wrote:
> On Mon, May 12, 2008 at 11:00 AM, Clement Ow
> <clement.ow@asia.bnpparibas.com> wrote:
>>
>> sd_a.each do |sd|
>> $source, $destination, $selections, $file_exception = sd
>> src = File.join $source, $selections
>> puts src
>> d= $d1
>> dst= File.join $destination, d
>> test = File.join $source, $file_exception
>
> Untested but change this:
>
>> src1 = Dir.glob(src) - Dir.glob(test)
>
> to:
>
> src1 = $file_exception.inject(Dir.glob(src)) {|result, ex| result -
> Dir.glob(ex)}
>
> Also, doing a Dir.glob for each exception can be a lot, why not use
> regular expressions
> to remove from the result of the first glob? You will have to change
> the exceptions
> a little bit, but it might be worth it:
>
> ["\.txt", "\.sql"].inject(Dir.glob("/home/jesus/*")) {|result, ex|
> result.reject{|x| x =~ Regexp.new(ex)}}
>
> This removes from my home folder all files that match ".txt" and ".sql"
>
> Hope this helps,
>
> Jesus.

Hi Jesus,
nice slick code there using regexp ;) just wondering if there would be a
possibility of having a different set of file exceptions for different
file paths. cause at the moment, there can only be one specific file
exceptions for every file path, which might be hard in the event where
we would need to cater to different source paths. Prolly a few arrays in
file exception?
--
Posted via http://www.ruby-....

Jesús Gabriel y Galán

5/13/2008 9:42:00 AM

0

On Tue, May 13, 2008 at 5:22 AM, Clement Ow
<clement.ow@asia.bnpparibas.com> wrote:
> Jes=FAs Gabriel y Gal=E1n wrote:
> > On Mon, May 12, 2008 at 11:00 AM, Clement Ow
> > <clement.ow@asia.bnpparibas.com> wrote:
> >>
>
> >> sd_a.each do |sd|
> >> $source, $destination, $selections, $file_exception =3D sd
> >> src =3D File.join $source, $selections
> >> puts src
> >> d=3D $d1
> >> dst=3D File.join $destination, d
> >> test =3D File.join $source, $file_exception
> >
> > Untested but change this:
> >
> >> src1 =3D Dir.glob(src) - Dir.glob(test)
> >
> > to:
> >
> > src1 =3D $file_exception.inject(Dir.glob(src)) {|result, ex| result -
> > Dir.glob(ex)}
> >
> > Also, doing a Dir.glob for each exception can be a lot, why not use
> > regular expressions
> > to remove from the result of the first glob? You will have to change
> > the exceptions
> > a little bit, but it might be worth it:
> >
> > ["\.txt", "\.sql"].inject(Dir.glob("/home/jesus/*")) {|result, ex|
> > result.reject{|x| x =3D~ Regexp.new(ex)}}
> >
> > This removes from my home folder all files that match ".txt" and ".sql=
"
> >
> > Hope this helps,
> >
> > Jesus.
>
> Hi Jesus,
> nice slick code there using regexp ;) just wondering if there would be a
> possibility of having a different set of file exceptions for different
> file paths. cause at the moment, there can only be one specific file
> exceptions for every file path, which might be hard in the event where
> we would need to cater to different source paths. Prolly a few arrays in
> file exception?

If what you want is to associate different information to each source path,
I would look into a hash of hashes or a hash of arrays, or a hash of struct=
s,
where you could have a complex object for the info related to an entity of
your program. For example:

A hash of arrays, if you only need exceptions:

exceptions_by_path =3D {}
exceptions_by_path["/home/jesus"] =3D ["\.txt", "\.sql"]
exceptions_by_path["/home/jesus/applications"] =3D ["\.sh", "\.bin"]
# [...]

and then

paths.each do |path|
files =3D exceptions_by_path.inject(Dir.glob("#{path}/*")) {|result,
ex| result.reject{|x| x =3D~ Regexp.new(ex)}}
end

If for a path you need several different things, I would go with a
Struct or a custom class:

FileInfo =3D Struct.new :exceptions, :other_value, :yet_another
paths_info =3D {}
paths_info["/home/jesus"] =3D FileInfo.new(["\.txt", "\.sql"], "other
value", "another")

and then access the exceptions array as paths_info["/home/jesus"].exception=
s
and use it as before.

Hope this helps,

Jesus.

Clement Ow

5/14/2008 4:38:00 AM

0

Jesús Gabriel y Galán wrote:
>
> Hope this helps,
>
> Jesus.

thanks Jesus, that was really helpful! However I altered the code alil
cause ruby rendered an error to me saying that it cant convert Array
into string (hmmm, dunno if that's normal) for this line(suppose it's
for the arrays in the hash, exceptions_by_path):
>files = exceptions_by_path.inject(Dir.glob("#{path}/*")) {|result,
ex| result.reject{|x| x =~ Regexp.new(ex)}}

So i decided to name my arays in the hash, file_exception[0],
file_exception[1] ... and used this instead with an incremental value:

>>i = 0
>> src1 = $file_exception[i].inject(Dir.glob(src)) {|result, >>ex|result.reject{|x| x =~ Regexp.new(ex)}}
>> i = 1 + i

But i had the problem of accidentally keyin in the a wrong path name and
nothing was shown for the 2nd source path.(Only after troubleshooting
for 1 whole hr did i realise) So is there any way where by we can have a
condition something like, if result == nil puts "wrong pathname"(just an
idea, cos i tried and it doesnt work)

And btw dont get me wrong, Struct is sweet too, just that i didnt want
to have a fixed number of exceptions for each path. ;)

Thanks again.
--
Posted via http://www.ruby-....

Clement Ow

5/14/2008 7:46:00 AM

0

Also, I have problems making some file exceptions. For example, i ahve
some files that start with 2007 which goes something like, 20070131 and
a file which is called "Risk 20070131" but when i put 2007 in the
file_exception variable, it deselects any file that has 2007 in the
filename, which not what i want. I know that the regexp doesnt allow any
like 2007* to be put in the file_exception to deselect any file which
starts with 2007. Any ideas at all, anyone?

Regards
--
Posted via http://www.ruby-....

Jesús Gabriel y Galán

5/14/2008 1:10:00 PM

0

On Wed, May 14, 2008 at 6:38 AM, Clement Ow
<clement.ow@asia.bnpparibas.com> wrote:
> Jes=FAs Gabriel y Gal=E1n wrote:
> >
> > Hope this helps,
> >
> > Jesus.
>
> thanks Jesus, that was really helpful! However I altered the code alil
> cause ruby rendered an error to me saying that it cant convert Array
> into string (hmmm, dunno if that's normal) for this line(suppose it's
> for the arrays in the hash, exceptions_by_path):
>
> >files =3D exceptions_by_path.inject(Dir.glob("#{path}/*")) {|result,
> ex| result.reject{|x| x =3D~ Regexp.new(ex)}}

Sorry, that's what I get for not testing the code. I think (I'm a bit
dense right
now, so this might not work) that what I meant was this:

exceptions_by_path =3D {}
exceptions_by_path["/home/jesus"] =3D ["\.txt", "\.sql"]
exceptions_by_path["/home/jesus/applications"] =3D ["\.sh", "\.bin"]
# [...]

and then

paths.each do |path|
files =3D exceptions_by_path[path].inject(Dir.glob("#{path}/*")) {|result=
,
ex| result.reject{|x| x =3D~ Regexp.new(ex)}}
end

so you get the exceptions for that path, which is an Array that should
work with
inject as I was expecting.

> And btw dont get me wrong, Struct is sweet too, just that i didnt want
> to have a fixed number of exceptions for each path. ;)

FileInfo =3D Struct.new :exceptions, :other_value, :yet_another
paths_info =3D {}
paths_info["/home/jesus"] =3D FileInfo.new(["\.txt", "\.sql"], "other
value", "another")

The number of exceptions is not fixed, as you can see above,
I am storing an array in the :exceptions field, so each path can
have a different number of exception patterns.

Jesus.

Jesús Gabriel y Galán

5/14/2008 1:13:00 PM

0

On Wed, May 14, 2008 at 9:46 AM, Clement Ow
<clement.ow@asia.bnpparibas.com> wrote:
> Also, I have problems making some file exceptions. For example, i ahve
> some files that start with 2007 which goes something like, 20070131 and
> a file which is called "Risk 20070131" but when i put 2007 in the
> file_exception variable, it deselects any file that has 2007 in the
> filename, which not what i want. I know that the regexp doesnt allow any
> like 2007* to be put in the file_exception to deselect any file which
> starts with 2007. Any ideas at all, anyone?

I'm not sure if I'm understanding you correctly, but you can tweak the
regexps so that they actually match what you want. If you want
to deselect only the files that start with 2007 you can do this:

irb(main):001:0> a = %w{20071212 20073445 risk20072341}
=> ["20071212", "20073445", "risk20072341"]
irb(main):003:0> a.reject {|x| x =~ /\A2007/}
=> ["risk20072341"]

Jesus.

Clement Ow

5/15/2008 1:48:00 AM

0

>Sorry, that's what I get for not testing the code. I think (I'm a bit
>dense right
>now, so this might not work) that what I meant was this:

Nah, it's fine, we all know it can get a lil tiring sometimes. As it is
with this script im writing lol.

> files = exceptions_by_path[path].inject(Dir.glob("#{path}/*"))
>{|result,
>ex| result.reject{|x| x =~ Regexp.new(ex)}}
>end

>so you get the exceptions for that path, which is an Array that should
>work with
>inject as I was expecting.

Anw, I get what you mean, but because Im using a config file to hold all
the source paths, dest paths and the file exceptions, which is keyed in
by the user, I dont wanna make it too complicated to fill in the paths,
so i decided to just use numbers to name the arrays in the hash.

> I'm not sure if I'm understanding you correctly, but you can tweak the
> regexps so that they actually match what you want. If you want
> to deselect only the files that start with 2007 you can do this:
>
> irb(main):001:0> a = %w{20071212 20073445 risk20072341}
> => ["20071212", "20073445", "risk20072341"]
> irb(main):003:0> a.reject {|x| x =~ /\A2007/}
> => ["risk20072341"]

Oh yea, i did try this but it doesnt work, somehow *scratches head* It
just shows all files to be moved, and it obviously did not carry out the
exceptions. But if it's done this way, there wont be any point in keying
in the various different exceptions alr, hence i got stuck. :/
--
Posted via http://www.ruby-....

Clement Ow

5/15/2008 3:05:00 AM

0

>> I'm not sure if I'm understanding you correctly, but you can tweak the
>> regexps so that they actually match what you want. If you want
>> to deselect only the files that start with 2007 you can do this:
>>
>> irb(main):001:0> a = %w{20071212 20073445 risk20072341}
>> => ["20071212", "20073445", "risk20072341"]
>> irb(main):003:0> a.reject {|x| x =~ /\A2007/}
>> => ["risk20072341"]
>
> Oh yea, i did try this but it doesnt work, somehow *scratches head* It
> just shows all files to be moved, and it obviously did not carry out the
> exceptions. But if it's done this way, there wont be any point in keying
> in the various different exceptions alr, hence i got stuck. :/

Oh i realise what was wrong in the matching of this regexp, because in:
>files = exceptions_by_path[path].inject(Dir.glob("#{path}/*"))
>{|result,
>ex| result.reject{|x| x =~ Regexp.new(ex)}}
>end
After much playing around with this statement,result here is the whole
path name, which apparently doesnt match the filename itself, hence
making /\A2007/ not able to work. (prolly need to use
File.basename(result)) But can you do me a favour by explaining what
this statement means as I dunno how come some variables assigned to
certain commands etc.? Thanks!
--
Posted via http://www.ruby-....

Clement Ow

5/15/2008 7:46:00 AM

0

Clement Ow wrote:

>> Oh yea, i did try this but it doesnt work, somehow *scratches head* It
>> just shows all files to be moved, and it obviously did not carry out the
>> exceptions. But if it's done this way, there wont be any point in keying
>> in the various different exceptions alr, hence i got stuck. :/
>
> Oh i realise what was wrong in the matching of this regexp, because in:
>>files = exceptions_by_path[path].inject(Dir.glob("#{path}/*"))
>>{|result,
>>ex| result.reject{|x| x =~ Regexp.new(ex)}}
>>end
I found what is actually goin on in this statement. because x is the
whole path name eg. //sins1234/home/file_name the regexp, /\A2007/
doesnt match the beginning of the string. And also the exceptions array
must have "\\A2007" when passing it into Regexp.new. So my code now
looks like this:

>>>src1 = $file_exception[i].inject(Dir.glob(src)) {|result, ex|result.reject
>>>{|x| File.basename(x) =~ Regexp.new(ex, Regexp::IGNORECASE)}}
>>>Dir.glob(src1).each do |file|
>>> #do sth
>>>end
> After much playing around with this statement,result here is the whole
> path name, which apparently doesnt match the filename itself, hence
> making /\A2007/ not able to work. (prolly need to use
> File.basename(result)) But can you do me a favour by explaining what
> this statement means as I dunno how come some variables assigned to
> certain commands etc.? Thanks!

However, for education sake, do u mind explaining how the whole inject
statement works? thanks! ;)
--
Posted via http://www.ruby-....