rubocop / ruby-style-guide Goto Github PK
View Code? Open in Web Editor NEWA community-driven Ruby coding style guide
Home Page: https://rubystyle.guide
A community-driven Ruby coding style guide
Home Page: https://rubystyle.guide
Should we open a issue and discuss it or pull request the suggestion?
I'm taken aback by this example of a one line if alternative. Maybe it's hard to read only for me. Can you point to any examples of this in use?
I think this guide is turning into something great.
As many people have already seen it and probably even more will, it has the potential to become a bit more official than it wants to be :) Along these lines, I think it will be a good idea to include convention hints for some of the rarely-used constructs.
Thus, it is my opinion that adding some info on the %
-notion (e.g. %w
, %W
, %q
, %Q
, %r
, %{...}
, etc) won't be a bad idea. I, personally, haven't seen anything consistent on the subject out there.
Also it should be noted that these constructs must be avoided unless they're really needed in the particular situation.
What do you guys think?
So far this guide states that:
Use spaces around operators, after commas, colons and semicolons, around { and before }.
However, all examples using string interpolation do not use spaces ("Example #{self.number}"
).
Because of the previous statement, I've started using a string interpolation style like this:
"Example #{ self.number }"
Obviously, there cannot be a space before {
and it cannot required to have one after }
,
as that is part of the string. However, I find it nice to have the visual distinction that there is code
between {
and }
.
Thoughts?
The example isn't even multiline, which makes it contradict a later rule.
Never use then for multiline if/unless.
-good
if x.odd?
puts "odd"
end
Favor modifier if/unless usage when you have a single-line body
-bad
if some_condition
do_something
end
-good
do_something if some_condition
if x.odd?
puts "this extra puts make the this if multiline. the original example wasn't even multiline"
puts "odd"
end
I think I first ran into this style in Python, but I can't be sure. The idea is that in a multi-line liter Hash or Array, you leave a trailing comma on the final element, thus:
DEFAULTS = {
page: 1,
per_page: 50,
sort_by: name,
}
The thinking is that it makes adding elements easier; it's easy to forget to add a trailing comma to the line before your new element, you don't clutter a diff by changing a line that, really, didn't have to do with your changes and you can copy/paste any line up or down the list without having to edit it.
Personally, I like this style, but I know others disagree. I thought I'd see what people thought here. So... thoughts?
One of the reasons people don't like using assignment within if statements is because of how common it is for
There's a convention I've used to make it clear that the assignment is intentional:
# Intentional assigment
if (v = array.grep(/foo/))
...
end
# Oops, this should be equality
if v = 1
...
end
I like this because it sort of separates the assignment from the conditional, and clarifies the intention.
What do y'all think?
Minor issue in parenthesis example (about line 363)
class Person
attr_reader name, age
# omitted
end
should be
class Person
attr_reader :name, :age
# omitted
end
Use when x then ... for one-line cases. The alternative syntax when x; ... is deprecated in Ruby 1.9.
This is actually not true. The syntax that was deprecated was when x: ...
, with a colon, to avoid collision with the new hash literal syntax (eg: when key: value then :result
)
I prefer to use when x; ...
, since horizontal space is at a premium, especially when assigning the result to variable. The then
is also kind of line-noise-y too, as it's implied by the presence of a when
.
Anyway, I'm not against suggesting use of then
for one-liners, but when x; ...
is not deprecated, and should maybe be the suggested method. Discuss?
EDIT:
Never use if x; ... - it is deprecated in Ruby 1.9. Use the ternary operator instead.
This is also inaccurate. Bad for other reasons, but not deprecated.
I agree with "Use spaces around operators..." except. What I never do it for **
. To me,
e = M * c ** 2
Looks less like what it is than
e = M * c**2
What do others think about this? Is **
an exception, or am I being idiosyncratic?
I realize that it's not always easy to provide explanations for every style recommendation, but I think an explanation of why the recommendation was made will make it easier to remember and follow.
For example,
"Prefer %w to the literal array syntax when you need an array of strings."
Why? Is it just because the syntax is shorter? What if my elements have spaces in them, what should I do then? Knowing why this recommendation was made might help me better make a judgement call on edge cases and will hopefully help me understand when it's OK not to adhere to the recommendation.
Excellent work! I ask that you reconsider "Avoid return where not required."
The return keyword is excellent syntactic sugar for two reasons:
Can we build consensus behind whether to use spaces around =
when assigning a default value to a method parameter?
For example:
def method_one(arg1=:default, arg2=nil, arg3=[])
# do something...
end
vs.
def method_two(arg1 = :default, arg2 = nil, arg3 = [])
# do something...
end
I vote for leaving out the spaces as in method_one
.
Hiho!
I find your 'use || instead of or' misguiding, since it simply means something else (which most people don't know):
puts 3 || 4
3
=> nil
puts 3 or 4
3
=> 4
I'd suggest to explain s/th about the awkward precedence or whatever.
Best, Peter
Style guide contains a conceptual typo as in the title
I'm wondering about thoughts regarding the new hash syntax. We're discussing it at my company as well and waffling back and forth.
This looks pretty good:
{foo:1 bar:"baz"}
But that becomes jarring in the cases where you do need string keys:
def gimme_hash(key_suffix)
{"prefix_#{key_suffix}" => 1}
end
And when working in Rails, this isn't easy on the eyes, though this may be due to the newness of the syntax:
class MyModel < ActiveRecord::Base
validates :title, presence:true, if: :title_needed?
end
To be fair, that could be rewritten as:
class MyModel < ActiveRecord::Base
validates :title, presence:true, if:"title_needed?"
end
But the semicolon switching back and forth on that line makes it a little uncomfortable to read.
The chapter "The Ruby language" of "Programming Ruby 1.9" doesn't document the use of semicolons for case expressions - it only mentions then
. It may be syntactically valid, but it's so unusual that it shouldn't be used. Semicolons should only exist when they're being used to put multiple lines of code on a single line, and it should be rare enough that it's a code smell. If semicolons are regularly used, then they don't leap out as a warning that your code smells.
I suppose few people will be with me on this, but meh.
Recently I converted from being a space guy to a tab guy, the thing is simple, tabs for indentation are awesome, because the next guy can choose the indentation space, there's people that like 2 spaces, there's people that like 4, and there's even people that like 8, why forcing them to see everything in 2 spaces?
The underlined part after the tab (it starts at that grey dot) are spaces, this means that the real look of the code won't change, only the indentation.
In short, tabs for indentation, spaces for aligning. If your code looks different when you change indentation size, you're doing it wrong.
/discuss
I can't see anything about indenting multi-line method calls, which are relatively common if you need to supply a lot of params to an object.
Examples of the styles:
# Original
def send_mail(source)
Mailer.deliver(to: "[email protected]", from: "[email protected]", subject: "Important message", body: source.text)
end
# Two-indent
def send_mail(source)
Mailer.deliver(
to: "[email protected]",
from: "[email protected]",
subject: "Important message",
body: source.text)
end
# Four-indent (my preferred)
def send_mail(source)
Mailer.deliver(
to: "[email protected]",
from: "[email protected]",
subject: "Important message",
body: source.text)
end
# Aligned
def send_mail(source)
Mailer.deliver(to: "[email protected]",
from: "[email protected]",
subject: "Important message",
body: source.text)
end
I prefer double my normal indentation (so four spaces) to make it clear these are params, but I don't think it's common at all. I'm not keen on aligned style even though it's more common because of the effort and maintenance required.
What do you think should be in the style guide?
I am using the following style for long literal arrays:
[ :one, :two, :three, :four, :five, :six, :seven, :eight, :nine, :ten, :eleven,
:twelve, :thirteen, :fourteen, :fifteen, :sixteen ].each do |n|
puts n
end
or sometimes:
[ :one, :two, :three, :four, :five, :six, :seven, :eight, :nine, :ten, :eleven,
:twelve, :thirteen, :fourteen, :fifteen, :sixteen
].each do |n|
puts n
end
Would you recommend this?
(For short arrays i am using [1, 2, 3]
.)
Ruby doesn't have Python-style keyword arguments so I think it's important to give some guidelines on the matter. My personal preference for method signatures is:
def method(arg1, arg2, options = {})
end
Where arg1 and arg2 are compulsory arguments and the ones in options are not.
Secondly, there is the problem regarding the default values of the options. This is how I usually handle it:
def method(arg1, arg2, options = {})
options.reverse_update!({
opt1: default_value_for_opt1,
opt2: default_value_for_opt2,
opt3: default_value_for_opt3,
})
end
Hash#reverse_update! is not vanilla Ruby but you can always use an Hash#update + assignment. This simple snippet gets you all the power of keyword arguments (except it's not in the signature therefore it's not automatically documented).
eg:
class Foo
def bar
end
private # this
def baz
end
protected # versus this
def quux
end
end
I'm not sure which is the most widely-used. I know Rails uses the former, but I don't have a strong opinion. I feel like a style guide that suggests using private where applicable should also dictate how to indent it.
Hi,
I'd like to know the reason of this recommendation :
Use
def
with parentheses when there are arguments. Omit the parentheses when the method doesn't accept any arguments.def some_method # body omitted end def some_method_with_arguments(arg1, arg2) # body omitted end
Is there a good reason, and if so, can someone flesh out the recommendation?
I usually don't add the parens in this case, and I don't see why I should do
No major qualms with the guide, though I prefer this format for visibility keywords as I find they are easy to lose track of when indented to match the method definitions.
class SomeClass
def public_method
# ...
end
private
def private_method
# ...
end
end
I find the layout pleasingly analogous to constructs like this:
def foo
# main logic goes here
rescue
# failure handling goes here
end
Wondering which the preferred method...
Reference the instance variable with the "@" notation from within the class:
class Sample
attr_reader :color
def initialize(color)
@color = color
end
def demo
@color
end
end
or referencing the instance variable with the getter representation:
class Sample
attr_reader :color
def initialize(color)
@color = color
end
def demo
color
end
end
Likewise the setter variant:
Reference the instance variable with the "@" notation from within the class:
class Sample
attr_accessor :color
def initialize(color)
@color = color
end
def demo
@color = "awesome color"
end
end
or referencing the instance variable with the getter representation:
class Sample
attr_accessor :color
def initialize(color)
@color = color
end
def demo
self.color = "awesome color"
end
end
The block form of class_eval is preferable to the string-interpolated form.
This statement is made with no backup and in my experience it's not true either. It can be confusing to work with live code that has access to variables from the scope that generated it as well as its own state.
If someone has backup for this assertion, I'd be very interested to see it.
Hi,
I miss some rules on the initializers of Arrays and Hashes. I prefer to use
{}
and []
over Hash.new
and Array.new
.
Sets are a bit more difficult, I myself use Set.new
, when an array is empty but otherwise [foo, bar].to_set
.
Another notation of this would be Set[foo, bar]
, but i prefer the other.
Any comments?
I had a discussion with someone this week about a method with a '!'-postfix, lets say its called order!
When I call foo.order!
I could not think of a use case where its return value is not the ordered foo
.
This convention is useful in method chaining (though chaining is not always a good thing).
e.g.
foo.order!.validate!
What do you think about this?
Maybe it would be good to add conventions about '?' and '!' postfixes in method names anyways?
even thought they are quite basic?
I'm sorry but Ruby is a programming language aimed for humans to understand, right?
So if I ask a journalist to tell me what this is what would he say:
result = some_condition ? something : something_else
How about when I ask him to interpret this:
result = if some_condition then something else something_else end
This rule doesn't make sense, you should interchange the "good" with the "bad".
After vacillating for years, I finally found a rule that works for me:
Parens when you're treating it like a class verb (Array.delete
) OR a function (Math.sin
)
No parens when you're treating it like a DSL: class macros (has_many
), rspec (should_be
), Rails migrations (t.string
)
Saying Array.delete e
just feels naked to me, and I usually hate extra parens. Am I wrong on this one? Is this really the growing style? Most Rails core source I've seen uses parens here, though I haven't looked at much non-Rails source.
You state:
"Prefer single-quoted strings when you don't need string interpolation or special symbols such as \t, \n, ', etc."
I disagree with that.
This is not a convention widely followed. For example I'd say that you will find more double quoted simple strings in Rails than single quoted ones (if you exclude requires
which are typically single quoted).
It's a rule I personally dislike because I usually do not know if a string will ever require a special character or interpolation (again except for require
s). Example:
raise ArgumentError, 'Expected a string'
could later become:
raise ArgumentError, "Expected a string, got #{some_arg}"
I dislike having to change single quotes to double quotes.
Regarding breaking up a method into logical paragraphs how about an empty line before control structures like if, while, return / return values, break, maybe also the ternary operator, etc. UNLESS it's the first line at the current "block".
Code sample:
def enforce_ssl?(req)
enforce = false
keys_by_type = {
:hosts => [:only_hosts, :except_hosts], :path => [:only, :except],
:methods => [:only_methods, :except_methods]
}
if !keys_by_type.values.flatten.compact.any? { |option| @options[option] }
return true
end
keys_by_type.keys.each do |type|
enforce = enforce_ssl_for?(keys_by_type[type], req)
next unless enforce
keys_by_type.each do |other_type,sub_keys|
next if type == other_type || !sub_keys.any? { |option| @options[option] }
enforce = enforce_ssl_for?(sub_keys, req)
break unless enforce
end
break if enforce
end
enforce
end
The naming section mentions whether to capitalize methods, variables, classes, modules and constants, but doesn't mention whether or not to capitalize symbols.
Are they generally :snake_case
?
OK, so I was reading this. I like it, but it certainly states some opinion-things a little too emphatically.
Then I realized how it should be.
The whole deal should be interactive, where you can opt in or out of the items. Some things could be locked completely, because they are truly community-wide choices, like 2-space indentation. Other things would be radio-button options.
Imagine something like the old "Geek Code" which would encapsulate your choices. It would only populate for deviances.. so your style code would be something like the straight-up "bbatsov/ruby-style-guide", where rking's would be like: "bbatsov/ruby-style-guide?if_and_ok,minimal_parens,..."
Then, as another layer to the idea, you take each visitor's deviances and hash them down. So the first guy gets the short-hand "bbatsov/ruby-style-guide?1" ... the 16th guy gets "bbatsov/ruby-style-guide?f", and so forth. The cool thing is that collisions start happening. If you pick the exact same settings as someone else, you'll find out, "Oh, hey, I'm actually style '3f'." Then the other cool thing about it is that the popular choices become lower-numbered hashses, so you can tell at a glance how common the style choice is.
There are plenty more problems to solve, but I'd be interested to know if you are up for the challenge.
-☈
Great work on the whole!
I dislike this example:
kind = case year
when 1850..1889 then "Blues"
when 1890..1909 then "Ragtime"
when 1910..1929 then "New Orleans Jazz" when 1930..1939 then "Swing"
when 1940..1950 then "Bebop"
else "Jazz"
end
puts kind
This is a code smell to me. Put the case statement in a method, then call the method:
def kind
case year
...
end
end
puts kind
I would say the same about using the ternary operator. Most of the time it is used, it is used to be able to assign a variable in one line. So expand it to if .. else .. end
and put it in a separate method.
I'm about to introduce a new section devoted to data structures. This issue is the place to share your opinion about good and bad practices that you want to see listed in the new section.
Just my 2 cent, I find indenting 1 level deeper for private
, protected
and public
would help eyes navigating through blocks more easily. Additionally, I prefer having 2 newlines between normal codes and those declarations.
public
def abc; end
def cde; end
private
def abc; end
def cde; end
protected
def abc; end
def cde; end
I know it is more of personal taste of style but I'd argue my style has some edge advantages.
I'm about to introduce a new section devoted to regular expressions. This issue is the place to share your opinion about good and bad practices that you want to see listed in the new section.
I'd like to see conventions for "proper" use of notes tags like 'todo' etc
which can be collected using
rake notes # Enumerate all annotations (use notes:optimize, :fixme, :todo for focus)
I use the convention to use _ for a variable name when not used. e.g:
some_hash.map { |_, value| value + 1 }
would be a nice addition to this guide I think
I'd like to see more detail on writing rdoc comments.
I'd like to suggest the following styles regarding to method calls.
Given the method:
def say_hi(name, surname = nil)
"Hi #{name} #{surname}!"
end
# good
say_hi("John", "Doe")
# bad
say_hi "John", "Doe"
# good
say_hi "John"
# good
output = say_hi("John")
# bad
output = say_hi "John"
# good
pretty_print say_hi("John")
# bad
pretty_print say_hi "John"
# good
pretty_print say_hi("John", "Doe")
# bad
pretty_print say_hi "John", "Doe"
Please feel free to give your impressions. And congrats for the great work!
We should add a guide for the use of heredocs. Probably worth adding the whitespace-stripping and hyphen to ignore whitespace before the END.
variable << -END.gsub(/^\s+/, '')
I am a
very long
string (but not really)
end
#=> "I am a\nvery long\nstring (but not really)
I'm about to introduce a new section devoted to metaprogramming. This issue is the place to share your opinion about good and bad practices that you want to see listed in the new section.
I tend to separate methods in to logical groups, somewhat like using context
blocks in tests. For example:
class Cart
# ==========================
# Add / Remove Items
# ==========================
def add(item)
# ...
end
def remove(item)
# ...
end
# ==========================
# Calculate Totals
# ==========================
def total
# ...
end
def total(item)
# ...
end
end
#
, followed by one space, followed by =
up to 80 characters=
should extend to column 80, regardless of starting pointclass Noises
# BAD
# ============
# Angry Noises
# ============
def blah
end
# GOOD
# ===========================================================================
# Angry Noises
# ===========================================================================
def blah
end
module Something
# =========================================================================
# Does not exceed 80 characters
# =========================================================================
def higher_indentation
end
end
end
Open to feedback and suggestions
I just stumbled upon this git repository during my quest to search for better guides and rules for programming Ruby. I've recently switched from Textmate to Sublime Text 2 together with the SublimeLinter addon and I love the constant auto ruby -w
checking it does. However, I also noticed this linter is far more advanced for use with Python, as it uses the PEP-8 code rules to provide feedback about tabs/spaces/double lines, etc etc...
I was wondering, is there something like that being developed for this ruby-style-guide, or would it be possible for something like this? I know it probably takes a lot of time, and in a perfect world I would step up to the task and get this ball rolling, but as it is right now I lack both the experience and the time to do so, so I figured I'd come and ask here.
Regardless of the outcome, thank you for this document, I am sure it is going to help me become a better programmer, with or without an automated tool.
Especially for developers coming from Javascript, I'd suggest stating that the self.
in self.my_method
is usually not needed and should be left off for brevity's sake.
I'll write something up if you'd like me to.
\Z is actually equivalent to:
/\n?\z/
In other words, it matches a line ending at the end of the string. Not necessarily what you want, although probably rarely harmful.
The correct regexp syntax to match the absolute end of the string is \z.
in the guide:
Use CamelCase for classes and modules. (Keep acronyms like HTTP, RFC, XML uppercase.)
The given examples are abbreviations, but not acronyms.
Furthermore, I could use a bit more info, though I use abbreviations like HTTP
myself (instead of Http
) in class names,
But e.g.HttpTcpXmlServer
is better readable then HTTPTCPXMLServer
(don't worry, I just made this one up as an example)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.