开发者

How do you make hierarchical class names in 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 cl开发者_高级运维ass 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.


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.


You need modules. If you want a class identified by Funthing::Text::Index in Funthing/Text/Index.rb and be required with require 'Funthing/Text/Index', you do this:

# file Funthing/Text/Index.rb
module Funthing
  module Text
    class Index
      def do_the_twist()
        puts "Let's twist again!"
      end
    end
  end
end

Then use it like this:

require "Funthing/Text/Index"
c = Funthing::Text::Index.new

Note: the file hierarchy is not required, but (in my opinion) is best practice.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