Undefined method `find' for.:Module

Hello,

I am quite new at Ruby (we use it for test automation in conjunction
with Cucumber, where it works great!) but as a stand-alone, I’m finding
myself more productive with Python. Maybe that’s just me.

I have to confess I do not know what the issue is. When I try to run the
attached script (note: this example is copied EXACTLY from Ruby
Cookbook) I am given the following error at Windows cmdline:

E:\Sounds\Digital>ruby Froop.rb
Froop.rb:6:in match': undefined methodfind’ for Froop:Module
(NoMethodError)
from Froop.rb:12:in `’

Note that the Froop.rb is in same directory from where I am attempting
to run it. Ruby doesn’t seem to recognize it’s own require statement:

require ‘find’

on the first line of the file, which is positively baffling.

Note, that when I try to only put my function in the file and call Froop
from the command line (how I originally tried to do it), that’s a lost
cause too:

E:\Sounds\Digital>irb
irb(main):001:0> require ‘Froop’
LoadError: no such file to load – Froop
from internal:lib/rubygems/custom_require:29:in require' from <internal:lib/rubygems/custom_require>:29:inrequire’
from (irb):1
from C:/Ruby192/bin/irb:12:in <main>' irb(main):002:0> Froop.match("./") { |p| ext = p[-4...p.size]; ext && ext.downcase == "mp3" } NameError: uninitialized constant Object::Froop from (irb):2 from C:/Ruby192/bin/irb:12:in
irb(main):003:0>

Seriously what gives? I’m ready to put Ruby in the Bin and switch to
Python, but my heart won’t let me…yet. :frowning:

On Thu, Oct 28, 2010 at 6:42 PM, John H. [email protected]
wrote:

E:\Sounds\Digital>ruby Froop.rb
Froop.rb:6:in match': undefined method find’ for Froop:Module
(NoMethodError)
from Froop.rb:12:in `’

You are calling find as a standalone method, but the find library
creates a Find class:

require ‘find’

module Froop
def match(*paths)
matched=[]
Find.find(*paths) { |path| matched << path if yield path
}
return matched
end
module_function :match
end

Froop.match(“./”) { |p| ext = p[-4…p.size]; ext && ext.downcase ==
“mp3” }

This works, or at least, doesn’t raise an error about the find method.

cause too:
NameError: uninitialized constant Object::Froop
from (irb):2
from C:/Ruby192/bin/irb:12:in `’
irb(main):003:0>

Seriously what gives? I’m ready to put Ruby in the Bin and switch to
Python, but my heart won’t let me…yet. :frowning:

You are using ruby 1.9.2, which has removed “.” from the LOAD_PATH. You
can use:

require ‘./Froop’

or add “.” to the load path yourself:

$: << “.”

Don’t lose faith in Ruby, you’ll be glad in the end if you persevere :slight_smile:

Jesus.

Hi, good explantion -and thanks! - almost - but please show me how my
script must actually look - as changed via your suggestion - to get it
to work properly.

I don’t understand a thing about load paths and what that does either.
As I’m using windows CMD a Unix command won’t help.

Last thing: your suggestion

require ‘./Froop’

Throws and error:

irb(main):003:0> require ‘./Froop’
NoMethodError: undefined method find' for Froop:Module from E:/Sounds/Digital/Froop.rb:6:inmatch’
from E:/Sounds/Digital/Froop.rb:12:in <top (required)>' from <internal:lib/rubygems/custom_require>:29:inrequire’
from internal:lib/rubygems/custom_require:29:in require' from (irb):3 from C:/Ruby192/bin/irb:12:in

So I’m still stuck at the beginning :frowning:

Using all of the above suggestions, I have gotten exactly nowhere:

The .rb now looks like this:

require ‘./find’ #NOTE: also tried - require ‘find’ - same error

module Froop
def match(*paths)
matched=[]
find(*paths) { |path| matched << path if yield path }
return matched
end
module_function :match
end

