tags:

views:

139

answers:

3

Hi All,

I am a starter with ruby, I searched that if someone else has asked similar question but was not able to find any. so I am asking it here.

I am trying my hand at modules in ruby.

I created a folder Project

inside Project folder, created a class One

class Project::One

  include Project::Rest

end

inside Project folder, created a module Rest

module Project::Rest

 def display
   puts "in display"
 end

end

but when I try to run the program(ruby one.rb) I get the

uninitialized constant Project (NameError)

Please help me

A: 

The issue is that you're not nesting your classes/modules correctly. You have to declare a module with the module keyword, not merely by writing class Project::Class. Assuming you have this structure:

Project/
    one.rb
    rest.rb

then your files should look something like this:

# one.rb
require 'rest'

module Project
  class One
    include Project::Rest
  end
end

# rest.rb
module Project
  module Rest
    def display
      puts 'in display'
    end
  end
end

Note how the modules are nested in these examples.

mipadi
A: 

If you have code in multiple files, you have to load those files before you can access what's in them. This is usually done with a require statement. I think what you want to do should look like this:

# one.rb
require 'rest'
module Project
  class One
    include Rest
  end
end


# rest.rb
module Project
  module Rest
    def display
      puts "in display"
    end
  end
end
Alex Reisner
+2  A: 

The problem is that you never actually define the Project constant. You have to define it before you can use it. Example:

# root.rb
module Project
end
require "project/test"

# project/test.rb
class Project::Test
end

You should then be able to run ruby root.rb. Another approach is to state the module in the namespace.

# root.rb
require "project/test"

# project/test.rb
module Project
  class Test
  end
end

With this example, you are able to run ruby project/test.rb as well, since the Project module is defined in that file.

And if you have multiple files defining the Project module, that's not a problem either. It won't be re-defined, it will always be the same module.

Both of these methods will define the Project module. Simply going Project::Test will not, however, define the module.

As a sidenote, Rails has a auto loader. If you're in a rails app, and use a certain folder structure, these kind of intermediate modules will be defined for you. Without Rails, though, you have to define them yourself.

August Lilleaas
thanx for your reply...now I understand what I was doing wrong....your side note was very helpful as I had seen the same work in rails application
markiv
This answer is correct. However, the two below answers are correct as well, and perhaps more in keeping with the example given in the question. Could whoever down-voted Mipadi and Alex's answers perhaps explain why? I think it is misleading that they have negative scores since they work, and the difference is mainly one of style and application layout (which wasn't clear from the question).
Alex Reisner
The down-votes were from me. I actually tried to retract them because I came to the same conclusion as you, but it was too late. Apparently, you can only retract a vote shortly after you voted.
August Lilleaas