Using packages in Ruby? - ruby

I just started learning Ruby coming from Java. In Java you would use packages for a bigger projects. Is there anything equivalent to that in Ruby? Or what is the best way to achieve a package like setting?
The way I'm doing it right now is 'load'ing all the needed class into my new Ruby file. Isn't there a way to tell my current Ruby class to use all other Ruby classes in the same folder?
Cheers,
Mike

There's three kinds of package loading in Ruby:
Explicitly loading a library with require
Implicitly loading a library using autoload
Importing a library with gem
The require method is the most direct and has the effect of loading in and executing that particular file. Since that file may go on to require others, as a matter of convenience, you may end up loading in quite a lot at once.
The autoload method declares a module that will be loaded if you reference a given symbol. This is a common method to avoid loading things that you don't need, but making them automatically available if you do. Most large libraries use this method of loading to avoid dumping every single class into memory at once.
The gem approach is a more formalized way of packaging up a library. Although it is uncommon for applications to be split up into one or more gems, it is possible and provides some advantages. There's no obligation to publish a gem as open-source, you can keep it private and distribute it through your own channels, either a private web site or git repository, for instance, or simply copy and install the .gem file as required.
That being said, if you want to make a library that automatically loads a bunch of things, you might take this approach:
# lib/example.rb
Dir.glob(File.expand_path('example/**/*.rb', File.dirname(__FILE__))).each do |file|
require file
end
This would load all the .rb files in lib/example when you call require 'example'.

You probably want to use require rather than load, since it should take care of circular references.
If you want to grab all the files in a given folder, that's easy enough:
Dir.foreach("lib"){|x| require x}
Your other option is to have a file that manually requires everything, and have your other files require that.
You should also look at wrapping the code in your libraries with a module block, to give them their own namespaces.
That said: rightly or wrongly, I tend to feel that this is the one area -- perhaps the only one -- where Ruby is less powerful than Python, say, or Java.

I understand your feeling. It's an ordinary problem you have to face when coming from another language like Java. I'd say try to study Ruby modules but you deserve a longer reply. So my advice is reading a good Ruby book like Eloquent Ruby.

Related

How to create a multi module project(subproject) in Ruby

In java, there are various ways to create multiple module project. Maven provides extensive support for it.
I am wondering if such a feature is available in ruby.
Why we need it:
A full-stack project has middle tier, front end html and js controller code. This will help in categorize each of them.
Modules and Gems
In Ruby, a Module is a class-like object that collects methods and constants, and can be mixed into other classes. That's probably not what you're really asking about, but other solutions generally build on top of Ruby's Module and Class semantics.
You're more likely to be looking for something like RubyGems and Bundler to manage libraries and dependencies. The documentation for each is fairly extensive.
Frameworks like Ruby on Rails also offer additional capabilities to inject gems and modules directly into the codebase, but it's arguably more common in Rails to build out these capabilities with gems and bundles. An exhaustive treatment of all the various ways to extend Rails (e.g. vendored gems, plugins, engines, etc.) is beyond the scope of a reasonable Stack Overflow answer, though. I mention some of them here in passing to help you search for the right documentation for your specific use cases.

Chef Shared Ruby Functions or libraries

