ruby-style-guide
ruby-style-guide copied to clipboard
Style for Arrays of Hashes and similar constructs
I came to check the guide for suggestions but didn't see anything for this.
# clear but can we make it more compact?
people = [
{
:name => "John Smith",
:address => "123 Street St, City, Region, Country"
},
{
:name => "Jane Smith",
:address => "321 Avenue Ave, City, Region, Country"
}
]
# compact but less readable if we start wrapping, likely if we add additional keys
people = [
{ :name => "John Smith", :address => "123 Street St, City, Region, Country" },
{ :name => "Jane Smith", :address => "321 Avenue Ave, City, Region, Country" }
]
# fairly clear but the braces don't line up and we only saved 2 rows
people = [{
:name => "John Smith",
:address => "123 Street St, City, Region, Country"
},
{
:name => "Jane Smith",
:address => "321 Avenue Ave, City, Region, Country"
}]
I'm not totally happy with any of these. Any other suggestions?
Thanks for all the hard work on this guide, BTW!
-Michael
I usually do 2 for small hashes and 3 for the bigger ones, except I put the closing and opening brackets between the hashes in the same line:
people = [{
:name => "John Smith",
:address => "123 Street St, City, Region, Country"
}, {
:name => "Jane Smith",
:address => "321 Avenue Ave, City, Region, Country"
}]
I tend to follow @michaelmarziani's example, except I line up my values. I don't worry about the number of lines so much (thank you, text folding in competent editors), but I have been known to pull sizeable declarations out into separate files/objects. (SRP FTW!)
My current convention would look like
people = [{
:name => "John Smith",
:address => "123 Street St, City, Region, Country"
},
{
:name => "Jane Smith",
:address => "321 Avenue Ave, City, Region, Country"
}]
or, for code that's been touched post-Ruby 1.9,
people = [{
name: "John Smith",
address: "123 Street St, City, Region, Country"
},
{
name: "Jane Smith",
address: "321 Avenue Ave, City, Region, Country"
}]
@fuadsaud: I like the close and open brackets on one line; it remains readable and saves an extra line per array element. Thanks for that suggestion!
@fuadsaud's answer also raises a related question: Is it better to always follow the same style convention or is it ok to use "style 2" for smaller hashes, and a variant of "style 3" for larger ones? Stated another way, should we aim for consistency whenever we create a structure like this, or should we aim for readability, allowing > 1 style convention so long as the declaration is clear?
@jdickey I think lining up the values makes for even better readability. Thanks! The only thing unclear in your examples is unequal indentation of the opening and closing of the array:
# unclear that these go together when scanning down code
people = [{
}]
# vs what I believe is considered best practice
people = [{
}]
@michaelmarziani I tend to prefer the indented closing brace/bracket to make the next line (which isn't indented) stand out more, as if to say "I'm not part of what came before me!"
I used to prefer the second example you give. Then I did some heavy cut-and-paste rearrangement of some legacy code and found that the indentation makes for easier reading when you're whipping the selection cursor down the page.
I prefer a third option:
# clear that these go together, and stands out from what comes after
people = [{
...
}]
@eclubb I tend to dislike that, on the grounds that it penalises descriptive, intention-revealing variable names. If the array's name is more than a half-dozen or so characters long and if the key/value pairs in the hash are longer than 70 or so characters, the lines will wrap if you have a wrap margin enabled at 80 (as other style-guide recommendations would suggest).
By having the keys indented one or at most two two-position levels from the surrounding code, that leaves more room before the right margin.
You can also break the line after the =
people =
[{
...
}]
Not that I like it much, but it's possible.
Points for effort, @fuadsaud, but I don't like it much, either. :-1:
@jdickey I see your point. Have you run into those situations often? I have some, but in my experience they're pretty rare. I usually hit them when the value is built from calling methods with longish names on objects with longish names (as opposed to using local variables for the value.
longish_hash_name = {
longish_key_name: here_is_an_object.with_a_longish_method_name
}
In which case, i might do something like:
local_variable = here_is_an_object.with_a_longish_method_name
longish_hash_name = {
longish_key_name: local_variable
}
I could, however, see it being more of a problem in deeply nested code. When extracting a local variable won't help, I will usually fall back to one level of indentation:
longish_hash_name = {
longish_key_name: here_is_an_object.with_a_longish_method_name
}
another option is to parse raw text, it is limited but looks well for given data https://gist.github.com/sowcow/9679560
@eclubb I have run into that sort of situation often enough that it's troublesome. Often, but not always, it's an indicator of some overly-complex code. Say, you've got a couple of if
or case
statements that move the margin in three or four indentation levels from the beginning of a method within a module, so you've chewed up a dozen or so spaces before you've even started — and your shop standards call for 80-column soft-wrapped lines. So your
longish_hash_name = {
longish_key_name: here_is_an_object.with_a_longish_method_name
}
example would just fit (64 positions for the key/value pair indented two spaces from the hash name, plus call it a dozen spaces indentation for module/class/method/whatever). And then you decide to be "neat" and have all the values vertically aligned and boom here comes ugly auto-wrapping. Breaking that nesting up into nice, neat modules/methods while keeping the organisation of the code tight enough that people don't get lost is an art that too few have mastered.
And yes, one level of indentation is a Good Thing. (If you look at the examples in my first comment, the keys appear to be indented two levels from the start of the assignment to people
:
people = [{
name: "John Smith",
address: "123 Street St, City, Region, Country"
},
{
name: "Jane Smith",
address: "321 Avenue Ave, City, Region, Country"
}]
Note, however, that the array items, being hashes, have their opening and closing braces indented one level from person
, with the keys one level beyond that. A detail that I'm usually willing to yield to a sufficiently truculent colleague.