Ruby carmen 'NameError' - ruby

I am using the carmen gem and following the instructions there. When I execute these statements:
require 'carmen'
include Carmen
us = Country.named('United States')
I get a
NameError: uninitialized constant Country
even though I have required and included Carmen. require returns true and include returns Object

The reason is that the Github source and documentation you're seeing is for the latest unreleased version. Put this in your Gemfile instead:
gem "carmen", :git => "git://github.com/jim/carmen.git", :branch => "master"
It's probably best to go to Rubygems and subscribe to the library for updates too, as it's not great to have to rely on an untagged branch in a project.

Related

Why does bundler use more than one gem location?

This is happening in Puppet's bundle.
The Gemfile specifies
gem "puppet", :path => File.dirname(__FILE__), :require => false
But one of the gems I installed in $GEM_HOME appears in $: after all.
$ bundle exec ruby -e 'puts $:'
...
/home/puppy/puppet-git-clone/lib
...
/usr/lib/ruby/vendor_ruby
...
/home/puppy/gems/gems/puppet-3.7.5/lib
...
This is not a problem in and of itself, but apparently Ruby will load Puppet 3.7.5 instead of the 3.7.3 I checked out of the git repo.
$ bundle exec irb
irb(main):001:0> require 'puppet'
=> true
irb(main):002:0> Facter.value(:puppetversion)
=> "3.7.5"
Why is Puppet not loaded from the git tree and how can I debug this further?
Update
Puppets .gemspec might be involved. It's clever about specifying the version. I now worry that Rubygems does in fact load the installed 3.7.5 gem so that Puppet.version would truthfully report a wrong value, throwing off bundler. Could that be what's happening?
Update 2
As suggested in the comments, I tried settings the path and version statically in the Gemfile.
gem "puppet", "3.4.2", :path => "/home/puppy/puppet-git-clone", :require => false
As for the result, well - at least bundler is consistent in its views ;-)
Could not find gem 'puppet (= 3.4.2) ruby' in source at /home/ffrank/git/puppet.
Source contains 'puppet' at: 3.7.3
Run `bundle install` to install missing gems.
The quick fix is to add -Ilib to your ruby command:
$ bundle exec ruby -e "require 'puppet'; puts Facter.value(:puppetversion)"
3.7.5
$ bundle exec ruby -Ilib -e "require 'puppet'; puts Facter.value(:puppetversion)"
3.7.3
If we compare the load paths, you can see that adding -Ilib results in 3.7.5 not being present in the second load path:
$ diff <(bundle exec ruby -e 'puts $:') <(bundle exec ruby -Ilib -e 'puts $:') | grep 'puppet-'
< /Library/Ruby/Gems/2.0.0/gems/puppet-3.7.5/lib
It seems like this should be the default behavior, so there may be a bug in bundler.
Provided you've deleted your Gemfile.lock and removed all other versions of the gem before trying bundle exec ... although not explicitly defined by the same problem, this is a known problem with Bundler check this out:
https://github.com/bundler/bundler/issues/3585
And it ought to be fixed as of this merged Pull Request:
https://github.com/bundler/bundler/pull/3592
This will cause your "preferred source" to be favored, and used.
( Links used as answer because this refers to existing activities, not a solution I could put here in the answer. Not link-only answer. )
try this :
source "file://home/puppy/puppet-git-clone"
gem "puppet", "3.4.2", :path => "/home/puppy/puppet-git-clone"
why do you need require false?
After what you said in my previous answer, try this:
Add gemspec to your Gemfile near the top.
If you do this, the subsequent gem ... calls will override the gemspec which is ultimately setting the version.
Add it right here:
source ENV['GEM_SOURCE'] || "https://rubygems.org"
gemspec # and let me know if this fixes it
Like I recently said, I found the same problem you had, in my own projects. And I've solved it by a workaround. The idea itself is what I'm giving here, I'm not saying it's the most efficient or bug-free way. A variation of this approach worked for me.
It involves hijacking Gemfile and perhaps gemspec, depending on what's the offender in reality -- that part is still unknown. My most recent answer, the second approach I gave could solve this already. If not, you may need a workaround. There are many standing impasses for Bundler.
As a work around, insert a curator.
I suggest, at the end of Gemfile you insert a processor such as this one, to curate Bundler::Dsl yourself. We can focus completely on the gem you're looking to resolve, but it could be done for any and all gems.
For example... this is mostly a concept, it may run, but it may have a bug. You will need to harden it. This will remove everything but the version you expect:
PUPPET_VERSION = 'version desired'
until(current = self.dependencies.find { |d| d.name == 'puppet' }) == 1
current.each { |gem|
if !gem.version == PUPPET_VERSION
self.dependencies.delete(current)
end
}
end
I'm not sure which version you actually want. There are three versions mentioned, 3.7.3, 3.7.5 ... just plug in the one you do want. Any other versions will be purged from the dependencies Bundler is working with.
I had the same problem in past, I think you can specify your gem without the 'require: false' parameter and it will look for the Gemfile specific version.
gem "puppet", "3.4.2", :path => "/home/puppy/puppet-git-clone"
If you specify the 'require' option with 'gem' and run the irb command with bundle exec irb it always load the latest version for the gems which has declared with require: false option.

Can't see custom local gem

