# Add files to array matching pattern

**URL:** <https://www.ruby-forum.com/t/add-files-to-array-matching-pattern/116381>\
**Category:** Ruby\
**Created:** [October 5, 2007, 1:08am UTC](https://www.ruby-forum.com/t/add-files-to-array-matching-pattern/116381 "2007-10-05T01:08:55Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![leonb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/22d042/32.png) [@leonb](https://www.ruby-forum.com/u/leonb)\
**Post date:** [October 5, 2007, 1:08am UTC](https://www.ruby-forum.com/t/add-files-to-array-matching-pattern/116381/1 "2007-10-05T01:08:55Z")

</div>

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!

---

<div class="post-metadata">

**Author:** ![leonb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/22d042/32.png) [@leonb](https://www.ruby-forum.com/u/leonb)\
**Post date:** [October 5, 2007, 1:23am UTC](https://www.ruby-forum.com/t/add-files-to-array-matching-pattern/116381/2 "2007-10-05T01:23:11Z")

</div>

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]

---

<div class="post-metadata">

**Author:** ![leonb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/22d042/32.png) [@leonb](https://www.ruby-forum.com/u/leonb)\
**Post date:** [October 5, 2007, 1:35am UTC](https://www.ruby-forum.com/t/add-files-to-array-matching-pattern/116381/3 "2007-10-05T01:35:31Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![leonb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/22d042/32.png) [@leonb](https://www.ruby-forum.com/u/leonb)\
**Post date:** [October 5, 2007, 1:50am UTC](https://www.ruby-forum.com/t/add-files-to-array-matching-pattern/116381/4 "2007-10-05T01:50:16Z")

</div>

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](http://agileconsultingllc.com)  
removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![leonb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/22d042/32.png) [@leonb](https://www.ruby-forum.com/u/leonb)\
**Post date:** [October 5, 2007, 2:03am UTC](https://www.ruby-forum.com/t/add-files-to-array-matching-pattern/116381/5 "2007-10-05T02:03:53Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![leonb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/22d042/32.png) [@leonb](https://www.ruby-forum.com/u/leonb)\
**Post date:** [October 5, 2007, 5:25am UTC](https://www.ruby-forum.com/t/add-files-to-array-matching-pattern/116381/6 "2007-10-05T05:25:16Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![leonb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/22d042/32.png) [@leonb](https://www.ruby-forum.com/u/leonb)\
**Post date:** [October 5, 2007, 9:21am UTC](https://www.ruby-forum.com/t/add-files-to-array-matching-pattern/116381/7 "2007-10-05T09:21:45Z")

</div>

2007/10/5, Leon B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> 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

---

<div class="post-metadata">

**Author:** ![leonb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/22d042/32.png) [@leonb](https://www.ruby-forum.com/u/leonb)\
**Post date:** [October 5, 2007, 5:41am UTC](https://www.ruby-forum.com/t/add-files-to-array-matching-pattern/116381/8 "2007-10-05T05:41:04Z")

</div>

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.
