Ruby Module Help -- Looking in wrong directory? - ruby

Hey everyone! I am having trouble with understanding modules -- I have two files, one named "modfile.rb" with the module, and one named "main.rb" that runs the code:
# modfile.rb
module Module1
def method1
puts "SUCCESS!"
end
end
# main.rb
require 'modfile'
Module1.method1
Unfortunately, instead of SUCCESS! appearing on my screen, I get this:
<internal:lib/rubygems/custom_require>:29:in 'require': no such file to load -- modfile (LoadError)
from <internal:lib/rubygems/custom_require>:29:in 'require'
from main.rb:1:in '<main>'
I think (though I may be wrong) that Ruby is looking to the lib/.... file inside the Ruby directory on my computer, while modfile.rb is saved in the same directory as main.rb. How do I fix this problem (other than by moving the module's file?)
PS. one guide suggested I add the line "require 'rubygems'" but I already did and got the same error.

Check into the differences between require and require_relative in Ruby: require vs require_relative - best practice to workaround running in both Ruby <1.9.2 and >=1.9.2
In Ruby 1.9 the . directory was removed from the search path. To fix the problem this generated they added require_relative.

If modfile.rb and main.rb are in the same directory, make sure that you aare calling main.rb from the directory it's in, ie:
ruby main.rb
As I believe that is the directory that the Ruby interpreter will be looking in for any require files.
Edit: as #the-tin-man points out, the behaviour has changed for Ruby 1.9.
To be completely on the safe side, you can do:
require File.join(File.dirname(__FILE__), "modfile")
One other thing:
def method1
... should be:
def self.method1
... since you are calling the method as a class level method.

Related

Do the .rb files in your db >>migrate have to be the same name as the rb files in your model folder?

I am fresh into Sinatra and Activerecord and I noticed I get a lot of errors such as
LoadError: cannot load such file -- ./model/character_houses
or
rake aborted!
NameError: uninitialized constant House
The first one is when I try to load into irb with require './app' for my main rb file.
The second is when I try to load a seed file.
Could someone just explain how file structures should be linked when using Sinatra and ActiveRecord. I have no problem setting the files up it's only when I try to check within irb or actually fill the tables.
A lot of the forums I see online pertain mostly to ruby on rails but we as a class are starting that after this so I am not sure if it is similar or relevant to my situation.
With sinatra the 'require' order is important
Dir.glob('./app/{exceptions,helpers}/*.rb').each do |file|
require file
end
require './app/controllers/api_controller'
require './app/uploaders/application_uploader'
Dir.glob('./app/{uploaders,jobs,controllers,models,etls,docs}/*.rb').each do |file|
require file
end
try 'require_relative app' with irb

Unable to load modules in ruby

I googled it, but no luck
I have a file called mdl.rb and main.rb, they both in the same folder
mdl.rb has module Test_module and method in it called say_hello, I want to use that method in my main.rb.
So my main.rb looks like this:
require 'mdl'
say_hello
but I get error:
in `require': cannot load such file -- mdl (LoadError)
You would use
require_relative 'mdl.rb'
See Ruby docs for require_relative.
(require_relative 'mdl' and require './mdl' also work, as pointed out in the comments by #MichaelBerkowski and #FélixSaparelli respectively.)

LoadError: cannot load such file -- directory/file_name

I have a file structure like
root
|--lib
|--root.rb
|--extensions
|--strings.rb
I want to be able to use methods in string.rb in root.rb file.
So I added require 'extensions/strings' at the top of root.rb file.
But I get LoadError: cannot load such file -- extensions/strings.rb error.
How do I avoid this?
You can try the below:
require File.dirname(__FILE__) + "/extensions/strings"
Use require_relative if you are in Ruby 1.9 or later. In root.rb, write:
require_relative 'extensions/strings.rb'
I found the answer I am looking for here.
I used jandot's solution.
Dir[File.dirname(__FILE__) + '/extensions/*.rb'].each {|file| require file }
Edit after some testing,
For some reason, this doesn't throw any error message, but it doesn't seem to be loading the actual Ruby file.
I tried adding this to extensions/strings.rb
class Dog
def self.bark
puts "bark"
end
end
And ran it on irb.
1.9.3-p0 :001 > require 'rhapsody'
=> true
1.9.3-p0 :002 > Dog
NameError: uninitialized constant Dog
from (irb):2
from /Users/jasonkim/.rvm/rubies/ruby-1.9.3-p0/bin/irb:16:in `<main>'
So it's not finding the Dog class in extensions/strings.rb for some reason.
Edit after reading a guid in rubygems.org
When I start irb, I had to go irb -Ilib -rextensions
The guide explains the situation this way
We need to use a strange command line flag here: -Ilib. Usually RubyGems includes the lib directory for you, so end users don’t need to worry about configuring their load paths. However, if you’re running the code outside of RubyGems, you have to configure things yourself.
require_relative '../lib/extensions/strings'
Works for me.

ruby require not working

I'm new to ruby, but I'm working on my first ruby program. It currently has two files, one is a library of functions (xgync.rb stored in lib) the other is the executable xgync stored in 'bin'. (Project visible here https://bitbucket.org/jeffreycwitt/xgync/src) I've also created a symlink to my /usr/local/bin/xgync so that I can write the command xgync {arguments} from anywhere in the terminal.
The problem seems to be that bin/xgync depends on the library lib/xgync.rb. I've written this dependency in bin/xgync as follows:
$:.unshift(File.dirname(__FILE__) + '/../lib')
require "xgync"
However, i keep getting the following error:
/Users/JCWitt/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require': cannot load such file -- xgync (LoadError)
from /Users/JCWitt/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
from /usr/local/bin/xgync:4:in `<main>'
can you see anything wrong with what I've written? Could the symlink be somehow messing things up?
Thanks for your help :)
When using ruby 1.9.x you don't usually alter the path with the $:.unshift when requiring other files in your project.
Instead the best practice is to use require_relative instead.
require_relative '../lib/xgync.rb'
require_relative requires files relative to the file you are currently editing.
But the error you experience appears, because you require a file, which does not exist:
bin/xgync
lib/xgync.rb
These are the files in your project according to your question, and the code-excerpt is from bin/xgync you extended the path to look for files in lib/ but you try to require 'xgync' which is a file, that is not present in lib/, so if you wanted to use this method (instead of require_relative you would have to use require 'xgync.rb'.

stuck in rvm hell trying to get a simple rspec running

Ruby Settings From terminal
% ruby -v
ruby 1.9.2p180 (2011-02-18 revision 30909) [i686-linux]
=> ~/ruby/grounded/test
% where ruby
/home/mike/.rvm/rubies/ruby-1.9.2-p180/bin/ruby
/home/mike/.rvm/bin/ruby
/usr/local/bin/ruby
/usr/bin/ruby
=> ~/ruby/grounded/Person/test
% which ruby
/home/mike/.rvm/rubies/ruby-1.9.2-p180/bin/ruby
% rvm current
ruby-1.9.2-p180
Directory Structure
% tree
.
├── bowling.rb
└── bowling_spec.rb
File Contents
bowling.rb
class Bowling
end
bowling_spec.rb
require 'rubygems'
require 'rspec'
require 'bowling'
describe Bowling, "#score" do
it "returns 0 for all gutter game" do
bowling = Bowling.new
20.times { bowling.hit(0) }
bowling.score.should eq(0)
end
end
% ruby bowling_spec.rb
/home/mike/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require': no such file to load -- bowling (LoadError)
from /home/mike/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
from bowling_spec.rb:3:in `<main>'
Questions
Why am I getting a LoadError when bowling.rb and bowling_spec.rb
are in the same folder?
In the error what the heck is .../site_ruby/1.9.1/... when I am running ruby 1.9.2 then why would 1.9.1 even show up?
how do I get over this hump and start having fun with ruby.
When requiring files, the file must be in a list of directories called the $LOAD_PATH. The current directory used to be in this list, but as of 1.9.2, it has been removed for security reasons.
You have four options (listed in order of how good I think they are)
1 Change your directory structure to look like this
.
|-- lib
| `-- bowling.rb
`-- spec
`-- bowling_spec.rb
And then run as rspec spec instead of ruby bowling_spec.rb
This works because RSpec will see that lib is in your current directory, and then add it to the $LOAD_PATH for you.
If you do this, you also don't have to require 'rspec'.
2 Run with ruby -I . bowling_spec.rb
which will add the current directory to the $LOAD_PATH
3 Use require_relative 'bowling' instead of require 'bowling'.
This will look for the bowling.rb file relative to the current file being run (bowling_spec.rb)
4 Use require('../bowling', __FILE__) instead of require 'bowling'
This is basically the same as the above.
Other questions:
Q: Why am I getting a LoadError when bowling.rb and bowling_spec.rb are in the same folder?
A: Because the current directory (the directory you are running the script from, not the directory the files are located in) is not in the $LOAD_PATH.
Q: In the error what the heck is .../site_ruby/1.9.1/... when I am running ruby 1.9.2 then why would 1.9.1 even show up?
A: Hmm. Not sure I remember exactly, but IIRC, it was something like they're so similar that the interface hadn't changed, so they could be compatible with 1.9.1 from a system perspective.
Q: how do I get over this hump and start having fun with ruby.
A: I suppose that depends. If the issue is that you want to be able to run files that are in your CWD, then you can add the environment variable RUBYLIB to . to your .bash_profile (or whatever the equivalent is on your system) which will tell Ruby to look in the current directory for files. This is prone to bugs, though (and it could lead to unintentional execution of Ruby files, which is a security risk). If you just mean "how do I start learning" or whats a fun project? Then check out one of my projects, Ruby Kickstart which, in six sessions, will take you through a pretty big portion of Ruby, and have you write and deploy a simple web app by the end of it.
When you require a file and don't specify an absolutely path to the file, Ruby looks on its load path (accessed within ruby as $LOAD_PATH or $:) and checks each directory there for the file you want. You cannot load bowling.rb because it's not in a directory on your load path.
The solution is one of two things:
Put the current directory on the load path:
$:.unshift File.expand_path('.')
This puts the full path to the current working directory on the load path.
Use require with the absolute path to the file:
require File.expand_path('../bowling', __FILE__)
A little additional info: File.expand_path returns the absolute path to the first parameter from the current working directory, unless a second parameter is given; then it uses that as the starting point. So the whole line could be read:
require /home/mike/src/something/bowling_spec.rb/../bowling

Resources