Use:: To refer to constants (including classes and modules) and constructors (such as Array () or nokogiri::html ()).
Never use:: To invoke a method.
# bad
someclass::some_method
some_object::some_method
# good
someclass.some_method
some_ Object.some_method
somemodule::someclass::some_const
somemodule::someclass ()
Use parentheses to enclose the parameters of def. Ignores parentheses when the method does not receive any arguments.
# Bad
def some_method ()
# body omitted ' #
good
def some_method
# body omitted
End
# bad
def some_method_with_arguments arg1, arg2
# body omitted
end
# good
def some_ Method_with_arguments (Arg1, arg2)
# body omitted
end
Never use for, unless you know the exact reason for using it. Most of the time iterators can be used for. The for is implemented by a set of each (so you are indirectly adding a level), but there is a path-the for does not contain a new scope (unlike each) and the variables defined in its block are also accessible outside.
arr = [1, 2, 3]
# Bad for
elem in arr does
puts Elem
end
# Note This elem is accessible outside of the F or loop
elem #=> 3
# good
arr.each {|elem| puts elem}
# Elem is not accessible outside each ' s block
elem #=> nameerror:undefined local variable or method ' Elem '
Do not use then in multiple lines of if/unless.
# bad
if Some_condition then
# body omitted ' #
good
if some_condition
# body omitted< C19/>end
If/unless always put the condition on the same line as the if/unless on multiple lines.
# bad
if
some_condition
do_something
do_something_else
End
# good
if some_ Condition
do_something
do_something_else
End
Like ternary operation (?:) over if/then/else/end structure.
It is more general and clearly more concise.
# bad Result
= if some_condition then something else Something_else end
# good result
= some_condition? somet Hing:something_else
Use an expression to use only one expression under each branch of a ternary operation. This means that the ternary operator is not nested. Prefer to use if/else in such a situation.
# Bad
some_condition? (Nested_condition nested_something:nested_something_else): Something_else
# good
if Some_condition
Nested_condition? Nested_something:nested_something_else
Else
something_else
End
Do not use if x: ...-it has been removed in Ruby 1.9. Use ternary operations instead.
# bad Result
= if some_condition then something else Something_else end
# good result
= some_condition? Mething:something_else
Do not use if x; ...。 Use ternary operations instead.
Using the IF and case is the fact that the expression is a result of their return.
# bad
if condition result
= x
else result
= y-end
# good result
=
if condition
x< C10/>else
y
End
When One-line cases, use the When x then .... The alternative syntax when X:XXX has been removed in Ruby 1.9.
Do not use when x; ...。 View the rules above.
Use! Instead of not.
# Poor-Because the operator has a priority, it needs to be in parentheses.
x = (not something)
# good
x =!something
Avoid using!!.
# bad
x = ' Test '
# obscure nil check
if!! x
# Body omitted
end
x = False
# Double negation are useless on booleans
!! X # => False
# good
x = ' test '
unless X.nil?
# Body omitted End
The AND and or keywords are banned. It ' s just not worth
It. Always use && and | | instead.
And and or these two keywords are forbidden to use. It's not a real name. Always use && and | | To replace.
# Bad
# Boolean expression
if Some_condition and some_other_condition
do_something
End
# control Flow
document.saved? or document.save!
# good
# Boolean expression
if some_condition && some_other_condition
do_something
End
# Control Flow
Document.saved? | | document.save!
Avoid multiple lines? : (ternary operator); use if/unless to replace.
A single body prefers to use the if/unless modifier. Another good way is to use &&/| | Control process.
# bad
if some_condition
do_something
End
# good
do_something if Some_condition
# another good Option
some_condition && do_something
Boolean Expressions Use &&/| |, and/or to control the flow. (Rule of thumb: if you have to use extra parentheses (expression logic), then you're using the wrong operator. )
# Boolean expression
if some_condition && some_other_condition
do_something
End
# Control flow
Document.save or document.save!
Avoid multiple lines?:( Ternary operation), using if/unless substitution.
Love to use the if/unless modifier in a single-line statement. Another good option is to get and/or to do process control.
# bad
if some_condition
do_something
End
# good
do_something if Some_condition
# Another good option
some_condition and do_something
Never use unless and else combinations. Rewrite them as a positive condition.
# bad
unless success?
Puts ' failure '
else
puts ' success '
end
# good
if success?
Puts ' success '
else
puts ' failure '
end
Do not use parentheses to contain if/unless/while conditions.
# Bad
if (x > Ten)
# body omitted
end
# good
if x > Ten
# body omitted
end
Do not use while/until condition in multiline while/until.
# bad while
x > 5 does
# body omitted
end
until x > 5 does
# omitted end
# good< C30/>while x > 5
# omitted
until x > 5 # Body
omitted
end
When you have a single body, use the While/until modifier as much as possible.
# bad while
some_condition
do_something
'
# good
do_something while some_condition
The negative condition is judged as much as using until instead of while.
# bad
do_something while!some_condition
# good
do_something until some_condition
The cyclic condition is judged using kernel#loop and break, not begin/end/until or begin/end/while.
# bad
begin
puts val val
= 1 End While
val < 0
# good loops do
puts val
+ = 1 Break
unless Val < 0
End
Ignores parentheses around internal DSL method parameters (such as Rake, Rails, RSpec), methods with a "keyword" state in Ruby (such as: attr_reader,puts), and property access methods. All other method invocations use parentheses around the arguments.
Class Person
Attr_reader:name,: Age
# omitted
end
temperance = person.new (' temperance ',)
Temperance.name
puts temperance.age
x = Math.sin (y)
array.delete (e)
bowling.score.should = 0
Ignores curly braces outside of an implicit option hash.
# bad
user.set ({name: ' John ', age:45, permissions: {read:true}})
# good
user.set (name: ' John ', Age:4 5, permissions: {read:true})
External brackets and curly braces for internal DSL methods.
Class Person < activerecord::base
# bad
validates (: Name, {presence:true, Length: {within:1..10}})
# good
validates:name, presence:true, Length: {within:1..10}
end
Method calls do not require arguments, then parentheses are ignored.
# bad
kernel.exit! ()
2.even? ()
fork ()
' Test ' upcase ()
# good
kernel.exit!
2.even?
Fork
' Test '. upcase
Rather than do...end, you would prefer to use {...} instead of a single block of code. Avoid using {...} in a multiline code block (multiline chains usually get very ugly). Do...end is typically used to do process control and method definitions (for example, in Rakefiles and some DSLs). Avoid using do...end in chained calls.
names = [' Bozhidar ', ' Steve ', ' Sarah ']
# bad
names.each do |name|
Puts name
end
# good
names.each {|name| puts name}
# bad
names.select do |name|
Name.start_with? (' S ')
End.map {|name| name.upcase}
# good
names.select {|name| name.start_with? (' S ')}.map {|name| Name.upcase}
Some argue that multiline chains look like they work with {...}, but they ask themselves--such code really has readability code and why the content in the code block can't be extracted into the beautiful method.
Consider using explicit block argument to avoid writing block
Literal that just passes it arguments to another block. Beware of
The performance impact, though, as the block gets converted to a
Proc.
Consider using explicit block parameters to avoid writing a block literal that simply passes the argument to another block. Be careful of the effects of performance, even if,
The block was converted into Proc.
Require ' tempfile '
# bad
def with_tmp_dir
Dir.mktmpdir do |tmp_dir|
Dir.chdir (tmp_dir) {|dir| yield dir} # block just passes
-arguments
end
# good
def with_tmp_dir (& Block)
Dir.mktmpdir do |tmp_dir|
Dir.chdir (Tmp_dir, &block) End-
with_tmp_dir do
|dir|
Puts "DIR is accessible as parameter and PWD are set: #{dir}" End
Avoid using return in control that does not require flow.
# Bad
def some_method (Some_arr) return
some_arr.size
end
# good
def some_method (Some_arr)
Some_arr.size End
Avoid using self in unwanted places (it only needs to call some self for Write access) (it is only required when calling a self write accessor.)
# bad
def ready?
If Self.last_reviewed_at > Self.last_updated_at
self.worker.update (self.content, self.options)
Self.status =: in_progress
end
self.status =: verified
End
# good
def ready?
If Last_reviewed_at > Last_updated_at
worker.update (content, options)
Self.status =: in_progress
End
status =: Verified
End
As an inevitable result, avoid placing methods (parameters) under the shadow of local variables unless they are equal.
Class Foo
attr_accessor:options
# OK
def initialize (options)
self.options = Options
# both Options and self.options are equivalent here-end
# bad
def do_something (options = {})
unless options[: When] = =: later
output (Self.options[:message]) end
# good
def do_something (params = {})
unless params[:when] = =: later
output (options[:message)
end
End
Do not use an = (Assignment) return value in a conditional expression unless the conditional expression is assigned in parentheses.
This is a fairly popular Ruby dialect, sometimes called safe assignment in condition.
# bad (+ a warning)
if v = array.grep (/foo/)
do_something (v) ...
End
# Good (MRI would still complain, but Rubocop won ' t)
if (v = array.grep (/foo/))
do_something (v)
. ..
End
# good
v = array.grep (/foo/)
if v
do_something (v)
...
End
Use the Quick Self assignment operator wherever you can.
# bad
x = x + y
x = x * y
x = x**y
x = x/y
x = x | | y
x = x && y
# good
x + + y
x *= y
x **= y
x/= y
x | | = y
x &&= y
Use only if the variable is not initialized = to initialize the variable.
# set name to Vozhidar, only if it ' s nil or false
name | | = ' Bozhidar '
Do not use | | = To initialize the Boolean variable. (Think about what happens if the current value is false.) )
# Bad-would set Enabled to true even if it is False
enable | | = True
# good
enabled = True if Enabled.nil?
Use &&= to preprocess variables that do not determine whether a variable exists. Using &&= only in the presence of (variables)
Will change the value and remove the use of if to check its existence.
# bad
if something
something = something.downcase
end
# bad
something = something? nil:something.d Owncase
# OK
something = Something.downcase if something
# good
something = something && Something.downcase
# better
something &&= something.downcase
Avoid the use of congruent (case equality) = = operator. It is known from the name that this is the implicit use of the case expression and the use of the case outside the case statement can produce incomprehensible code.
# bad
Array = = Something
(1..100) = = 7
/something/= = some_string
# good
something.is_a? ( Array)
(1..100). Include? ( 7)
some_string =~/something/
Avoid using Perl's specified variable style (for example, $:,$; Wait a minute. )。 They are rather cryptic and do not encourage the use of them outside of a single line of code.
Use the friendly alias provided by the English library.
# bad
$:.unshift file.dirname (__file__)
# good
require ' 中文版 '
$LOAD _path.unshift file.dirname (__ FILE__)
never use a space between the method name and the open parenthesis (parameter).
# Bad
f (3+2) + 1
# good
f (3 + 2) +1
If the first parameter of the method starts with an open parenthesis, it is usually enclosed in parentheses. For example F ((3 + 2) + 1).
You typically run the Ruby interpreter with the-w option, and Ruby will prompt you when you forget the above rules.
Defines a single line block using the new lambda syntax. Defines the use of lambda methods in multiple-line blocks.
# bad
L = lambda {|a, b| A + b}
L.call (1, 2)
# Correct, but looks extremely awkward
L =-> (A, B) Do
tmp = A * 7
tmp * B/50
end
# good
L =-> (A, b) {a + B}
L.call (1, 2)
L = lambd A do |a, b|
TMP = A * 7
tmp * B/50
End
Use proc rather than proc.new.
#
Bad p = proc.new {|n| puts n}
# good
p = Proc {|n| puts n}
anonymous methods and blocks with Proc.call () instead of proc[] or Proc. ()。
# Bad-looks Similar to enumeration access
L =-> (v) {puts v}
l[1]
# also Bad-uncommon syntax
l =-> (v) {puts v}
L. (1)
# good
L =-> (v) {puts v}
l.call (1)
Unused block parameters and local variables use _. It can also be accepted by _ to use (even if it has less descriptive).
This convention is organized by tools such as Ruby interpreter and RUBOCOP that will suppress their unused parameter warnings.
# bad Result
= hash.map {|k, v| v + 1}
def something (x)
Unused_var, Used_var = Something_else (x)
#. ..
End
# good result
= hash.map {|_k, v| v + 1}
def something (x)
_unused_var, Used_var = Something_else (x)
# ...
End
# good result
= hash.map {|_, v| v + 1}
def something (x)
_, Used_var = Something_else (x)
# ...
End
Use $stdout/$stderr/$stdin instead of Stdout/stderr/stdin. Stdout/stderr/stdin is a constant, although in Ruby it can be assigned to a constant (possibly redirected to a stream), but the interpreter warns if you insist.
Use warn rather than $stderr. puts. In addition to being more clear and concise, if you need to,
Warn also allows you to suppress (suppress) warnings (by-w0 to set the warning level to 0).
The tendency is to use sprintf and its alias format rather than the rather obscure string#% method.
# bad
'%d '% # => ' #
good
sprintf ('%d%d ', M,)
# => ' #
Good
sprintf ('%{first}%{second} ', First:20, Second:10)
# => '
format ('%d%d ', m)
# => ' 20 10 '
# Good
format ('%{first}%{second} ', First:20, Second:10)
# => ' 20 10 '
tends to use array#join instead of rather obscure array#* using strings as arguments.
# bad
%w (one Two three) * ', '
# => ' One, two, three '
# good
%w (one two three). Join (', ')
# => ' One, two, three '
When you're dealing with a variable that you want to treat like an array, but you're not sure it's an array,
Use [*var] or array () instead of an explicit Array check.
# bad
paths = [paths] unless paths.is_a? Array
Paths.each {|path| do_something (path)}
# good
[*paths].each {|path| do_something (path)}
# Good (and a bit more readable)
Array (paths). Each {|path| do_something (path)}
Use range or Comparable#between as far as possible? To replace a complex logical comparison.
# bad
do_something if x >= 1000 && x <=
# good
do_something if (1000..2000). Include? ( x)
# good
do_something if X.between? ( 1000, 2000)
Try to use the predicate method rather than the = =. Except for comparison numbers.
# bad
if x 2 = 0 End
if x 2 = 1 End
if x = = Nil end
# good
if X.even?
End
if x.odd?
End
if X.nil?
End
if X.zero?
End
If x = = 0 End
Avoid using BEGIN blocks.
Use Kernel#at_exit. Never use end blocks.
# bad end
{puts ' goodbye! '}
# good
at_exit {puts ' goodbye! '}
Avoid using flip-flops.
Avoid using nested conditions to control the process.
When you may assert an illegal data, use a defensive statement. A defensive statement is a conditional declaration at the top of a function so that if the data is not legitimate, it can jump out of the function as quickly as possible.
# Bad
def compute_thing (thing)
if Thing[:foo]
update_with_bar (thing)
if Thing[:foo][:bar]
Partial_compute (thing)
else
re_compute (thing) end end
# good
def compute_ Thing (thing) return
unless Thing[:foo]
Update_with_bar (thing[:foo)) return
Re_compute (thing) unless Thing[:foo][:bar]
partial_compute (thing)
end