The Totally Unofficial Ruby coding style guide
github.com
github.com
Not too sure about that... I prefer collect/detect/select/reject...
> Keep existing comments up-to-date - no comment is better than an outdated comment.
Ambiguous sentence warning!
kind = case year
when 1850..1889 then "Blues"
...
I also have a question that I have always wanted to ask. I am not a native speaker of English. Are "if not" and "unless" really the same thing?Does this:
def foo(x, y, z)
destroy_universe unless all_arguments_valid?
# more code...
and this: def foo(x, y, z)
destroy_universe if not all_arguments_valid?
# more code...
really have the same implications? "unless" makes it sound a tiny bit as if "all_arguments_valid?" was the exception - to me at least. Does anyone else use "if not" based on this gut feeling sometimes?>The length of an identifier determines its scope. Use one-letter variables for short block/method parameters, according to this scheme:
a,b,c: any object
d: directory names
e: elements of an Enumerable
ex: rescued exceptions
f: files and file names
i,j: indexes
k: the key part of a hash entry
m: methods
o: any object
r: return values of short methods
s: strings
v: any value
v: the value part of a hash entry
x,y,z: numbersMany others have forked this guide and made modifications according to their tastes.
I've moved instead to simply using reasonably descriptive variable names where the type is easily inferred. The extra type information isn't missed.
sZipCode = "90210"
really isn't necessary. Instead: zipCode = "90210"
works just fine. And leaving out the type information for a variable with no repercussions is 95% of use cases for variables.I don't recommend one letter variables. I don't know if I've ever seen an official style guide that has.
Not that familiar with idiomatic Ruby, but using one letter variables as iterators in for loops (and some other things) is pretty idiomatic C:
int i;
for (i = 0; i < queue_size; i++)
queue[i] = get_rarest_peer(t->peer_list); [1, 2, 3].each { |e| puts e }
Object.methods.each { |m| "Method is: #{m}" } [1, 2, 3].each { |value| puts value }
Object.methods.each { |method| "Method is: #{method}" }
I consider that a better habit to have than using single-character variables. And style guides should be about encouraging the best habits possible.If you're not used to Ruby, here's an example of what he's referring to:
To work with the keys and values of a hash (dictionary / associative array) I use the .each method on the hash itself. The .each method gives me access to the key and value of each entry in the hash.
hash = {"name => "Homer", "age" => 42}
hash.each{|k, v| puts k + " " + v}
Where 'k' is key, and 'v' is value.I never really gave much thought to "standardizing" this.
hash.each { |key,value| puts "#{key} #{value}" }Interesting how "more readable" is somewhat objective, isn't it?
puts k + " " + v
Does that execute as puts(k) + " " + v, puts(k + " ") + v or any other combination? While those of us familiar with Ruby know the answer, I would still argue that it takes greater cognitive resources to evaluate over the single string, especially in the presence of a syntax highlighting editor who clearly defines the string boundaries in colour.You are right that it is definitely subjective. Coding is user interface design, but we don't usually have the luxury of processes like A/B testing to validate our work like other interface designers do. It would be interesting to put both of our code samples along with some other variations in front of an audience and see how they are received.
When I've tried to jump right into string interpolation, people don't quite get what's going on, which resulted in me having to backtrack and do addition anyway.
But that's just my experience.
def method_name(arg1, arg2)
instead of def method_name arg1, arg2
especially when they do not like empty parentheses for no args def method_name()
and they just love to omit the parentheses when actually using a method puts "odd"
Why the inconsistency? Unnecessary parentheses are unnecessary! When in doubt .. let the args out!edit:
> Avoid hashes-as-optional-parameters. Does the method do too much?
And I'm totally against this. This is an extremely useful pattern and can be key to increasing readability. I basically insist on opts hashes on any method with more than 2 args. Wow, you can see what is intended rather than Model.do_something(3, false, false).
Any big application has methods that take a lot of switches. The opts hash pattern lets you at least label them, rather than rely on obscure argument order. And it lets you set defaults on the args in a sane way (rails' famous reverse_merge!). Why would anyone be against that?
So it's cleaner from the side of invoking the method, but relies on the developer of the method to heavily document what the hash's options are. That's the only thing I've noticed.