Calling classes from files - ruby

I am writing a program which includes two file. I’m the first file all I am doing is initializing the next file which includes multiple classes. I call the class at the bottom of the file, but it runs the class at the top of the file.
Btw I am running ruby
First file:
Require ‘./secondfile.rb’
newfile.Lastclass
Second file:
class Firstclass
end
class Lastclass
end

Hint #1. It's better to write without .
It depends on directory from where you run your app.
For example you have directory folder. And there you have two files:
file.rb
puts "I'm file.rb"
main.rb
require './file.rb'
If you run your app from folder - it's ok:
folder$ ruby main.rb
I'm file.rb
But if you'll run it from high level - it will be error:
folder$ cd ..
:~$ ruby folder/main.rb
kernel_require.rb:55:in `require': cannot load such file -- ./file.rb (LoadError)
But how to write in this case?
Hint #2. You can use special method
main.rb
require "./#{__dir__}/file.rb"
Now it's ok in all cases:
~$ ruby folder/main.rb
I'm file.rb
folder$ ruby main.rb
I'm file.rb
But you can write it better.
Hint #3. You can use require_relative
main.rb
require_relative 'file.rb'
And even better.
main.rb
require_relative 'file'
Ruby understand it.
~$ ruby folder/main.rb
I'm file.rb
folder$ ruby main.rb
I'm file.rb
Hope this helps you.

Classes are injected into the root namespace if they're defined. If another file defines a class, all files get it:
require_relative './secondfile.rb'
Lastclass
This is unlike JavaScript (e.g. Node.js) where you must explicitly import classes from other files. In Ruby it happens by manipulating the root namespace.
Another note is to pay close attention to which slashes you use. In your code you used a backslash, which is incorrect. You also used the wrong quotes. Often every character counts when programming.

Related

ruby require command not loading correctly

First post, "Hello World"
I am working through the lynda videos on Ruby and am just getting to the part of requiring content from .rb files in irb. An example patch we made is named contact_info.rb and from irb I am trying to require that file. When executed it comes back with the attached below.
Some light googling made it seem like this is maybe a yosemite issue (running 10.10.3.), but I'm not sure how to troubleshoot.
Thanks all
irb(main):006:0> require contact_info.rb
LoadError: cannot load such file -- contact_info.rb
from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/rubygems/core_ext/kernel_require.rb:55:in 'require'
from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/rubygems/core_ext/kernel_require.rb:55:in 'require'
from (irb):6
from /usr/bin/irb:12:in '<main>'
you can use require_relative 'contact_info'.
Assuming the file is in your current directory, type this in your command line:
irb -r './contact_info.rb'
First, note that with any require statement, you omit the file extension:
require 'contact_info'
When you require a file, ruby only looks in certain directories on your computer for the file. You can see which directories those are by running the following code:
p $LOAD_PATH
In ruby 1.8.7, the $LOAD_PATH array included ".", or the current directory, which means your code would have worked. But, including the current directory in $LOAD_PATH was deemed a security risk, so now you have to do something different:
1) One option is to use a relative path for the file you specify in the require statement:
require './contact_info'
The path is relative to the current directory. That works fine if you have this structure:
/some/dir/
your_prog.rb
contact_info.rb
And you switch directories to /some/dir and then run your_prog.rb:
~$ cd /some/dir
/some/dir$ ruby my_prog.rb
The require statement works--no problems. However, what if you do this:
/some/dir$ cd ..
/some$ ruby ./dir/your_prog.rb
Now, the current directory is /some, and require './contact_info' tells ruby to look in the /some directory for contact_info.rb--but it isn't there, so you will get the error:
`require': cannot load such file -- ./contact_info.rb (LoadError)
2) To cure that problem, ruby added require_relative. Paths specified with require_relative are relative to the location of the file that contains the require_relative statement. As a result, the statement:
#your_prog.rb:
require_relative './contact_info'
...will look in the directory containing your_prog.rb for the file contact_info.rb. Now, doing this:
/some$ ruby ./dir/your_prog.rb
will work fine. And in fact, in the require_relative you don't even have to write the ./ in the path:
#your_prog.rb:
require_relative 'contact_info' #Look for contact_info.rb in the same
#directory that contains this file
require_relative '../contact_info' #Look for contact_info.rb one directory
#above the directory that contains this file
I am working through the lynda videos on Ruby and am just getting to
the part of requiring content from .rb files in irb.
In my opinion, it's not a good idea to use irb for much of anything. A better option is to create a couple of files called 1.rb, 2.rb, 3.rb, and do your coding in those files.

Require in an IRB shell

