I've a small ruby program that require files in the same directory. Program works perfect on my mac and when I run a test ruby script without any require it also works so. It seems the ruby program doesn't look in the current directory for the file by default. e.g. the . dir. In windows where do I need to update this so ruby does look in the current dir for requires?
Chances are that your Mac is running Ruby 1.8 and Windows is running Ruby 1.9. As of 1.9, the default load path no longer includes the current directory. A common practice is to add this to the top of your ruby file before your require statements
$LOAD_PATH.unshift File.dirname(__FILE__)
require 'my_file.rb'
You can also use the shorthand $: instead of $LOAD_PATH:
$:.unshift File.dirname(__FILE__)
Another alternative is adding the load path on the command line instead:
ruby -I. my_ruby_file.rb
Ok, I understand now since 1.9.2 for "Security" reasons they don't allow require to work like that anymore. The neatest way I found to solve it strangely was to put './' in front of every require.
e.g.
require "./myfile.rb"
"." was removed from $: was removed from Ruby 1.9.2 to be precise. Do
puts RUBY_VERSION
puts $:.inspect
on Ruby 1.8 (what's installed on your Mac) and Ruby 1.9.2 (what's installed on your windows machine) if you don't believe me.
Why does Ruby 1.9.2 remove "." from LOAD_PATH, and what's the alternative? discusses why "." was removed.
Related
What is the difference between
require 'blahblahlblah.rb'
vs
require './blahblah.rb'
vs
require File.expand_path('../blahblah', __FILE__)
I see both of them being used. Wondering what's better, and under what circumstance is one better than the other.
Thanks!
require blaba.rb is searching to your default gem path to load the file, which depends on the ruby version you are using. For example RVM will search in $HOME/.rvm/rubies/... while a system wide ruby will search in the distribution's default path. Note that this is where gems are located, but you could manually add a library say mylibrary.rb in the same path and use it in any of your programs. However, that's an awful thing to do, it's a much cleaner procedure to create gems and install them in your system.
require ./blabla.rb loads a file that is sitting in your working directory. You could add the full path like require /home/username/library/myproject/models/sample.rb. It will work just about the same. In the UNIX-like world the ./ sign means current directory. This solution is often used in irb to load say a rails Model i.e. users.rb into irb or pry and work with it. To give you an example in a shell environment (if you are familiar with UNIX shells, you'll figure it out):
GreyJewel ~ » ls myports.txt
myports.txt
GreyJewel ~ » ls ./myports.txt
./myports.txt
The third solution require File.expand_path('../sample.rb', __FILE__) is used in programs, because it explicitly creates a full path using as an anchor the directory which the file holding the line sits, which is a much more secure approach compared to require ./sample.rb. Note that when you load a ruby file, you can omit the file extension .rb.
Hope this clarifies a bit the situation.
Been running into a problem ever since I started using rvm to manage my ruby installation. Whenever I want to require another class I've written, such as require 'filename', I get a require - no such file to load error when I try to run my script. If I switch back to my system ruby using rvm use system it works again, but I'm 1.8.2 as my system ruby and some features I want to use in my code are only available in 1.9.*, which I can access through rvm. How do I fix this problem?
I'm not sure this is a problem with RVM, but a problem with Ruby 1.9 not including '.' in the current path. For instance, if you are trying to require a library at './lib/file.rb', you can't do
require "lib/file"
You have to do this:
require "./lib/file"
Have you tried that syntax for your require?
I think you want to use require_relative
http://extensions.rubyforge.org/rdoc/classes/Kernel.html
I am editing a gem in which there are the usual require commands, pointing at the loaded gem (the gem I'm talking about is called nirvana, and the files in it contain require 'nirvana', require 'nirvana/shell' and so on).
When I use the bin-file of the application (/mypath/nirvana/bin/nirvana), I want the require 'nirvana' command written inside it to point to the files in the local fork of that gem (the ones I am editing), and I want not to load the original nirvana gem, that is installed with the classic gem install.
I don't want to substitute all the require 'nirvana' commands with
require File.dirname(File.expand_path(__FILE__)) + '/../lib/nirvana.rb'
... this would resolve my problem, but it's ugly! Is there a way to do not load nirvana gem, and to make require 'nirvana' load my libraries (maybe adding them in the $LOAD_PATH...) ?
You might be running into the require vs. require_relative conundrum in 1.9+.
require is good for loading a gem that is loaded via the normal gems paths, i.e., installed into Ruby's space.
require_relative is good for loading relative to a particular file, for instance, if you're loading a module you wrote and its in the same or a sub-directory or relative directory of yours.
`require_relative 'some/sub/dir/to/file'`
You should only be 'requiring' nirvana.rb once, if you're doing so from your gems binary executable. So this line only needs to appear once. It's quite common to see it appear in these files.
Do note your example can be better written as
require File.expand_path('../lib/nirvana.rb', __FILE__)
As File::expand_path takes an optional second argument (a directory String).
A lot of authors will also shift the lib directory into the $LOAD_PATH before executing the binary so the local files are loaded before attempting to load any installed gems.
If you're using rvm, have a look at gemsets. You can create a gemset that doesn't have the nirvana gem installed, then when you require 'nirvana' you'll only get your local libraries required, as there isn't a nirvana gem to include.
(I'm assuming you're using ruby 1.9, as if you're using 1.8 you could just omit require 'rubygems'.)
I'm quite new to Ruby language (up to now I developed in Groovy + Grails) but since I was curious about it I wanted to try Sinatra on Ruby 1.9.2-p0.
I have a trivial website that is contained in /mywebpage and has 2 files:
# blog.rb
get '/' do
'Hello World!'
end
get '/impossible' do
haml :index
end
and
#config.ru
path = File.expand_path "../", __FILE__
$LOAD_PATH << (File.expand_path ".") + "/views"
require 'haml'
require 'sinatra'
require "#{path}/blog"
run Sinatra::Application
then in the same folder I have a /views/ folder that contains index.haml.
I try to run the server with rackup -p8080 but when I try to get /impossible I receive the following error:
Errno::ENOENT at /impossible
No such file or directory - /home/jack/mywebpage/<internal:lib/rubygems/views/index.haml
By searching over internet it seems that this maybe caused by "." not being included in $LOAD_PATH so I tried to add it or add directly views ./views so that actually $LOAD_PATH.inspect gives me correct path: ..., "/home/jack/mywebpage/views"]
But still it doesn't seem to work. Being quite new to the framework and the language I was wondering if I'm doing something wrong. any clues?
Running Sinatra with Ruby 1.9.2 the template directory is no longer implicitly 'views', you need to set it yourself.
set :views, File.dirname(__FILE__) + "/views"
Note that currently Ruby also has Kernel#__dir__() method that is equivalent to File.dirname(__FILE__).
This, and other issues with 1.9, will be have been solved in Sinatra 1.1. You could use this fork: http://github.com/rkh/sinatra/tree/1.1
I ran into a similar problem, and solved it like this. I didn't dig into the problem, but this is what I found and it works. It'll supposedly be fixed in the next version of Sinatra (which they should really get out the door, just to fix these few 1.9.2 bugs).
#!/usr/bin/env ruby
require 'rubygems'
require 'sinatra'
enable :run
get '/' do
"Hello, world!"
end
Edit: It seems there are multiple bugs with Sinatra on 1.9.2. This one will fix Sinatra apps not starting on 1.9.2. I don't use a views directory (I like to keep my apps single-file), so I didn't run into your particular problem. This fix most likely won't help you at all. I probably should have read your problem more closely..
gem install sinatra --pre
I ran into that last week and didn't find a suitable fix on the Sinatra site short of tweaking the sinatra code. I'm using rvm for my development and switched to try sinatra on Ruby 1.8.7 and it works fine again, so that's where I left it.
Oh, since you're new to Ruby, you might not know about rvm, so here's the lowdown. RVM is Mac only and highly recommended for managing your Ruby version and gems. It makes it trivial to have multiple Ruby versions and alternate groups of gems for development and testing. Everything is stored in your ~/.rvm directory so it's easy to blow it all away if you need to.
http://rvm.beginrescueend.com/
I just looked at the Sinatra site again about the problem to see if there was anything new, but it appears they consider the following to be an acceptable fix:
http://github.com/sinatra/sinatra/issues/#issue/50
I'm a bit adverse to having to edit the source of Sinatra as recommended by issue #50, but it's not real hard to do. I'd like to see them put out an update so we'd have an official fix but I haven't seen anything yet:
gem env will tell you the "GEM PATHS". Sinatra's gem will be in one of those. The line mentioned in issue #50 goes into base.rb. On my machine it's something like ...gems/ruby-1.9.2-p0/gems/sinatra-1.0/lib/sinatra/base.rb.
Insert:
/<internal:/, # ruby 1.9.2-p0 hacks
at line 1020.
Save the file and you should be good to go.
I haven been all day training to fix this problem but i couldn't.
The question is easy, i don't want to put anymore the require 'rubygems' line everytime i require a gem...
If i put the require 'rubygems' before any other "require" the file runs perfect but if i don't put the require 'rubygems' line the following error occurs:
(...)in `require': no such file to load -- 'gemname' (LoadError)
I suspect that may be there is some path remaining where to check out the gems repository.
I want to ask you if there is a way to do this.
Thanks a lot.
Cheers,
Juan.
You could invoke you ruby script with
ruby -rubygems script.rb
or add rubygems to RUBYOPT
$ export RUBYOPT="rubygems"
put
require 'rubygems'
as first line of your ruby code and be safe.
of course you can invoke with -rubygems switch (as Peter Krenn wrote) instead of it
In Unix you can:
$ RUBYOPT="rubygems"
$ export RUBYOPT
$ ruby juans_masterpiece.rb
and in Windows:
SET RUBYOPT=rubygems
or right-click on My Computer->Properties->Advanced->Environment Variables
and then finally add the RUBYOPT variable there. Next time you open a cmd.exe run set and it will be there.
You don't have to put it every time you require a gem — you just have to have it before the first time you require a gem. When you require Rubygems, it replaces the default require with a special one that does all the Rubygems magic.
But that's only in 1.8. You don't have to require Rubygems at all in Ruby 1.9 — so that's a very easy solution to the problem as long as you aren't dependent on 1.8-specific things.
Right-click the Computer Icon, then select Properties, then Additional system parameters, then Environment variables, there is a GUI for changing opts, click Create, put name and value, OK. This is an approximate translation of how you do this on windows 7, if you can't find the place try to google for "changing environment variables in {your windows version here}"