Reputation: 266940
On my server (or laptop for that matter) whenever I install a gem using:
gem install mygemname
or in my gemfile:
gem 'mygemname'
It will install on the computer to some folder on my computer.
Can I go to that folder and edit the file if I want to say add some logging etc.?
If this is not possible, I remember reading that you can have the gem source code installed in your rails 3 application under the 'vendor' folder. How do I install it locally so I can edit it and add logging to it (to learn how it works etc.)
Upvotes: 21
Views: 12503
Reputation: 26997
Yes
Absolutely Not.
There are a few ways to solve this problem:
If you feel that this 'change' would benefit the entire community, find the source code (most likely on github), fork, apply the patch, write tests, and submit a pull-request. If the developer agrees that your patch is viable, it will be merged into the project and released with the next version of the gem.
AdvantagesIf you don't think this is something the entire community would benefit from, but you still want to allow your other developers to use the gem in a systematic way, fork the existing gem, apply your patch, rename the gem, and publish. in this case, it's good practice to prefix your custom gem with the original gem name. For example, if the gem was named foo
, you would name your gem foo-my-company
. You now can choose to open-source that gem (push to rubygems) or push it to a private development gem server within your organization. You still must source the original gem author in your re-gem!
You can create a monkey-patch inside your application and override any methods or properties that don't fit your current environment.
AdvantagesThis is my recommended option. Why did I put it last - the other ones are more common. In this method, you fork the gem from its original repository (probably on github), and then source your gem from your git repo. For example, say the gem was named foo
, you would fork foo
to username/foo
on github. Apply you patches, changes, whatevers. Then in your Gemfile:
gem 'gem_name', :git => 'git://github.com/username/foo'
This will install and compile the gem from source at your repo every time the bundle command is run. You can also specify a particular tag and branch (recommended to stability).
AdvantagesEach method has its own advantages and disadvantages (which I've tried to enumerate as best as possible). In any event, the method you suggested is not an advised method for solving that problem.
If readers have comments about other advantages/disadvantages, please list them, and I'll add them to my answer.
Upvotes: 69
Reputation: 160551
We have had this discussion at work, and it is a practice I discourage.
Gems are made to be updated when improvements and bug-fixes are made. That will instantly wipe out the changes you have done, breaking your code.
You can freeze your version by making it read-only, or use bundler or copying the entire Ruby distribution, but in each of those you are going against the flow.
Instead, I recommend:
lib
directory, and made the change there, then required
it last, allowing the method to be fixed without subverting Gem's normal use. require
if/when the change is accepted.I used to work at a major corporation that decided it was a good idea to make a patch to one of the source files in their mail system. The software was not something they wrote themselves, so, as time went by, they spent more and more time having to roll in their "special" changes to the software as the vendor grew the product. Eventually, it took months to roll in the changes and made the software fragile, which is not a good thing for something that is a core-business service. Ruby's ability to redefine a method would have saved them untold dollars and months of work.
Upvotes: 1
Reputation: 1237
Dave Newton's advice is wisdom and you should take it, but there's nothing wrong with taking a look at it to learn something. Running gem env
will show you where your gems are installed; the lib
directory is where you tend to find the meat of the code.
Upvotes: 3
Reputation: 160181
Sure, it's just code.
Should you? Not in general, since it could be re-installed, updated, etc.
Since you can re-open classes IMO it's safer to monkey-patch, embrace and extend, etc. This isn't always as practical as direct modification, of course.
For educational purposes (when it doesn't matter if modifications are lost), it's fine, and makes more sense than duplicating everything. AOP-ish logging is often doable w/o modifying the original source, though. Sometimes cloning a repo and using it, particularly during exploratory phases, is cleaner.
Upvotes: 4