Add files to array matching pattern

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!

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]

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?

On Oct 4, 2007, at 7:35 PM, Leon B. wrote:

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 B. http://agileconsultingllc.com
[email protected]

Leon B. wrote:

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.

Leon B. wrote:

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.

2007/10/5, Leon B. [email protected]:

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

Leon B. wrote:

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.