I got bit by assuming that
module A
module B
end
end
and
module A::B
end
are alike. I was able to find a solution from this blog, this SO thread and and this SO thread.
Why and when should one prefer the compact syntax A::B
over the other, given that it evidently has a drawback? I have a intuition that it could be related to performance, as looking up constants in more namespaces requires more computation. But I was not able to verify this by benchmarking normal classes.
These two methods of writing get confused quite often.
First is to say, that to my best knowledge there is no measurable performance difference. (one constant look-up in the below written example)
The most obvious difference, probably the most known, is that your second example (module A::B
) requires for the module A
to exist in the time of the definition.
Otherwise than than that most people think they are interchangeable. That is not true.
Modules are simply constants in ruby and so regular constant look-up applies.
Let me show it on an example:
module A
class Test
end
module B
class Show
p Module.nesting # =>[A::B::Show, A::B, A]
def show_action
Test.respond_with(%q(I'm here!))
end
end
end
end
On the other hand if you call it via the A::B
look what happens:
module A
class Test
end
end
module A::B
class Show
p Module.nesting # => [A::B::Show, A::B]
def show_action
Test.respond_with(%q(I'm here!))
end
end
end
The difference is that .nesting
produces:
1) in the first case: [A::B::Show, A::B, A]
(you are nested in module A
)
2) in the second case: [A::B::Show, A::B]
(here not)
The first one has more information than the second one. Naturally, in most cases, you can assume that the second form can always be replaced by the first one, but not the other way around. In fact, you cannot use the second form unless A
is defined in advance. But be careful that the return values of Module#nesting
differ between the two forms as the method has lexical scope interpretation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With