We have a local Ruby Library that we include in a lot of our ruby projects. It contains a lot of configuration information that would be extremely useful to use in our chef scripts. This allows us to put all of our configuration in one place, so we don't have to make multiple places everytime we change a database etc. Trying to keep the code DRY. That being said, the code are straight ruby functions, not in the chef DSL.
I have been trying to pull the library into Chef, but have found it very difficult. Which makes me think I'm going against some sort of pattern.
I have tried and didn't work.
- Add the Ruby Code via require_relative and includes.
- Add the Ruby Code to it's own cookbook, then wrap the cookbook.
- Create a local ruby gem (not retrievable via rubygems, or other repo)
What worked:
- Copying and pasting the code into a cookbook. (but it's not sharable.)
My real question, what is the best way to share this ruby code library amongst many cookbooks? Depending on the best way, how do you actually do it?, or pointers in the right direction.
thanks.
myles.
I would use Halite (disclaimer: my project) to convert the gem into a cookbook and then upload it as a cookbook. Then you can depend on it and require stuff from it like normal in your Chef code.
You can create a cookbook and copy the ruby code into libraries folder of the cookbook. Then it will be loaded by Chef automatically on node, as soon as you include the cookbook into run list.
Could you tell, what exactly you did, and what didn't work when you tried "Add the Ruby Code to it's own cookbook, then wrap the cookbook"?
I have created a ruby library. Basically, it reads the ip of the server in opsworks. Once it gets that it knows what environment it is in, and it will set a hash. This hash is then used to set the attributes. This way all the server configurations are stored in one place.
I can put the code in each different cookbook that needs it. However, I have to duplicate the code in each different cookbook. I would like to put the code in one place, and include it in each cookbook. That way if I have to modify it, I only have to do it in one place.
I tried making it a gem, and requiring it with no luck.
I also created a cookbook with nothing but the ruby code in a library. I then included "depends etc" that cookbook in another and tried to run the library functions, but I couldn't get it to work.
I may have been on the right track, but I stopped before I got it working.
Essentially I want to write a simple ruby code library, that I can use in any cookbook I want. There must be a way to do this, but I've run into some dead ends. I'll keep banging my head against the wall. Eventually, a hole will open up!

What is the right place to require a ruby module in rails 3 & ruby 1.9.2?

I need to use the CSV module built into Ruby 1.9.2, and, in order to do this, I need to do require 'csv'.
In Rails 3, where is the proper place to put this require? I have seen examples where it's at the top of the file it's used in.
I have also see an example where it's put in config/initializers/csv_init.rb.
Is there a rule of thumb here? If I need it in multiple files, put it in an initializer, if only one put it in the file itself?
Put it in 'config/application.rb'. (See "Configuring Rails Applications").
In general, do this stuff in a central place and document it. The person maintaining your application will appreciate it when some future Ruby or Rails version breaks all kinds of backward compatibility.

Ruby program structure

Preface: This is not much about how to structure code within files. I have that down. This is more of the topic of organization of your source tree. Hopefully someone will just say, "Here's a great link on the topic." However, firsthand opinions on the subject are welcome too.
So I've done a bit of digging on this subject and find tons of material on simple structure. I guess the assumption is that, by the time you need to deal with the problems of the size of your codebase, you'll already know the answer. However, even the IDEs seem to be waging a holy war on how these projects should be structured (which is NOT what I wanted to start in this thread).
Java enforced the package structure in the language. Kudos for that. Eclipse then lets you use projects to have (potentially) independent -- we'll call them 'buckets' in this example -- buckets of related code. Intellij has distinct but similar concepts with 'modules' within a singleton instance of a 'project'. If you want another project, you're essentially starting from scratch.
However, RubyMine offers no such modules in ruby apps, and by default just wants to slam everything into the root directory. It allows Directories, so one could essentially just pick some arbitrary tree structure and run with it. This implies to me their intent was that all classes have access to all other classes within your project. This might have some resolution through the use of Ruby 'modules', or might just be an honor-system pattern of "don't reference that stuff."
So, to put it succinctly, say I were building a 'foo' and a 'bar' concept, and both depend on a 'util' class. maybe I'll deploy them as gems, maybe I won't. I could:
Slam them all into one RubyMine project and just ignore the fact that 'foo' and 'bar' have no reason to be aware of each other.
Put each in its own RubyMine project. This seems like a real pain if there is any concurrent development. First of all, 'util' would have to be packaged separately and then included as an external resource in the other projects.
Neither seems particularly appealing. Thougts?
I'd develop all three independently, then make util a gem. In the Gemfile for each of foo and bar, you can give a path to the gem so that you can develop them all concurrently without the pain of messing with version numbers and so forth (for production, you would then point it to the real gem on Rubygems or at some git repository).
For project structures, check out the Ruby Packaging Standard and Gem Patterns.

What's the best practices in code reuse between different Ruby projects?

guys!
I'm a software developer with Java background and I'm starting some projects using a Ruby web framework (Padrino/Sinatra).
In my java projects, I usually had some "common" projects whose classes where used in several projects. For instance, I had a central authentication service, and a shared database that stored the user profiles. All my projects that used this service shared some models mapped to the user profile database.
So, despite the framework, orm lib etc., what's the best way of sharing code across several Ruby projects?
Besides this, ruby's gems is one of the best way of reusing common parts of code. Gems have names, version numbers, and descriptions and therefore you can easily maintain up-to-date versions of these libraries, install and uninstall, manage your computer’s local installations of gems using the gem command, available from the command line. Gems became standard with Ruby 1.9, but before you have to use require 'rubygems' line in the scripts. There are several tools that help create them, for example, bundler. Bundler not only tool for gem creation, but an awesome application's dependencies manager.
Put your code into a something.rb file and require it at the top of your other script(s).
You can also use load instead of require, but require has the nice property that it will not include a file more than once. Also, using load requires the .rb extension, whereas require does not, i.e.,
#some_script.rb
puts('hello world')
#another script
require 'some_script'
>> hello world
load 'some_script'
LoadError: no such file to load -- some_script
from (irb):2:in 'load'
from (irb):2
You will almost always use require, but load is an option as well if you want to use it for... whatever reason.

Resources