unshift + file.join in ruby - ruby

$:.unshift File.join(File.dirname(__FILE__),\
'vendor','addressable-2.1.0','lib','addressable','uri')
Does the code above access a file that has this path:
'vendor/addressable-2.1.0/lib/addressable/uri'
I'm trying to vendor the addressable gem into a Sinatra app to deploy it to my hosting provider but I keep receiving:
"no such file to load -- addressable/uri"
after putting the 'unshift' line in config.ru.

The above code adds the path "vendor/addressable-2.1.0/lib/addressable/uri" to the global variable used for looking up external files. The path will be relative to the directory that houses the file this code is placed in. So were {dir} is the directory config.ru is placed, it will add {dir}/vendor/addressable-2.1.0/lib/addressable/uri to the lookup path for includes.

What the line does is it puts the path 'vendor/addressable-2.1.0/lib/addressable/uri' (relative to the directory your ruby script is in) into the load path, which is the list of directories ruby looks through when looking for files you require.
By itself the line won't try to access any files.

Related

Why I am getting LoadError for require 'support/number_helper' in Ruby

When I am using the require_relative 'support/number_helper' it's working fine, But when I am using require 'support/number_helper' then I am getting this error.
rubies/ruby-2.3.1/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require': cannot load such file -- ./support/number_helper (LoadError)
I also tried this but getting the same error.
require './support/number_helper
I am using the ubuntu.
require_relative 'support/number_helper' searches for a file to load by adding given string to the directory of current_file (__FILE__). For example, in your project folder you have 2 files:
lib/special_gem/fetcher.rb
lib/special_gem/support/number_helper.rb
You can use require_relative 'support/number_helper' in your 1st file to load the 2nd. The command takes the path to the directory of the current file (lib/special_gem/), appends given string (support/number_helper) and successfully finds file to load.
What about require command, if given path is not absolute, it will search for the file in the directories listed in $LOAD_PATH. Very likely your lib folder is in this list, so to load 2nd file you could use the command
require 'special_gem/support/number_helper'
Since it's not relative, you can use it from your 1st file or any other file of your project.
When using require 'support/number_helper' it will search for the file at lib/support/number_helper. If that file is missing, LoadError exception is raised.
See the documentation for details.

How does an executable within a gem reference the greater gem?

Say that my gem is VideoPlayer. The folders tructure is:
VideoPlayer/
/bin
vidplay.rb
/lib
VideoPlayer.rb
Subtitler.rb
Screenshotter.rb
I want people to invoke vidplay from the command line, and for vidplay to reference code in the VideoPlayer, Subtitler and Screenshotter files.
If I just write, within vidplay.rb, require '../lib/VideoPlayer.rb', it will throw an error, saying that it cannot require such file. I thought "Maybe it automatically requires everything in lib/", but it apparently doesn't; if I don't require anything, it'll say that VideoPlayer is an uninitialised constant.
So how does this work?
I usually add the lib dir to the library load path ($:). You can add this to the top of your bin file.
lib = File.expand_path('../../lib', __FILE__)
$:.unshift(lib) unless $:.include?(lib)
Then you can do a normal require:
require 'videoplayer'
Hope this helps.

Ruby including files

I have a Ruby app that runs on a server with no web interface. It is run using the command line(ruby path/to/file.rb).
I have classes in different files that I want to be accessible. The files are located in the "app/classes" directory.
I put this in the application.rb file:
config.autoload_paths += Dir["#{config.root}/classes"]
and I get an uninitialized constant error.
I can put in "require_relitive 'somefile'" but I would rather not have to do this for every class that is used. How do I create an autoload path and where should it be located at?
Use require_all
See https://github.com/jarmo/require_all
It basically allows you to write this:
require 'require_all'
require_all 'app/classes'
And all ruby files in app/classes will be loaded.

no such mongoid configuration file issue

I have a minitest_helper.rb and mongoid.yml files in a directory. I putted the below code in minitest_helper;
require 'mongoid'
Mongoid.load!("mongoid.yml", :test)
Although these files in a same directory, Mongoid couldn't load yml file and I got 'no such file' as below:
/home/developer/.rvm/gems/ruby-1.9.3-p374/gems/mongoid-3.1.2/lib/mongoid/config
/environment.rb:40:in `initialize': No such file or directory - mongoid.yml
(Errno::ENOENT)
Also I don't use any framework like Rails, Sinatra etc.
What is wrong?
As you can see in the documentation, the #load! needs the full path to the file. Try changing the code into something like this:
Mongoid.load!(File.join('path_to_the_yml','starting_at_root_of_the_project', 'mongoid.yml') , :test)
The way you construct the File.join will depend on your directory structure. If I had an structure such as this:
project_root
--lib
--spec
----fixtures
------test.xml # the path for this file is project_root/spec/fixtures/test.xml
Then the File.join will look like this:
File.join('spec','fixtures', 'test.xml')

How do I require a file from inside a directory with Ruby?

I think I'm missing something here. I have a directory like this:
myapp
|-lib
|-package1
|-dostuff.rb
|-package2
|-dostuff.rb
From an irb console I'm trying to test the library before I add it to my real project (a Rails app). However, typing this:
require 'lib/package1/dostuff'
returns an error saying it can't find the file to load. I added the lib directory to the load path but I'm not able to load the file.
What am I forgetting? The two filenames don't have to be the same but that's how they are to begin with (they are auto-generated from some web services I need to call using soap4r; each package represents a different web service API group)
If the directory "lib" is in the load path, the argument to require must be relative to lib. So require 'package1/dostuff' without the lib, otherwise it will look for lib/lib/package1/dostuff.rb.
In Ruby 1.9 there's the new require_relative method, which would let you do require_relative "../package2/dostuff" from within package1/dostuff.rb.

Resources