E:\Sounds\Digital>irb
irb(main):001:0> require ‘./Froop’
=> true
irb(main):002:0> Froop.match("./") { |p| ext = p[-4…p.size]; ext &&
ext.downcase == “mp3” }
NoMethodError: undefined method find' for Froop:Module from E:/Sounds/Digital/Froop.rb:6:inmatch’
from (irb):2
from C:/Ruby192/bin/irb:12:in `’

On Thu, Oct 28, 2010 at 7:00 PM, John H. [email protected]
wrote:

So I’m still stuck at the beginning :frowning:

I did it when I pasted the code in my previous answer:

require ‘find’

module Froop
def match(*paths)
matched=[]

          # I changed this line adding "Find." in front:
           Find.find(*paths) { |path| matched << path if yield path 

}

           return matched
   end
   module_function :match

end

Froop.match(“./”) { |p| ext = p[-4…p.size]; ext && ext.downcase ==
“mp3” }

Jesus.

On Thu, Oct 28, 2010 at 7:12 PM, John H. [email protected]
wrote:

Using all of the above suggestions, I have gotten exactly nowhere:

Sorry, you only need one of the suggestions when running your script
from the command line, and it’s the one you are not copying (in fact
you need this one for your method to work at all. Please look with
great care what I’m going to write:

You need to change this line:

find(*paths) { |path| matched << path if yield path }

to

Find.find(*paths) { |path| matched << path if yield path }

You see? When you require find, it creates a class or module (I don’t
know off the top of my head) with a class method called find. You need
to call it like that or Ruby won’t find it (no pun intended).

You don’t need to change the require ‘find’ to anything else, cause
“find” is in the stdlib and is available in the load path.

Jesus.

On Thu, Oct 28, 2010 at 8:12 PM, John H. [email protected]
wrote:

return matched
end
module_function :match
end

That’s the same exact code you started with. You’re not reading what
Jesus wrote, twice! Read his code carefully… note the difference
he clearly hi-lighted!

Regards,
Ammar

You know guys, it’s a been a very long day and I might be missing some
things.

Usually I use Python and don’t get stuck on things like this for as long
as I have in this case.

I do appreciate your suggestions but this just isn’t working I’m afraid.

So thank you for your help anyway.

On Thu, Oct 28, 2010 at 7:33 PM, John H. [email protected]
wrote:

from C:/Ruby192/lib/ruby/1.9.1/find.rb:40:in `catch’
irb(main):002:0> Froop.match(“./”) { |p| ext = p[-4…p.size]; ext &&
irb(main):003:0>
OK, well, we’ve moved one step further :-). What this means is that
the block is being called with a nil value, which is causing p inside
the block to be nil, and when you try to call p.size it complains that
nil doesn’t have that method. I’m not able to reproduce it, even in an
empty folder (at least the block gets passed “./”), so maybe it’s a
Windows thing, I’m using Ubuntu, and it works perfectly for me. By the
way, there’s a better way to check the extension:

$ irb
irb(main):001:0> require ‘./Froop’
=> true
irb(main):003:0> Froop.match(“./”) { |path|
File.extname(path).downcase == “.rb” }
=> [“./Froop.rb”]

Hope this helps,

Jesus.

Hi Jesus,

Sorry I didn’t see your earlier reply.

Unfortunately this is what I get when I run your code from CMD:
E:\Sounds\Digital>ruby Froop.rb
Froop.rb:15:in block in <main>': undefined methodsize’ for
nil:NilClass (NoMethodError)
from Froop.rb:8:in block in match' from C:/Ruby192/lib/ruby/1.9.1/find.rb:41:inblock in find’
from C:/Ruby192/lib/ruby/1.9.1/find.rb:40:in catch' from C:/Ruby192/lib/ruby/1.9.1/find.rb:40:infind’
from Froop.rb:8:in match' from Froop.rb:15:in

And this is what I get when I import to IRB and run FROOP block
separately:

E:\Sounds\Digital>irb
irb(main):001:0> require ‘./Froop’
=> true
irb(main):002:0> Froop.match("./") { |p| ext = p[-4…p.size]; ext &&
ext.downcase == “mp3” }
NoMethodError: undefined method size' for nil:NilClass from (irb):2:inblock in irb_binding’
from E:/Sounds/Digital/Froop.rb:8:in block in match' from C:/Ruby192/lib/ruby/1.9.1/find.rb:41:inblock in find’
from C:/Ruby192/lib/ruby/1.9.1/find.rb:40:in catch' from C:/Ruby192/lib/ruby/1.9.1/find.rb:40:infind’
from E:/Sounds/Digital/Froop.rb:8:in match' from (irb):2 from C:/Ruby192/bin/irb:12:in
irb(main):003:0>