Declaring a class within a module

11,615

Solution 1

what is the advantage of doing it this way?

It serves as namespace so classes with the same name do not clash (so it has nothing to do with mixins). It's standard.

Why are we appending self to class, is that not already implied?

That's just one of the ways of defining class-methods (the other being def self.method_name).

Solution 2

Is this the same as including the module?

No. When you have module Foo; end and then do

class Bar
  include Foo
end

You end up with a class Bar that includes all the methods of the module Foo. But when we do

module Foo
  class Bar
  end
end

We end up with a class Foo::Bar that includes none of the methods in Foo that are not in Bar

What is the advantage of doing it this way?

It allows your to organize your code, if it's needed.

Why are we appending self to class, is that not already implied?

No, it's not already "implied". Doing so is equivalent to defining each method in that block with self. like def self.mymethod; end. See class << self idiom in Ruby.

Share:
11,615
steve_gallagher
Author by

steve_gallagher

I'm a programmer.

Updated on June 05, 2022

Comments

  • steve_gallagher
    steve_gallagher about 2 years

    Surveying work code (in a module called Surveyor, no less), trying to understand it. I ran across this section that contains a class within a module. Is this the same as including the module? If not, what is the advantage of doing it this way? Thanks. (BONUS POINTS: Why are we appending self to class, is that not already implied?)

    module Surveyor
      class Common
        RAND_CHARS = [('a'..'z'), ('A'..'Z'), (0..9)].map{|r| r.to_a}.flatten.join
        OPERATORS = %w(== != < > <= >= =~)
    
        class << self
          def make_tiny_code(len = 10)
            if RUBY_VERSION < "1.8.7"
              (1..len).to_a.map{|i| RAND_CHARS[rand(RAND_CHARS.size), 1] }.join
            else
              len.times.map{|i| RAND_CHARS[rand(RAND_CHARS.size), 1] }.join
            end
          end
    
          def to_normalized_string(text)
            words_to_omit = %w(a be but has have in is it of on or the to when)
            col_text = text.to_s.gsub(/(<[^>]*>)|\n|\t/su, ' ') # Remove html tags
            col_text.downcase!                            # Remove capitalization
            col_text.gsub!(/\"|\'/u, '')                   # Remove potential problem characters
            col_text.gsub!(/\(.*?\)/u,'')                  # Remove text inside parens
            col_text.gsub!(/\W/u, ' ')                     # Remove all other non-word characters      
            cols = (col_text.split(' ') - words_to_omit)
            (cols.size > 5 ? cols[-5..-1] : cols).join("_")
          end
    
          def equal_json_excluding_wildcards(a,b)
            return false if a.nil? or b.nil?
            a = a.is_a?(String) ? JSON.load(a) : JSON.load(a.to_json)
            b = b.is_a?(String) ? JSON.load(b) : JSON.load(b.to_json)
            deep_compare_excluding_wildcards(a,b)
          end
          def deep_compare_excluding_wildcards(a,b)
            return false if a.class != b.class
            if a.is_a?(Hash)
              return false if a.size != b.size
              a.each do |k,v|
                return false if deep_compare_excluding_wildcards(v,b[k]) == false
              end
            elsif a.is_a?(Array)
              return false if a.size != b.size
              a.each_with_index{|e,i| return false if deep_compare_excluding_wildcards(e,b[i]) == false }
            else
              return (a == "*") || (b == "*") || (a == b)
            end
            true
          end
    
          alias :normalize :to_normalized_string
    
          def generate_api_id
            UUIDTools::UUID.random_create.to_s
          end
        end
      end
    end