I'm working in an IRB shell on a dos CMD
I load a module from a mystuff file
require '.\mystuff'
I change the module in the mystuff file and I type again
require '.\mystuff'
How come the IRB does not pick up the changes in the file when I try to call functions or variables from the newest version of my mystuff module?
require will not load the same file twice. If you want to load the file again, you need to use load. See What is the difference between include and require in Ruby? for more information.
Your Syntax is Wrong
Ruby doesn't use backslashes. You need to use forward slashes, or use File#join.
Your $LOAD_PATH is Wrong
Your $LOAD_PATH (a.k.a $:) is wrong. You need to include the present working directory with:
$: << '.'
in irb, or use Kernel#require_relative in executable or sourced files.

load error when run the ruby file from a different location

I have the following problem:
My ruby project structure : Ruby_Source\
file1.rb
file2.rb
file3.rb
In file1.rb,
require 'file2'
require 'file3'
now ,if I run the file1.rb from Ruby_Source, am not getting any error.
but , when I run the same from a different system location eg(c:)
error is Load error.
Can some one help me please?
You might want to use require_relative:
require_relative complements the builtin method require by allowing you to load a file that is relative to the file containing the require_relative statement.
See further discussion:
What is the difference between require_relative and require in Ruby?
And if you run Ruby 1.8:
Ruby: require vs require_relative - best practice to workaround running in both Ruby <1.9.2 and >=1.9.2
Try this:
require_relative 'file2'
in Ruby 1.9.x. It will search for file2 in the directory of file1.
In older versions you might try something like:
$: << File.dirname($0)
which will add the current program's path to the require-search path.

Ruby 'require' error: cannot load such file

I've one file, main.rb with the following content:
require "tokenizer.rb"
The tokenizer.rb file is in the same directory and its content is:
class Tokenizer
def self.tokenize(string)
return string.split(" ")
end
end
If i try to run main.rb I get the following error:
C:\Documents and Settings\my\src\folder>ruby main.rb
C:/Ruby193/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `require': cannot load such file -- tokenizer.rb (LoadError)
from C:/Ruby193/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `require '
from main.rb:1:in `<main>'
I just noticed that if I use load instead of require everything works fine. What may the problem be here?
I just tried and it works with require "./tokenizer".
Just do this:
require_relative 'tokenizer'
If you put this in a Ruby file that is in the same directory as tokenizer.rb, it will work fine no matter what your current working directory (CWD) is.
Explanation of why this is the best way
The other answers claim you should use require './tokenizer', but that is the wrong answer, because it will only work if you run your Ruby process in the same directory that tokenizer.rb is in. Pretty much the only reason to consider using require like that would be if you need to support Ruby 1.8, which doesn't have require_relative.
The require './tokenizer' answer might work for you today, but it unnecessarily limits the ways in which you can run your Ruby code. Tomorrow, if you want to move your files to a different directory, or just want to start your Ruby process from a different directory, you'll have to rethink all of those require statements.
Using require to access files that are on the load path is a fine thing and Ruby gems do it all the time. But you shouldn't start the argument to require with a . unless you are doing something very special and know what you are doing.
When you write code that makes assumptions about its environment, you should think carefully about what assumptions to make. In this case, there are up to three different ways to require the tokenizer file, and each makes a different assumption:
require_relative 'path/to/tokenizer': Assumes that the relative path between the two Ruby source files will stay the same.
require 'path/to/tokenizer': Assumes that path/to/tokenizer is inside one of the directories on the load path ($LOAD_PATH). This generally requires extra setup, since you have to add something to the load path.
require './path/to/tokenizer': Assumes that the relative path from the Ruby process's current working directory to tokenizer.rb is going to stay the same.
I think that for most people and most situations, the assumptions made in options #1 and #2 are more likely to hold true over time.
Ruby 1.9 has removed the current directory from the load path, and so you will need to do a relative require on this file, as David Grayson says:
require_relative 'tokenizer'
There's no need to suffix it with .rb, as Ruby's smart enough to know that's what you mean anyway.
require loads a file from the $LOAD_PATH. If you want to require a file relative to the currently executing file instead of from the $LOAD_PATH, use require_relative.
I would recommend,
load './tokenizer.rb'
Given, that you know the file is in the same working directory.
If you're trying to require it relative to the file, you can use
require_relative 'tokenizer'
I hope this helps.
Another nice little method is to include the current directory in your load path with
$:.unshift('.')
You could push it onto the $: ($LOAD_PATH) array but unshift will force it to load your current working directory before the rest of the load path.
Once you've added your current directory in your load path you don't need to keep specifying
require './tokenizer'
and can just go back to using
require 'tokenizer'
This will work nicely if it is in a gem lib directory and this is the tokenizer.rb
require_relative 'tokenizer/main'
For those who are absolutely sure their relative path is correct, my problem was that my files did not have the .rb extension! (Even though I used RubyMine to create the files and selected that they were Ruby files on creation.)
Double check the file extensions on your file!
What about including the current directory in the search path?
ruby -I. main.rb
I used jruby-1.7.4 to compile my ruby code.
require 'roman-numerals.rb'
is the code which threw the below error.
LoadError: no such file to load -- roman-numerals
require at org/jruby/RubyKernel.java:1054
require at /Users/amanoharan/.rvm/rubies/jruby-1.7.4/lib/ruby/shared/rubygems/custom_require.rb:36
(root) at /Users/amanoharan/Documents/Aptana Studio 3 Workspace/RubyApplication/RubyApplication1/Ruby2.rb:2
I removed rb from require and gave
require 'roman-numerals'
It worked fine.
The problem is that require does not load from the current directory. This is what I thought, too but then I found this thread. For example I tried the following code:
irb> f = File.new('blabla.rb')
=> #<File:blabla.rb>
irb> f.read
=> "class Tokenizer\n def self.tokenize(string)\n return string.split(
\" \")\n end\nend\n"
irb> require f
LoadError: cannot load such file -- blabla.rb
from D:/dev/Ruby193/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `req
uire'
from D:/dev/Ruby193/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `req
uire'
from (irb):24
from D:/dev/Ruby193/bin/irb:12:in `<main>'
As it can be seen it read the file ok, but I could not require it (the path was not recognized). and here goes code that works:
irb f = File.new('D://blabla.rb')
=> #<File:D://blabla.rb>
irb f.read
=> "class Tokenizer\n def self.tokenize(string)\n return string.split(
\" \")\n end\nend\n"
irb> require f
=> true
As you can see if you specify the full path the file loads correctly.
First :
$ sudo gem install colored2
And,you should input your password
Then :
$ sudo gem update --system
Appear
Updating rubygems-update
ERROR: While executing gem ... (OpenSSL::SSL::SSLError)
hostname "gems.ruby-china.org" does not match the server certificate
Then:
$ rvm -v
$ rvm get head
Last
What language do you want to use?? [ Swift / ObjC ]
ObjC
Would you like to include a demo application with your library? [ Yes / No ]
Yes
Which testing frameworks will you use? [ Specta / Kiwi / None ]
None
Would you like to do view based testing? [ Yes / No ]
No
What is your class prefix?
XMG
Running pod install on your new library.
you need to give the path.
Atleast you should give the path from the current directory. It will work for sure.
./filename

