Kit Ho
Kit Ho

Reputation: 26968

Any difference declaring class using :: or module?

module Api
  module V1
    class ABC
    end
  end
end


class Api::V1::ABC
end

Any different between these to declare a class?

Any pros and cons?

Upvotes: 3

Views: 54

Answers (1)

Arup Rakshit
Arup Rakshit

Reputation: 118261

Yes, there is a difference while you will be doing constant lookups. Module::nesting will be helpful here to things get cleared for you.

module Api
  module V1
    class ABC
      p Module.nesting
    end
  end
end

# >> [Api::V1::ABC, Api::V1, Api]

module Api
  module V1
  end
end


class Api::V1::ABC
  p Module.nesting
end
# >> [Api::V1::ABC]

Module.nesting returns the lexically enclosing classes/modules which are searched before Ruby walks up the class/module hierarchy to find the constant.

It means, with the following code :

module Api
  module V1
    X = 12
  end
end

X = 10
class Api::V1::ABC
  p X
end
Api::V1::ABC.superclass # => Object
# >> 10

While constant looks-up will be happening, it will first search to the array of constants, which has been given by Module.nesting, if not found then, up to the ancestor chains/included modules. It means following to the Api::V1::ABC.ancestors outputs.

Now in the above example, you can see that value of X printed, which is defined in the Object, not inside the API::V1. The reason as I said above.

Now coming to another example below :-

X = 10
module Api
  module V1
    X = 12
    class ABC
      p X
    end
  end
end

# >> 12

Here the constant look up will follow through the array [Api::V1::ABC, Api::V1, Api]. You can see the output found as 12, as Api::V1 has a constant X defined into it.

Thus we can say - Yes there is a difference between the 2 declarations.

Upvotes: 3

Related Questions