Ben Biddington

Whatever it is, it's not about "coding"

Archive for January 2010

I’ve created my gem, but can’t require it

with one comment

Creating gems is easy, all you need is a gemspec:

Gem::Specification.new do |spec|
    spec.name = 'chubby-bat'
    spec.version = '0.0.1337'

    spec.files = [
	'./lib/chubby_rain.rb',
	'./lib/crack_murphy.rb',
    ]

    spec.summary = 'An example gem'
    spec.author = 'Ben Biddington'
end

And then to build it:

$ gem build chubby-bat.gemspec

And then to install it:

$ gem install chubby-bat-0.0.1337.gem

No such file to load — xxx

Trouble is, when requiring the new gem, you may encounter an error like:

irb(main):001:0> require 'chubby-bat'
LoadError: no such file to load -- chubby-bat
        from C:/Ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in
            `gem_original_require'
        from C:/Ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `require'
        from (irb):1
irb(main):002:0>

I found this pretty confusing, until I realised the interpreter is looking for a file called chubby-bat.

In short, a gem needs to contain a file with the same name as the gem itself in its lib folder:

And gemspec becomes:

Gem::Specification.new do |spec|
    spec.name = 'chubby-bat'
    spec.version = '0.0.1337'

    spec.files = [
	'./lib/chubby-bat.rb',
	'./lib/chubby_rain.rb',
	'./lib/crack_murphy.rb',
    ]

    spec.summary = 'An example gem'
    spec.author = 'Ben Biddington'
end

Rubygems require

The comment in rubygems custom_require explains:

# See: path/to/Ruby/lib/ruby/site_ruby/1.8/rubygems, custom_require

##
  # When RubyGems is required, Kernel#require is replaced with our own which
  # is capable of loading gems on demand.
  #
  # When you call require 'x', this is what happens:
  # * If the file can be loaded from the existing Ruby loadpath, it
  #   is.
  # * Otherwise, installed gems are searched for a file that matches.
  #   If it's found in gem 'y', that gem is activated (added to the
  #   loadpath).
  #
  # The normal require functionality of returning false if
  # that file has already been loaded is preserved.

Ruby loadpath, gem install and Kernel#require

Installing a gem simply copies files to somewhere in $LOAD_PATH, and invoking require triggers a file search within these locations.

Kernel require does the following:

  • Ruby tries to load the library named string, returning true if successful.
  • If the filename does not resolve to an absolute path, it will be searched for in the directories listed in $:.
  • If the file has the extension “.rb’’, it is loaded as a source file; if the extension is “.so’’, “.o’’, or “.dll’’,or whatever the default shared library extension is on the current platform, Ruby loads the shared library as a Ruby extension. Otherwise, Ruby tries adding “.rb’’, “.so’’, and so on to the name.
  • The name of the loaded feature is added to the array in $”.
  • A feature will not be loaded if it‘s name already appears in $”.

This means if you print out the contents of $”, you’ll see chubby-bat.rb in there.

Advertisements

Written by benbiddington

12 January, 2010 at 13:37

Posted in development

Tagged with , , , ,

Git — remove all deleted files in one line

with one comment

I got sick of manually removing deleted files, this makes it easier:

$ git rm $(git status | grep deleted: | awk '{ print $3 }')

Written by benbiddington

3 January, 2010 at 13:15

Posted in development

Tagged with , ,