= RubyCodingConvention
(DRAFT VERSION: 2001/11/01)
== File Names
=== Directory and File names and Suffixes
:Ruby source code
file/directory name is lower case class/module name with
suffix '.rb'.
ex.
Foo class => foo.rb
Bar module => bar.rb
FooBar class => foobar.rb (Normal Rule)
foo_bar.rb (Rails Rule)
Foo::Bar class => foo/bar.rb
:Libraries((-any arguments?-))
non-standard multiple files required by a script should be in
one directory, and they should be installed to the standard
site-ruby directory or a script's library directory.
don't use a current directory for libraries --- it is dangerous.
since the directory in which script exists can not be specified
portably, it is also not suited for libraries.
== File Organization
* require (if necessary)
* include (if necessary)
* classes and modules definition
* main
* testing code(?) using __FILE__ idiom
ex:
if __FILE__ == $0
<testcode>
end
=== Beginning Comment
==== begin - end style
for file header or footer.
=begin
* Name:
* Description
* Author:
* Date:
* License:
=end
==== using '#' style
for class/module and method definitions
# using foo bar
#
# foo bar buz.
#
class Foo
# bar.bar.bar.
#
class Bar
# constructor of Bar.
#
def initialize(bar = nil)
super(bar)
end
def bar
self
end
end
def initialize()
end
end
== Indentation
=== Line length
Max length is about 80 characters.
=== Wrapping Line
* Break after comma
* Break after operator
== Comments
Ruby has two comments style: =begin...=end and '#'.
You should use =begin...=end for Documentation Comments,
and '#' for both Documentation Comments and Implementation
Comments.
=== Implementation Comments
==== Block Comments
# Here is block comment.
#
# foo, bar, buz.
==== Single-Line Comments
# this is single line comment.
## this is also single line comment.
==== Tailing Comments
if a == 2
true # special case
else
prime?(a) # work only for odd a
end
=== Documentation Comments
==== Header/Footer
=begin
= FooBar library
== What's New?
.....
....
== Installation
.....
....
....
=end
==== In Class/Module
# .....
# ....
#
def foo()
..
or
##
# .....
# ....
#
def foo()
..
=== Way of no commenting
If you can write simple, short and light scripts, comments may not be necessary.
You can let ((*the script itself tell everything*)), instead of embedding documentation that may confuse readers of your script.
== Definitions
=== Initialization
Ruby variables have no 'definitions'. So, you should initialize
variables.
=== One initialization per line
level = 0
size = 0
is preferred over
level = size = 0
=== Placement
== Statements
=== Simple Statements
Each line should contain at most one statement.
foo = 1 ## Correct
bar = 2 ## Correct
foo = 1; bar = 2 ## AVOID!
=== Compound Statements
=== if-end, if-else-end, if-elsif-else-end Statements
simple example:
if <condition>
<statements>
end
more complex example:
if <condition>
<statements>
elsif <condition>
<statements>
else
<statements>
end
You can put on <condition> after <statements>
when <statements> is one-line.
<statements> if <condition>
=== block methods
`{...}' style:
bar.foo(vars){|vars2|
<statements>
}
`do...end' style:
bar.foo(vars) do |vars2|
<statements>
end
one-line block:
bar.foo(){|var| <statements> }
=== case-when Statements
Ruby's case-when (not when-case) does not need 'break'.
case foo
when condition1
<statements>
when condition2
<statements>
else
<statements>
end
=== begin-rescue-end Statements
It handles errors (Exceptions).
begin
<statements>
rescue FooError => e
<statements>
rescue BazError => e2
<statements>
rescue
<statements>
end
== White Space
=== Blank Lines
* Between sections of a source file
* Between class and module definitions
* Between methods
* Before blocks or single-line comments
* Between logical sections inside a method to improve readability
=== Blank spaces
A keyword followed by a parenthesis should be separated
by a space.
ex:
while (foo.end?) {
<statements>
}
The number of spaces should be balanced.
a+b ## Correct
a + b ## Correct
a+ b ## AVOID!
a +b ## AVOID! (Erroneous: interpreted as a(+b))
a += b + c
a = (a + b) / (c * d)
a = b
foo("foo" + buz + bar)
== Naming Conventions
=== Classes/Modules
class and module names should be nouns; in mixed case with
the first letter of each internal word capitalized.
ex: class Raster, class Raster::ImageSprite
=== Methods
Methods should be verbs. All lower case ASCII letters with
words separated by underscores ('_')
ex. run(), run_fast(), obj.background_color()
=== Variables
variable names should be all lower case ASCII letters with
words separated by underscore ('_')
ex:
i = 1
some_char = SomeChar.new()
table_width = 0.0
=== Constants
constants should be all upper case with words separated by
underscores ('_').
((-Huh, is there a reasonable background to distinguish constants from a class name which is a constant at the same time?-))
ex:
MIN_LENGTH = 1
DEFAULT_HOST = "foo.example.com"
=== Omission
Speaking of 'Connection Pool' as a variable, you should decide to prefer name by scope such as the following...
* 'conpool' for local scope (such as local variable)
* '@connection_pool' for class scope (such as instance variable)
== Pragmatic Programming Practices
=== Using attr_* to access
def foo()
@foo
end
attr_reader :foo
=== Without Parenthesis
Some methods are used without parenthesis.
* require
ex. require 'foo/bar'
* include
ex. include FooModule
* p
ex. p foo
* attr_*
ex. attr_reader :foo, :bar
=== Reduce repetition
When successive lines of a script share something,
x = ModuleA::ClassB::method_c( a )
y = ModuleA::ClassB::method_d( b )
(-- 'function' => 'method' --)
you should make it like this:
cb = ModuleA::ClassB
x = cb::method_c( a )
y = cb::method_d( b )
You can also do:
include ModuleA
x = ClassB::method_c(a)
y = ClassB::method_d(b)
== Code Example
=== Ruby Source File Example
=begin
blahdy/blah.rb
$Id:$
Copyright (c) 2001 TAKAHASHI Masayoshi
This is free software; you can copy and distribute and modify
this program under the term of Ruby's License
(http://www.ruby-lang.org/LINCENSE.txt)
=end
#
# module description goes here.
#
# @version: 1.82
# @author: TAKAHASHI Masayoshi
#
module Blahdy
class Blah < SomeClass
# A class implementation comment goes here.
# CLASS_VAR1 documentation comment
CLASS_VAR1 = 1;
# CLASS_VAR2 documentation comment that happens
# to be more than one line length.
#
CLASS_VAR2 = 1;
# ...constructor Blah documentation comment...
#
def initialize()
## ...implementation goes here...
end
# ...method do_something documentation comment...
#
def do_sometiong()
## ...implementation goes here...
end
# ...method do_something_else documentation comment...
#
# @param some_param description
#
def do_something_else(some_param)
## ...implementation goes here...
end
end
end
(DRAFT VERSION: 2001/11/01)
== File Names
=== Directory and File names and Suffixes
:Ruby source code
file/directory name is lower case class/module name with
suffix '.rb'.
ex.
Foo class => foo.rb
Bar module => bar.rb
FooBar class => foobar.rb (Normal Rule)
foo_bar.rb (Rails Rule)
Foo::Bar class => foo/bar.rb
:Libraries((-any arguments?-))
non-standard multiple files required by a script should be in
one directory, and they should be installed to the standard
site-ruby directory or a script's library directory.
don't use a current directory for libraries --- it is dangerous.
since the directory in which script exists can not be specified
portably, it is also not suited for libraries.
== File Organization
* require (if necessary)
* include (if necessary)
* classes and modules definition
* main
* testing code(?) using __FILE__ idiom
ex:
if __FILE__ == $0
<testcode>
end
=== Beginning Comment
==== begin - end style
for file header or footer.
=begin
* Name:
* Description
* Author:
* Date:
* License:
=end
==== using '#' style
for class/module and method definitions
# using foo bar
#
# foo bar buz.
#
class Foo
# bar.bar.bar.
#
class Bar
# constructor of Bar.
#
def initialize(bar = nil)
super(bar)
end
def bar
self
end
end
def initialize()
end
end
== Indentation
=== Line length
Max length is about 80 characters.
=== Wrapping Line
* Break after comma
* Break after operator
== Comments
Ruby has two comments style: =begin...=end and '#'.
You should use =begin...=end for Documentation Comments,
and '#' for both Documentation Comments and Implementation
Comments.
=== Implementation Comments
==== Block Comments
# Here is block comment.
#
# foo, bar, buz.
==== Single-Line Comments
# this is single line comment.
## this is also single line comment.
==== Tailing Comments
if a == 2
true # special case
else
prime?(a) # work only for odd a
end
=== Documentation Comments
==== Header/Footer
=begin
= FooBar library
== What's New?
.....
....
== Installation
.....
....
....
=end
==== In Class/Module
# .....
# ....
#
def foo()
..
or
##
# .....
# ....
#
def foo()
..
=== Way of no commenting
If you can write simple, short and light scripts, comments may not be necessary.
You can let ((*the script itself tell everything*)), instead of embedding documentation that may confuse readers of your script.
== Definitions
=== Initialization
Ruby variables have no 'definitions'. So, you should initialize
variables.
=== One initialization per line
level = 0
size = 0
is preferred over
level = size = 0
=== Placement
== Statements
=== Simple Statements
Each line should contain at most one statement.
foo = 1 ## Correct
bar = 2 ## Correct
foo = 1; bar = 2 ## AVOID!
=== Compound Statements
=== if-end, if-else-end, if-elsif-else-end Statements
simple example:
if <condition>
<statements>
end
more complex example:
if <condition>
<statements>
elsif <condition>
<statements>
else
<statements>
end
You can put on <condition> after <statements>
when <statements> is one-line.
<statements> if <condition>
=== block methods
`{...}' style:
bar.foo(vars){|vars2|
<statements>
}
`do...end' style:
bar.foo(vars) do |vars2|
<statements>
end
one-line block:
bar.foo(){|var| <statements> }
=== case-when Statements
Ruby's case-when (not when-case) does not need 'break'.
case foo
when condition1
<statements>
when condition2
<statements>
else
<statements>
end
=== begin-rescue-end Statements
It handles errors (Exceptions).
begin
<statements>
rescue FooError => e
<statements>
rescue BazError => e2
<statements>
rescue
<statements>
end
== White Space
=== Blank Lines
* Between sections of a source file
* Between class and module definitions
* Between methods
* Before blocks or single-line comments
* Between logical sections inside a method to improve readability
=== Blank spaces
A keyword followed by a parenthesis should be separated
by a space.
ex:
while (foo.end?) {
<statements>
}
The number of spaces should be balanced.
a+b ## Correct
a + b ## Correct
a+ b ## AVOID!
a +b ## AVOID! (Erroneous: interpreted as a(+b))
a += b + c
a = (a + b) / (c * d)
a = b
foo("foo" + buz + bar)
== Naming Conventions
=== Classes/Modules
class and module names should be nouns; in mixed case with
the first letter of each internal word capitalized.
ex: class Raster, class Raster::ImageSprite
=== Methods
Methods should be verbs. All lower case ASCII letters with
words separated by underscores ('_')
ex. run(), run_fast(), obj.background_color()
=== Variables
variable names should be all lower case ASCII letters with
words separated by underscore ('_')
ex:
i = 1
some_char = SomeChar.new()
table_width = 0.0
=== Constants
constants should be all upper case with words separated by
underscores ('_').
((-Huh, is there a reasonable background to distinguish constants from a class name which is a constant at the same time?-))
ex:
MIN_LENGTH = 1
DEFAULT_HOST = "foo.example.com"
=== Omission
Speaking of 'Connection Pool' as a variable, you should decide to prefer name by scope such as the following...
* 'conpool' for local scope (such as local variable)
* '@connection_pool' for class scope (such as instance variable)
== Pragmatic Programming Practices
=== Using attr_* to access
def foo()
@foo
end
attr_reader :foo
=== Without Parenthesis
Some methods are used without parenthesis.
* require
ex. require 'foo/bar'
* include
ex. include FooModule
* p
ex. p foo
* attr_*
ex. attr_reader :foo, :bar
=== Reduce repetition
When successive lines of a script share something,
x = ModuleA::ClassB::method_c( a )
y = ModuleA::ClassB::method_d( b )
(-- 'function' => 'method' --)
you should make it like this:
cb = ModuleA::ClassB
x = cb::method_c( a )
y = cb::method_d( b )
You can also do:
include ModuleA
x = ClassB::method_c(a)
y = ClassB::method_d(b)
== Code Example
=== Ruby Source File Example
=begin
blahdy/blah.rb
$Id:$
Copyright (c) 2001 TAKAHASHI Masayoshi
This is free software; you can copy and distribute and modify
this program under the term of Ruby's License
(http://www.ruby-lang.org/LINCENSE.txt)
=end
#
# module description goes here.
#
# @version: 1.82
# @author: TAKAHASHI Masayoshi
#
module Blahdy
class Blah < SomeClass
# A class implementation comment goes here.
# CLASS_VAR1 documentation comment
CLASS_VAR1 = 1;
# CLASS_VAR2 documentation comment that happens
# to be more than one line length.
#
CLASS_VAR2 = 1;
# ...constructor Blah documentation comment...
#
def initialize()
## ...implementation goes here...
end
# ...method do_something documentation comment...
#
def do_sometiong()
## ...implementation goes here...
end
# ...method do_something_else documentation comment...
#
# @param some_param description
#
def do_something_else(some_param)
## ...implementation goes here...
end
end
end