Why is this simple require failing?

I have a simple require call that is failing with:

ruby mycar.rb

/Users/me/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require’: cannot load such file – mycar/car (LoadError)

from /Users/me/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require'

from mycar.rb:1:in `<main>'

My file layout is:

mycar.rb

mycar/car.rb

mycar.rb looks like:

require ‘mycar/car’

car.rb looks like:

modle MyCar

class Car

end

end

Why isn’t this working, getting frustrated :frowning:

Hi. There is a typo, the correct is Module MyCar

and try doing this: require ‘./mycar/car’

Why doesn’t mine work, very confused??

I’ve never seen that require in any gems on the web thought?

https://github.com/ryanb/cancan/blob/master/lib/cancan.rb

require 'cancan/ability'

require 'cancan/rule'

require 'cancan/controller_resource'

require 'cancan/controller_additions'

require 'cancan/model_additions'

require 'cancan/exceptions'

require 'cancan/inherited_resource'

require 'cancan/model_adapters/abstract_adapter'

require 'cancan/model_adapters/default_adapter'

require 'cancan/model_adapters/active_record_adapter' if defined? ActiveRecord

require 'cancan/model_adapters/data_mapper_adapter' if defined? DataMapper

require 'cancan/model_adapters/mongoid_adapter' if defined?(Mongoid) && defined?(Mongoid::Document)

Ok that made it work, but still doesn’t make sense to me, there must be something else wrong in my environment right?

Also to reference the class, I still needed to prefix the module name which is also strange because I am requiring it!

Example:

require ‘./mycar/car’

MyCar::Car.new # this works

Car.new #didn’t work

Also to reference the class, I still needed to prefix the module name
which is also strange because I am requiring it!

Look up the difference between 'require' and 'include'.

I've never seen that require in any gems on the web

That's because most of the time when you require something, it is a gem,
and gems are installed in specific directories that ruby searches when
you require something. You can see a list of the directories ruby
searches when you require something by doing this:

p $LOAD_PATH

If one of those directories isn't your current directory, and you want
to require a file in your current directory, then your require has to
specify the path(absolute or relative) to the file.

require './your_file.rb'

so why didn’t the file I linked to have to do that? i.e. the cancan gem require’ing its sub-directory files?

That’s because most of the time when you require something, it is a gem,

and gems are installed in specific directories that ruby searches when

I think you misunderstood, I am saying I’ve never seen:

require ‘./folder/file’

I ALWAYS see:

require ‘folder/file’

For example:

https://github.com/ryanb/cancan/blob/master/lib/cancan.rb

https://github.com/Shopify/active_merchant/blob/master/lib/active_merchant.rb

I just don’t understand why mine isn’t working the same way? Did cancan add something to the load path somewhere?

That’s because most of the time when you require something, it is a gem,

and gems are installed in specific directories that ruby searches when
you require something. You can see a list of the directories ruby
searches when you require something by doing this:

p $LOAD_PATH

7Stud was very clear…

The gems are installed to a folder/directory that is in your environment path.

So you won’t see this in a gem, unless someone is unaware of what they are doing, and it would also require you to run that specific gem in some specific folder or directory.

I see what your saying.

I guess what I am asking then is, when developing your own gem, say I am developing my gem on my Mac in:

/Users/me/projects/ruby/gem/some_gem_name/

So this means I have to somehow modify my load_path so that I can just require things like:

require ‘folder/file’

And then when I publish my gem and users use my gem, things will just work since the gem is installed by default at a path that ruby will look in?

How then do gem developers modify their path to have this work?

They don’t. They usually end up using something that 7Stud also mentioned. Which is to say require_relative or they add a relative path to the $PATH variable in some way.

So they don’t modify their path, they use the environment that will be given, and take advantage of this.

You can also use the file itself… you will see many different examples of this in different gems. For example, in Rails Admin, spec/spec_helper.rb you will see require File.expand_path(’…/dummy_app/config/environment’, FILE)

This takes the relative location of that file and load it that way, and so will not require it to know exactly where it was installed, but it can rely on its own project structure.

In IRB go ahead and do that… >> File.expand_path(’.’) you will see what I mean. From that piece of information, build your path as you need to require things for your project.