This is a topic.gemspec:
Gem::Specification.new do |s|
s.name = 'topic'
s.version = '1.0.0'
s.date = '2012-12-30'
s.files = ["lib/models/topic.rb"]
end
The gem is located in my application root.
in Gemfile:
gem 'topic', :path => '.'
While running the app, I can't see the topic class.
uninitialized constant ApplicationController::Topic
What am I doing wrong?
Thanks.
You should make sure that bundler required your gem. You should have a file lib/topic.rb. Add a puts statement and check if it is shown when you boot your app or the console.
As a side note. I don't think you should have a gemspec in the root of your directory. This will lead to the fact that your lib folder is used for the gem and for the rails app. It's better to create a subfolder for example topic/ and then host the gem inside. You can then add it in the Gemfile with:
gem 'topic', :path => './topic'
I highly recommend you place your gem in it's own directory as Yves mentions.
But you can also have other issues, lets try a few things:
It's seems you are trying to use Topic inside a controller, and maybe it's not searching outside? :s Try to use ::Topic instead. :: tells to look at the "root" so it wont search a ApplicationController::Topic
If that does not work maybe you don't have a namespace in your gem. I think bundle or whatever requires the namespace (module) named the same way as the gem so you should have:
# in topic/lib/topic.rb
module Topic
end
#require other parts of the gem
require 'topic/foo'
require 'topic/bar'
Hope I could help

Gemfile - separating Production gems from Development gems

So I know that in a Gemfile I can do something like this:
group :development, :test do
gem 'gem1'
gem 'gem2'
end
What I am looking to accomplish is something like this:
group :production do
gem 'gem1'
gem 'gem2'
end
group :development, :test do
gem 'gem1', :path => '/Documents/Code/gem1/'
gem 'gem2', :path => '/Documents/Code/gem2/'
end
So our application uses 2 gems that we also develop locally. In order to improve time while developing on our local machines, we want to be able to point our dev environments to the local copies of the gems - this way it picks up all changes without needing to restart our rails server. Otherwise we would have to rebuild the gem, re-install the gem, and restart rails with every development change in the gem.
However, doing this gives me the following error:
You cannot specify the same gem twice coming from different sources. You specified that gem1 (>= 0) should come from an unspecfied source and source at /Documents/Code/gem1
I have tried even running something like bundle install --without production and I get the same error.
Does anyone know if it IS possible to do what I would like to do?
Thanks!
i think that there is a supported way to do it and some hacks to work around it.
supported way:
use bundle config with the local option as described here: http://bundler.io/v1.3/man/bundle-config.1.html
hacky way:
use env vars and execute bundler before using in production: http://www.cowboycoded.com/2010/08/10/using-2-sources-for-a-gem-in-different-environments-with-bundler/
there is a feature-request for this problem on github with several related issues and lots of comments: https://github.com/carlhuda/bundler/issues/396
the github issue phoet linked to is resolved, and is consistent with the supported way.
I dug around through the docs, you'll need to set the config variable and updated your gemfile to reference the branch as well.
e.g.
edit your Gemfile:
gem <gem_name>, git: <git_url>, branch: <branch>
on command line:
bundle config local.<gem_name> <local_path_to_gem>
I solved this by creating a new Gemfile that's identical to the original except for the target gem's source. Then, in config/boot.rb, I used:
require 'rails'
if Rails.env.development?
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../DevGemfile', __FILE__)
else
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../ProdGemfile', __FILE__)
end

Developing a gem in parallel with another project

Let's say your working on a product, and you realise that some of the code is general enough to be extracted out to a gem.
So you create a new project, build the gem, publish it to Rubygems, and then reference it in your main project's Gemfile.
Then you discover a small bug with how the gem interacts with your product. Each time your make a fix, building and installing the gem locally can take about 15 seconds. How do you minimise this to have a quick develop/test cycle?
(Also it seems that the locally built gem's version number could contradict with what you've pushed to Rubygems, leading to confusion.)
Any best practice guides on this subject?
bundler doesn't just know how to get gems from rubygems. You could point it at a git repository
gem 'mygem', :git => 'git => 'git://github.com/...'
or, much more conveniently in this case
gem 'mygem', :path => '~/work/mygem'
where the path option points to the folder with the gem's source

Writing a Jeweler Rakefile that adds dependencies depending on RUBY_ENGINE (ruby or jruby)

I have a Rakefile that includes this:
Jeweler::Tasks.new do |gem|
# ...
gem.add_dependency('json')
end
The gemspec that this generates builds a gem that can't be installed on jruby because the 'json' gem is native.
For jruby, this would have to be:
Jeweler::Tasks.new do |gem|
# ...
gem.add_dependency('json-jruby')
end
How do I conditionally add the dependency for 'json-jruby' when RUBY_ENGINE == 'java'?
It seems like my only option is to manually edit the gemspec file that jeweler generates to add the RUBY_ENGINE check. But I'd rather avoid this, since it kind of defeats the purpose of using jeweler in the first place.
Any ideas?
After some more digging around, I've come to the conclusion that the problem here isn't so much the limitation in Jeweler as it is a problem with how the json-jruby gem is named.
In a perfect world, the json-jruby gem should be named just json. That way when the gem file is built under JRuby (i.e. jgem build json-jruby.gem), the resulting gem file would be named json-1.4.3-universal-java-1.6.gem (RubyGems names the file based on the 'platform' property in the gemspec). When installed with the appropriate platform in the gem name, everything works transparently. There's no need to explicitly require json-jruby. RubyGems uses the appropriate version automatically.
I've contacted the maintainer of the json gem to see if he'd be willing to get json-1.4.3-universal-java-1.6.gem added to his gemcutter repo, but in the meantime you can download the drop-in jruby json gem here: http://roughest.net/json-1.4.3-universal-java-1.6.gem

Resources