-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Avoid class A::B
definitions
#332
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
I'm torn on this. Does class A
class B
# body omitted
end
end or does it always have to be a class within a module? There are times when Ruby won't let you do this without nesting (or re-opening) a class. For instance, if you have a top level Are there any other advantages at all to explicitly declaring the module like that? I love |
All nested classes and modules will be picked up. I don't really follow your example @derekprior, could you clarify? |
How we define classes and modules also affect constant lookup: module A
CONSTANT = "a constant"
end
module A::B
def self.test
CONSTANT
end
end
module A
module C
def self.test
CONSTANT
end
end
end
A::B.test #=> NameError: uninitialized constant A::B::CONSTANT
A::C.test #=> "a constant" |
good example @calleerlandsson, that one has bit me once or twice |
9974292
to
0f2f4d0
Compare
Okay, thats cool. I was just saying that sometimes it's necessary to nest a class inside of another class (rather than a module) to get the name you want (i.e. your top level is already a class rather than a module). I mistook your PR description for saying I could only nest into modules. @calleerlandsson interesting, thanks. 👍 |
This seems reasonable. I knew this was a general best practice due to the constant lookup issues mentioned by @calleerlandsson but wasn't aware this also made things easier for CTags. 👍 |
Would the guideline be clearer if it was more than an example? Maybe something like "Avoid defining classes and modules using shorthand nesting ( |
@calleerlandsson Agreed, updated in 5779588 |
@@ -11,6 +11,8 @@ Ruby | |||
* Avoid explicit return statements. | |||
* Avoid using semicolons. | |||
* Avoid bang (!) method names. Prefer descriptive names. | |||
* Avoid defining classes and modules using shorthand nesting (class A::B) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we flip this wording to match the example?
Something like: Prefer nested module definitions instead of the shorthand version
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I sort-off want to keep Avoid
in there to emphesize that we couldn't use A::B
unless it's actually needed
👍 |
1 similar comment
👍 |
Sure. I've been split 50/50 in the past, basically however I feel that day. The |
All the times I've nested modules (and granted I haven't done it that much) have been for convenience. There's no real need to do this though. This seems like a good guideline to me. |
This has been open for more than a week now, and there doesn't seem to be a strong argument against this. Does anyone else have any objections before I squash and merge? |
@@ -13,6 +13,8 @@ Ruby | |||
* Avoid bang (!) method names. Prefer descriptive names. | |||
* Don't use `self` explicitly anywhere except class methods (`def self.method`) | |||
and assignments (`self.attribute =`). | |||
* Prefer nested class and module definitions instead of the shorthand version |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should "instead of" be "over" or "to"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good call, fixed in 7b95965
👍 for merging the guideline. I usually nest the modules instead of the single-line definition, at least until load order begins to matter. Then it can be used as an early warning system with an obvious solution. # file a
module A
class B
# ...
end
end
# file 2
module A
class C
# ...
end
end
# file 3
class A::D
# ...
end In the above code, load order only matters with file 3 since it requires Using syntax in file 3 adds an additional requirement that it be loaded after file 1 or 2, which shouldn't be necessary. |
This is not compatible with `ctags`
7b95965
to
817d5ed
Compare
No objections made, merging |
ctags
is an extremely useful tool for navigating quickly to a class,module, or method definition. Sadly it has a few limitations, one of
them is how namespaced classes/modules are defined.
If we define a class
B
like so:class A::B; end
,B
will never befound nor indexed by
ctags
.By defining classes like:
We can use
ctags
to navigate toB
(andA
for that matter aswell`)