Is it valid to make Ruby Gems an analogy to Java JARs? - ruby-on-rails

I believe I have put the question quite clearly and in a concise manner. Why do I ask?
I am to explain Ruby on Rails framework to students and this requires me to make some analogies to the Java world (as the course is quite Java-centric). I have no hands-on experience with Ruby on Rails but I sense the Gem/Jar analogy is a valid one.
Could anyone perhaps shed more light on this issue?

As a short answer I would say: Yes, it is valid.
As a long answer I would say: Yes, it is valid, but there are some important distinctions you may want to describe as well.
A jar has some qualities that makes it very different from a gem. JARs are packaged executable libraries that you generally have to explicitly declare a dependency upon in a Java program's execution at invocation time (by declaring the jar as a dependency when you invoke the java interpreter). The jar has little structure enforced upon it other than a few well defined locations for files (e.g. directory structure must mirror package path).
A Gem is a descriptor for installing a library to a system permanently as well as a package of functionality made available to be declared a dependency during runtime. A gem has a strict versioning syntax as part of its definition, and gems tend to be distributed from few centralized repositories that spend a decent amount of effort to ensure uniqueness in gem names. Gems can explicitly declare their dependencies on other gems. (Contrast with JARs where you must make sure you have all of the dependencies for a jar satisfied at invocation time and jars do not explicitly adopt the responsibility for dependency declaration OR resolution). Additionally there is some optional functionality built into the gem tool that can be quite convenient, for example you can declare a default executable for a gem to be invoked if a user wishes to "run a gem", and you can declare a unit testing suite for a gem so that a user who installs a gem can ensure its functionality.
Also you might want to describe to your students that RubyGems is a tool created independently of the Ruby language itself, and that it benefits after many of the inconveniences and complaints that arose from managing jars had been well exposed from years of Java development.

I'm not sure is that easy...
I think that a Gem is basically the same thing as a jar, but a Gem has to have a name and a version, a jar does not have this, hm, let's say..., restrictions.
The Jar mechanism was created for packaging and just for packaging.
The most important, IMHO, in the Gem is the RubyGems project
The RubyGems feature set is a little larger than just packaging, in involves package distribution and installation.
I think that the Apache Maven distribution and installation mechanism is the closest thing the Java community has from the Ruby Gems.

As a simple explination comparing them to JARs is good enough for a basic Ruby class. For a more detailed explination see holychao's answer. The analigy that comes to mind for me is that Gem's are to Ruby what CPAN is to Perl.

Related

How can I save whole package of Rails App including gems being used?

I'm using a lot of gems. They are really sensitive about dependencies each other.
Now, current combination of the gems is just perfect. I want to save this whole App, and re-use this when I'm going on next project.
As you know, the gems are not promised to exist in the future in rubygem.org
So I'd like to save whole package of both App and gems being used.
Then I don't need to care about setting up gems unless I need new gem.
All I need to care about is just coding in next project.
Someone told me to use this command and save whole App folder
bundle install --path=vendor/bundle
After this, my app got screwed :(
jQuery came not to work anymore after recompile
So I did need to replace whole App folder with old one, which was reffering the gem in /usr/local/bin/ruby /usr/local/lib/ruby/gems/1.9.1
Now, jQuery works fine after recompile :)
For this situation, how can I save whole package of both App and gems being used for it?
What I wanna do is, I only want to set up Ruby's correct version and MySQL.
Then I'd like to put this package into it and start coding, not deploying environment about gems!!
Can anyone share idea about this, please?
Answer to your question
Bundler's bundle package --all command will lock and cache all of your gem files into ./vendor/cache, and you can run bundle install --local so it won't check rubygems.org in the future.
Comments on your question
This question made me cringe because, while I understand the interest in having a "base image" that you know works, it sounds like a few problems will spill over to other projects.
Overburdened applications
Does each project really need all the same dependencies?
If not, then you are bloating each install with unneeded dependencies.
Brittle dependencies
You mention that your dependencies are very sensitive to each other, which sets off alarms.
I don't fully understand what you mean by that, but it sounds like you should consider finding dependencies with more stable interfaces.
Check out ruby-toolbox.com and keep an eye on the "Released" date.
Outdated dependencies
Locking down versions means your new applications will not benefit from updates by the maintainers.
(example) if you locked your rails dependency to 3.2.8 and continue to use it, you open yourself (and customers) to several major security holes.
(possible fix) Look at pessimistic version constraints to allow your applications to receive non-breaking fixes.
Best of luck.

