Add files to array matching pattern

L

Leon Bogaert

Hi all,

I wanted to simply add files to an array. The files must match a
pattern. I'm just starting with ruby so I really have to find my way in
it. I tried something like:

dir = "/home/leon/images"
test = Array.new
test << Dir.new(dir).entries.each { |x| if 1 == 1 }

Then I wanted to add a sort of if to that last line with a block ( I
think I have to use a block).
I tried this in irb, but it doesn't give an error.

What am I doing wrong here?

Thanks in advance!
 
L

Leon Bogaert

Tried this:

dir = "/home/leon/"; test = Array.new; test =
Dir.new(dir).entries.collect { |x| x == 'filezilla' ? x : next }

But that didn't work also. It gives back:

[nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
nil, nil, nil, nil, nil, nil, nil, nil, nil]
 
L

Leon Bogaert

This would work:

i = 0; dir = "/home/leon/"; test = Array.new; test =
Dir.new(dir).entries.map! { |x| x =~ /filezilla$/ ? x : next };
test.compact

Is the .compact needed? Can't I get rid of that?
 
R

Rob Biedenharn

This would work:

i = 0; dir = "/home/leon/"; test = Array.new; test =
Dir.new(dir).entries.map! { |x| x =~ /filezilla$/ ? x : next };
test.compact

Is the .compact needed? Can't I get rid of that?

test = Dir.entries("/home/leon").grep(/filezilla$/)

-Rob

Rob Biedenharn http://agileconsultingllc.com
(e-mail address removed)
 
7

7stud --

Leon said:
This would work:

i = 0; dir = "/home/leon/"; test = Array.new; test =
Dir.new(dir).entries.map! { |x| x =~ /filezilla$/ ? x : next };
test.compact

Is the .compact needed? Can't I get rid of that?

You can do something like this:

d = "./"
matching_files = Dir.open(d) do |dir|
dir.find_all { |filename| filename == "r8test.rb"}
end
p matching_files


collect puts the return values from the block into an array. With
find_all, if the block returns true, then the current filename is added
to the array.
 
7

7stud --

Leon said:
Tried this:

dir = "/home/leon/"; test = Array.new; test =
Dir.new(dir).entries.collect { |x| x == 'filezilla' ? x : next }

But that didn't work also. It gives back:

[nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
nil, nil, nil, nil, nil, nil, nil, nil, nil]

The reason you get that output is:

1) collect adds the value returned by the block to a results array.

2) There is no file named "filezilla" in the directory /home/leon

3) That means the value of the block is always whatever is produced by
the statement: next. If you try this:

[1, 2, 3].each {|x| puts next}

you'll get the error

r9test.rb:1: void value expression

I think that means that the next statement is one of the few statements
in ruby that doesn't produce a value. So what is the value of the block
when the next statement gets executed as the last statement? If you
try this:

results = [1, 2, 3].collect {|x| next}
p results

the output is:

[nil, nil, nil]

Look familiar? Apparently, a block returns nil by default if the
statements in the block do not produce any values.
 
7

7stud --

Leon said:
This would work:

i = 0; dir = "/home/leon/"; test = Array.new; test =
Dir.new(dir).entries.map! { |x| x =~ /filezilla$/ ? x : next };
test.compact

Is the .compact needed? Can't I get rid of that?

Also, next is used skip the rest of the code in a block. For instance:

(1..4).each do |x|
next if x==2
puts x
end

--output:--
1
3
4

On the other hand, using next as the last statement in a block does
nothing:

(1..4).each do |x|
puts x
next
end

--output:---
1
2
3
4

...except screw up the return value of the block:

results = (1..4).collect do |x|
x if x != 2
next
end

p results

--output:---
[nil, nil, nil, nil]

For methods like collect that use the block's return value, the next
statement ruins the results array.
 
R

Robert Klemme

2007/10/5 said:
This would work:

i = 0; dir = "/home/leon/"; test = Array.new; test =
Dir.new(dir).entries.map! { |x| x =~ /filezilla$/ ? x : next };
test.compact

Is the .compact needed? Can't I get rid of that?

You need it with your code because the map! will map some values to
nil. You probably rather want #select.

files = Dir.new(dir).entries.select { |x| /filezilla$/ =~ x }

But you can have that much easier with

files = Dir["/home/leon/*filezilla"]

Kind regards

robert
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,189
Members
46,734
Latest member
manin

Latest Threads

Top