Is there a shorter way to require a file in the same directory in ruby?

Is there a shorter way to require a file located in the same directory (as the script being executed)?
require File.expand_path(File.dirname(__FILE__) + '/some_other_script')
I read that require "my_script" and require "./my_script" will actually load the script twice (ruby will not recognize that it is actually the same script), and this is the reason why File.expand_path is recommended: if it is used every time the script is required, then it will only be loaded once.
It seems weird to me that a concise language like Ruby does not seem to have a shorter solution. For example, python simply has this:
import .some_other_module_in_the_same_directory
I guess I could monkey-patch require... but that's just evil! ;-)
Since ruby 1.9 you can use require_relative.
Check the latest doc for require_relative or another version of the Core API.
Just require filename.
Yes, it will import it twice if you specify it as filename and ./filename, so don't do that. You're not specifying the .rb, so don't specify the path. I usually put the bulk of my application logic into a file in lib, and then have a script in bin that looks something like this:
#!/usr/bin/env ruby
$: << File.join(File.dirname(__FILE__), "/../lib")
require 'app.rb'
App.new.run(ARGV)
Another advantage is that I find it easier to do unit testing if the loading the application logic doesn't automatically start executing it.
The above will work even when you're running the script from some other directory.
However, inside the same directory the shorter forms you refer to work as expected and at least for ruby 1.9 won't result in a double-require.
testa.rb
puts "start test A"
require 'testb'
require './testb'
puts "finish test A"
testb.rb
puts "start test B"
puts "finish test B"
running 'ruby testa.rb' will result in:
start test A
start test B
finish test B
finish test A
However, the longer form will work even from another directory (eg. ruby somedir/script.rb)
Put this in a standard library directory (somewhere that's already in your default loadpath $:):
# push-loadpath.rb
if caller.first
$: << File.expand_path(File.dirname(caller.first))
end
Then, this should work
% ls /path/to/
bin.rb lib1.rb lib2.rb #...
% cat /path/to/bin.rb
load 'push-loadpath.rb'
require 'lib1'
require 'lib2'
#...
caller gives you access to the current callstack, and tells you what file and where, so push-loadpath.rb uses that to add the file that load'd it to the loadpath.
Note that you should load the file, rather than require it, so the body can be invoked multiple times (once for each time you want to alter the loadpath).
Alternately, you could wrap the body in a method,
# push-loadpath.rb
def push_loadpath
$: << File.expand_path(File.dirname(caller.first))
end
This would allow you to require it, and use it this way:
% ls /path/to/
bin.rb lib1.rb lib2.rb #...
% cat /path/to/bin.rb
require 'push-loadpath'
push_loadpath
require 'lib1'
require 'lib2'
#...

Resources