I'm writing a script to install postgresql modules. How can I find the "contrib" directory?

I'm writing a script that will install some of the optional postgresql modules. Is there a way to programmatically figure out where the contrib directory is or do I have to prompt for the path? I've looked at a few examples and it seems inconsistent; doesn't appear in pg_config.
(The script might be run on OS X or linux, and I can't make assumptions about how postgresql was installed).
There is no easy works everywhere answer to this, so it's a matter of how much intelligence you want to try and put into your installer. And for some people it will be impossible to do what you hope for, the best you'll be able to do is offer guidance about what's missing. There is a lot of variation on packaging here between Linux distributions, versions of PostgreSQL, and the various ways you can install PostgreSQL on OS X (MacPorts, homebrew, etc.)
First off, only source code installs will have a contrib directory with source code in it that allows building the optional modules. In the packaged builds for Linux, all the contrib binaries may only be available via an optional package, called something like postgresql-contrib. That's the only way to make the optional modules that come with the database available: install the package the binaries are included in. You may see some variation in the OS X builds here too.
If you want to install extensions (what these are officially called as of PostgreSQL 9.1 now, rather than 'modules') using binaries you provide instead, what you then want to know is where to put the resulting shared libraries and matching SQL files that reference them. What pgconfig returns for pkglibdir will tell you where the binaries go, while sharedir points toward the default place to put the SQL. Providing binaries is a losing game though; the job of syncing with every platform to build them is a huge one.
And here are the sort of additional complications you'll run into in this area, if you wanted to ship source code and try to build things yourself in an automatic way:
PostgreSQL 9.1 now installs these using the CREATE EXTENSION
mechanism, so you'll need to handle both the pre-9.1 method and the
new one introduced there.
Not all PostgreSQL installations will have
pg_config. It's considered a development tool, and which package it
gets bundled with (and whether that package is mandatory or not)
varies. Debian/Ubuntu put it into the optional liqpq-dev, RedHat
derived RPMs have it in postgresql-devel or
postgresql-[version]-devel.
Due to pg_config being necessary for
compiling the new 9.1 extensions, packagers have started
reconsidering where pg_config goes; it's considered a lot more
important now than it used to be. 9.1 or later packages might alter which package it's contained in. That doesn't really change what you can and can't do though. It just impacts what advice you might offer for correcting situations your program can't deal with.
I've been describing the standard
Linux packaging here when I talk about that OS. There are also installers for both Linux and
OS X from EnterpriseDB, what they call their "one-click installers".
These use a different standard altogether for what people do and don't get installed in this area. I don't follow the commercial packaging to know what is actually different, but it's another variable you can expect people to encounter.
Recent OS X versions may
have some system PostgreSQL components floating around too. No idea
yet how this handle extensions though.
Basically, all three of version/packager/platform can vary how this will work, and the idea that you'll find any solution that handles even the majority of those permutations is optimistic. Installing extensions is known to be difficult in PostgreSQL, which is one thing that motivated all the 9.1 changes to turn it into a simple CREATE EXTENSION for many of them. But for now, those changes have just added another whole set of variation into the mix, actually making this harder during the transition period. It will be a while until PostgreSQL versions supporting that are the only ones in popular use.

How do I package a rails as a standalone executable

I've been developing a web application and a lot of customers are asking if they can host the application in their network (for security reasons). I have been looking for a way to package up a rails app into a single executable (with server and all), but haven't been able to find anything. My other requirement is that we distribute it without the source. Because of that I was looking at JRuby and Warbler. The end product should run on linux or windows. Has anyone done anything like this before, or can anyone point me in the right direction.
Thanks
My best guess would be to use JRuby and the JRubyCompiler, although I have no idea if you could compile a whole rails project (including all the required gems). I got it to compile a small ruby script though. Anyway, if you succeed, you could package those in a jar or war and deploy that as a contained application.
It doesn't sound like you necessarily need to package it as an executable, as long as the code is obfuscated. I personally haven't needed to protect any of my code, but a quick google search returned this product http://rubyencoder.com/. I'm sure there are others out there, but the basic idea is that your code is unreadable and cannot be reverse engineered. This would allow you to run a standard rails environment without giving access to your source code.
If you have the budget and really want to outsource this, the Github guys partnered with BitRock to build their cross-platform installable product (Github Firewall Install). BitRock has this case study on their website.

Just starting in Rails --> Is it really buggy these days or is it just me?

I've spent a fair bit of time with PHP & Python frameworks and recently thought I'd branch out to rails. The framework itself I like, but I seem to spend at least half my development time navigating through odd bugs and/or version incompatibilities between rails/ruby/rake/gems.
I'm happy to battle through it all if it gets less of a hassle, but even after a month it seems like I spend 90% of my time chasing down other people's bugs & only 10% of my time chasing down my own. The only guy I've talked to (who used it extensively until 2008) suggests "For the past 2 years, that's pretty much rails"
Any opinion on this? Does it get better, or is this just par for rails development at the moment?
Running it through Ubuntu 10.04, if it matters.
Rails is in transition right now between 2.3x and 3.0 so you are going to find it quite challenging as much of the most recent documentation and rails plugin readmes are being updated for rails 3. There are several tools that are indispensable right now for negotiating this stuff. First, Rails 3 uses bundler to manage dependencies, it is a much more civil way to manage gems.
gem install bundler
cd my_rails_project
bundle install
RVM (ruby version manager) is awesome and I would recommend installing it. Then you can build gemsets and dependency sets on a per project basis. and you don't need to superuser access to install.
also, if it were me, I'd just go ahead and start in rails 3
gem install rails --pre
if you want to stay with rails 2.3.x use the rake task for installing declared dependencies.
rake gems:install
if the project is a good project, it will be pretty specific about what it needs (declared in the config/environment.rb file), then if it doesn't run, checkout the stack traces to see where its failing.
In my experience this is not par for Rails development.
While using gems read the README file on github project repos and have a look at the issues and wikis....that should give you a fair idea of which gem is compatible with your Rails version. Regarding the framework, it is pretty stable....major bugs or patches or releases are reported on weblog.rubyonrails.org
Things grow incrementally with each release and that is obvious. There are some deprecations which are well documented in the Rails code and are reported when you run the code.
Rails itself is pretty bug free. I've not witnessed a bug in the framework itself now for a while unless I've been duplicating open tickets.
Where the problems you're seeing have crept in have been over a couple of different areas:
We've moved as a community from Ruby 1.8.x to 1.9
over the last year or so, and some
gems have specific Ruby version
requirements you need to check out
before using them. Most of the more
popular gems are fine and tested to
work in multiple environments. Read the docs first.
Rails itself has matured
significantly over the last few
years, and that has meant many
features have been deprecated. Lots
of plugins out there were written
for an older version of the
framework and expect behaviour that
just isn't valid any more. Read the docs first.
Several different Ruby interpreters
are now available (which is great),
but these sometimes can have an
impact when it comes to 3rd-party
code, but that's rare. Basically,
some gems and plugins expect to be
running on a specific interpreter.
None of the really popular ones are
like this, but you need to be aware
some gem builders are idiots. Read the docs first.
You might notice there is a common theme to the end of each point: read the docs first. :-)
I would say your experience is not at all typical of most Rails developer's workflows, although we've all had a day of struggling from time to time.
You will learn quickly which gems to trust, which ones you'll need but may struggle with from time to time (mysql - building that kills me on OS X, every time), and which ones you should avoid.
Overall though, the development cycle is more fluid (and you'll develop more rapidly) with Rails once you've got your bearings and are adopting good practice. There's a reason why we all like TDD and BDD though - if nothing else it helps us get through a gem update knowing stuff still works when a developer we don't know has done something moronic. :-)

Need for Rails plugin management tools?

I've been searching for a while, and I can't find any modern rails plugin management tools. I found several gem management tools (such as bundler and isolate), but no plugin management tools. The closest thing to that I found was piston, and that's not exactly what I was looking for was it was for plugin svn:externals management. Our plugins are not using svn:externals. Some can be used as gems, and managed by bundler, but not all plugins are offered by their developers in that form.
They can always be managed by hand, of course, but I'd rather have a tool to keep them current, etc., that works for plugins like isolate or bundler work for gems.
If others could use this I'll see if I can get supervisor approval to work on such and contribute it, assuming also there's not a good or even fair solution out there that I'm missing.
Cheers,
Craig
I use git submodules for that.
But, indeed in Rails 3, it is more natural to package each plugin as a gem, and i think it is the preferred way, especially for the reasons you mention.

Resources