Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you make hierarchical class names in Ruby?

Tags:

ruby

In Ruby a class named Foo would be defined with class Foo, used via require 'foo' and would live in $:[0]/foo.rb or something like that.

But what about Foo::Bar? Would it be called with require 'foo/bar'? Would it live in $:[0]/foo/bar.rb? And how would it be defined?

I am very used to Perl, where for personal projects I would make nested classes like Project::User, Project::Text::Index, Project::Text::Search, etc. I would then make a file like Project/Text/Index.pm, which would start with package Project::Text::Index, and be called via use Project::Text::Index;.

Now I'm starting a project in Ruby and have no idea how to do this. For some reason none of the Ruby books or docs I've read mention perl-style hierarchical class naming. When they mention inheritance it's usually via a trivial made up example like class Foo < Bar which doesn't really help me. Yet I figure it must be possible to do what I'm attempting because Rails (just to take one example) has classes like ActionView::Helpers::ActiveModelFormBuilder.

like image 310
Ryan Tate Avatar asked Jan 21 '23 13:01

Ryan Tate


1 Answers

You're combining a couple of concepts here which aren't really related, namely the load path, inheritance, and the scope resolution operator.

When requiring (or loading) files the argument to the require keyword is simply taken as a file path and appended to the load search path (the .rb extension is optional for require). Inheritance and nesting don't come into play here and any file can define anything it wants, e.g.:

require 'foo' # Looks for "foo.rb" in each of $:
require 'foo/bar' # Looks for "foo/bar.rb" in each of $:

Nested classes (and modules, variables, etc) are defined as expected but resolved with the scope resolution operator, e.g.:

class Foo
  def foo; 'foo'; end
  class Bar
    def bar; 'bar'; end
  end
end
Foo.new.foo # => "foo"
Foo::Bar.new.bar # => "bar"

Note that class nesting and inheritance are irrelevant to the location of the file from which they are loaded. There don't seem to be any explicit conventions for class/module structuring, so you're free to do what works for you. The Ruby Language page of the Programming Ruby book might be helpful too.

like image 182
maerics Avatar answered Jan 30 '23 12:01

maerics