Including a Ruby class from a separate file - ruby

For a while I had been including an entire class inside of a Ruby module. Apparently this is not what I am supposed to do. It appears that the point of a module is to store functions which can then be included as methods in a new class.
I don't want this. I have a class that I want to keep in a separate file which I can access from other files. How can I do this?
Thanks.

Modules serve a dual purpose as a holder for functions and as a namespace. Keeping classes in modules is perfectly acceptable. To put a class in a separate file, just define the class as usual and then in the file where you wish to use the class, simply put require 'name_of_file_with_class' at the top. For instance, if I defined class Foo in foo.rb, in bar.rb I would have the line require 'foo'.
If you are using Rails, this include often happens automagically
Edit: clarification of file layout
#file: foo.rb
class Foo
def initialize
puts "foo"
end
end
...
#file: bar.rb
require 'foo'
Foo.new
If you are in Rails, put these classes in lib/ and use the naming convention for the files of lowercase underscored version of the class name, e.g. Foo -> foo.rb, FooBar -> foo_bar.rb, etc.
As of ruby version 1.9 you can use require_relative, to require files relatively to the file you are editing.

You can also use load. Also you use require relative if the file is in the same directory. Read this link for further understanding: http://rubylearning.com/satishtalim/including_other_files_in_ruby.html

When Using Require, inside the string indicate the full path name of the class you are refereing to unless its in the Root Folder of Ruby

MyApp
|_ app
|_ bin
|_ etc, etc
root_level_file.rb
You can just do:
require './root_level_file'.
RootLevelFile.new

Related

Should Rspec file structure match file structure of code being tested?

I am writing a gem. I want to test some of the classes. I have them in modules.
The file structure:
my_gem
/lib
/my_gem
/practices
/texas
/medical_practice.rb
medical_practice.rb:
module MyGem
module Practices
module Texas
class MedicalPractice < Practice
end
end
end
end
In my spec directory, should I follow the same structure?
spec
/practices
/texas
/medical_practice_spec.rb
Or is it best practice to place medical_practice_spec.rb right under the /spec directory?
In my spec directory, should I follow the same structure?
Yes.
Usually in RSpec the spec structure matches the directory structure of the files under test.
Another example (when using Rails):
spec/controllers/users_controller_spec.rb would test app/controllers/users_controller.rb

Chef LWRP referencing relative resource

I am trying to create a LWRP to extend a supermarket cookbook 'webpshere'.
In my resource file, I am trying to extend this class with a base class found in parent cook book.
In the code below, 'WebsphereBase' is defined in the parent library 'websphere_base'. Can I get help on how to reference it?
Thanks
#require 'websphere_base'
module PIWebsphereCookBook
class WebsphereJbdc < WebsphereBase
require_relative 'helper'
In the source of the cookbook, you can see that the WebsphereBase class is defined inside the WebsphereCookbook module.
To reference this class from outside this module, you have to name the nesting so that Ruby is able to find the class you are referring to. With youur example, this can look similar to:
module PIWebsphereCookBook
class WebsphereJbdc < WebsphereCookbook::WebsphereBase
require_relative 'helper'
# ...
end
end
You don't need to require things coming from upstream cookbooks, nor can you (except for my weirdo cookbooks). All libs for cookbooks you depend on will be loaded by the time your library files run.

`require`ing files in a common codebase

I'm new to writing big Ruby projects (only mods and application scripting till now). I've made a project with some files in the project root and others in subfolders, including a "Test" folder.
So far I've tried:
Adding all folders and subfolders to the load path in RubyMine.
Declaring all the files to be part of the same module.
I've thought of using require_relative for loading all files needed but it seems tiresome and very Java-esque... Is there a better way?
Here is an example of a typical folder structure, its modules and how to include everything into the library. You would then only need to require 'lib' wherever you want to pull in the library for use.
# Root folder structure of project
lib.rb
./lib/a.rb
./lib/b.rb
./lib/b/c.rb
# lib.rb
require 'lib/a'
require 'lib/b'
module Lib
end
# ./lib/a.rb
module Lib
module A
end
end
# ./lib/b.rb
require 'lib/b/c'
module Lib
module B
end
end
# ./lib/b/c.rb
module Lib
module B
module C
end
end
end

Ruby 1.9.3: import all files in a given directory

I am having trouble import all of the .rb files I need from a given directory, I know this question has been asked a lot but none of the earlier posts seem to solve my problem.
Here is my directory structure:
- Docs
- Lexer
- Parser
--> Parser.rb
- SyntaxTree
--> I want all the .rb files from here
--> Sets.rb (Module I want to import)
--> EMPTY_SET (constant I want to reference)
- Test
<Main Program>
I am currently working in Parser.rb and I need to get all of the .rb files from the SyntaxTree directory so I can reference them inside of Parser.rb. I also want to import the Sets module that is contained in Sets.rb.
Here is my current way of trying to import all of the ruby files that I saw in most of the previous posts:
Dir['../SyntaxTree/*.rb'].each {|file| require file}
I also tried:
Dir['../SyntaxTree/*.rb'].each {|file| require_relative file}
With either of these method I still get errors when trying to include the Sets module:
class Parser
include Sets
.
.
end
`<class:Parser>': uninitialized constant Parser::Sets (NameError)
If I directly include Sets.rb the error goes away
Any ideas would be very helpful.
The best approach is to set up proper autoload dependencies within your modules so that the required classes are loaded on demand. If you simply load all of the files in using require, it won't be obvious which order they have to be loaded based on filenames and any inter-dependenceies are not resolved.
This is why having a top-level namespace for your application can help. Example:
module MyApp
autoload(:Parser, 'my_app/parser')
autoload(:Sets, 'my_app/sets')
end
Now those classes should load automatically on-demand.

What does ruby include when it encounters the "include module" statement?

If I have the following project structure
project/
lib/
subproject/
a.rb
b.rb
lib.rb
where lib.rb looks like this :-
module Subproject
def foo
do_some_stuff
end
end
and a.rb and b.rb both need to mixin some methods within lib.rb and are both namespaced within a module like so :-
require 'subproject/lib'
module Subproject
class A
include Subproject
def initialize()
foo()
end
end
end
What does ruby do when it encounters the include statement? How does it know that I want to only include the mixin from lib.rb rather than the whole module which includes both class A and class B, is this based purely on the require of subproject/lib or am I getting it wrong and it is including the whole of the module, including the definitions of Class A and B within themselves?
It is including the whole of the module. There is only one Subproject module, you've just reopened it in a.rb and b.rb and added classes A and B to it. I don't think require is related anyhow there.
BTW, you can always try it out in irb:
>> Subproject::A
=> Subproject::A
>> Subproject::A::A
=> Subproject::A

Resources