### Ruby Inline Annotation Usage Source: https://rubystyle.guide/index Provides an example of using inline annotations in Ruby for obvious issues where documentation is redundant. This should be used sparingly. ```Ruby def bar sleep 100 # OPTIMIZE end ``` -------------------------------- ### Date and Time Handling in Ruby Source: https://rubystyle.guide/index Provides guidance on using Ruby's `Time` and `Date` classes. It recommends `Time.now` over `Time.new` for current time and advises against `DateTime` unless historical calendar reforms are needed, in which case the `start` argument should be specified. ```ruby # bad - uses DateTime for current time DateTime.now # good - uses Time for current time Time.now # bad - uses DateTime for modern date DateTime.iso8601('2016-06-29') # good - uses Date for modern date Date.iso8601('2016-06-29') # good - uses DateTime with start argument for historical date DateTime.iso8601('1751-04-23', Date::ENGLAND) ``` -------------------------------- ### Rationale Comments in Ruby Code Source: https://rubystyle.guide/index Provides examples of effective rationale comments in Ruby code. These comments explain the 'why' behind certain code implementations, especially when the logic is complex or relies on external factors. ```ruby # bad x = BuggyClass.something.dup def compute_dependency_graph ...30 lines of recursive graph merging... end # good # BuggyClass returns an internal object, so we have to dup it to modify it. x = BuggyClass.something.dup # This is algorithm 6.4(a) from Worf & Yar's _Amazing Graph Algorithms_ (2243). def compute_dependency_graph ...30 lines of recursive graph merging... end ``` -------------------------------- ### Ruby Regex Start and End Anchors Source: https://rubystyle.guide/index Explains the difference between `^`, `$`, `A`, and `z` anchors in Ruby regular expressions. `^` and `$` match the start/end of a line, respectively, while `A` and `z` match the start and end of the entire string. ```ruby string = "some injection\nusername" string[/^username$/] # matches string[/Ausernamez/] # doesn't match ``` -------------------------------- ### Prefer proc.call() over proc[] or proc.() in Ruby Source: https://rubystyle.guide/index Demonstrates the preferred way to call procs and lambdas in Ruby using `.call()`. It shows examples of less desirable syntax like `[]` and `.`. ```ruby # bad - looks similar to Enumeration access l = ->(v) { puts v } l[1] # bad - most compact form, but might be confusing for newcomers to Ruby l = ->(v) { puts v } l.(1) # good - a bit verbose, but crystal clear l = ->(v) { puts v } l.call(1) ``` -------------------------------- ### Ruby Method Definition with Default Arguments Source: https://rubystyle.guide/index Demonstrates a Ruby method definition with default values for arguments, a common practice for flexibility. ```ruby def some_method(arg1 = :default, arg2 = nil, arg3 = []) # do something... end ``` -------------------------------- ### Ruby Access Modifiers Indentation Source: https://rubystyle.guide/index Provides an example of correct indentation for `public`, `protected`, and `private` access modifiers in Ruby classes, ensuring clarity and readability. ```ruby class SomeClass def public_method # some code end private def private_method # some code end def another_private_method # some code end end ``` -------------------------------- ### Lazy Evaluation Example Source: https://rubystyle.guide/index Demonstrates the benefit of lazy evaluation in Ruby, where blocks are only executed when their results are needed, such as in exception handling. ```ruby batman.fetch(:powers) { obtain_batman_powers } ``` -------------------------------- ### Avoiding Suppressed Exceptions in Ruby Source: https://rubystyle.guide/index Advises against suppressing exceptions without proper handling or documentation in Ruby. It shows examples of safely handling or explicitly acknowledging ignored exceptions. ```ruby # bad begin do_something # an exception occurs here rescue SomeError end # good begin do_something # an exception occurs here rescue SomeError handle_exception end # good begin do_something # an exception occurs here rescue SomeError # Notes on why exception handling is not performed end # good do_something rescue nil ``` -------------------------------- ### Ruby Metaprogramming with `define_method` Source: https://rubystyle.guide/index Highlights `define_method` as a preferred alternative to `class_eval { def ... }` for metaprogramming in Ruby, promoting cleaner code. ```ruby # from activesupport/lib/active_support/core_ext/string/output_safety.rb UNSAFE_STRING_METHODS.each do |unsafe_method| if 'String'.respond_to?(unsafe_method) class_eval(<<-EOT, __FILE__, __LINE__ + 1) def #{unsafe_method}(*params, &block) # def capitalize(*params, &block) to_str.#{unsafe_method}(*params, &block) # to_str.capitalize(*params, &block) end # end def #{unsafe_method}!(*params) # def capitalize!(*params) @dirty = true # @dirty = true super # super end # end EOT end end ``` -------------------------------- ### Ruby: Using super with Arguments Source: https://rubystyle.guide/index Illustrates the correct way to call the `super` method when passing arguments in Ruby. It emphasizes the necessity of using parentheses for clarity and correctness. ```ruby # bad super name, age # good super(name, age) ``` -------------------------------- ### Ruby: Merging Keyword Arguments Source: https://rubystyle.guide/index Demonstrates the preferred way to pass additional keyword arguments when an existing hash is already being used. Direct addition is favored over using `merge`. ```ruby # bad some_method(**opts.merge(foo: true)) # good some_method(**opts, foo: true) ``` -------------------------------- ### Ruby Annotation Keyword Formatting Source: https://rubystyle.guide/index Illustrates the proper formatting for annotation keywords in Ruby, requiring a colon and a space after the keyword followed by the descriptive note. ```Ruby # bad def bar # FIXME This has crashed occasionally since v3.2.1. baz(:quux) end # good def bar # FIXME: This has crashed occasionally since v3.2.1. baz(:quux) end ``` -------------------------------- ### Ruby Annotation Placement Source: https://rubystyle.guide/index Demonstrates the correct placement of annotations in Ruby code, emphasizing placing them on the line immediately above the relevant code for clarity. ```Ruby # bad def bar baz(:quux) # FIXME: This has crashed occasionally since v3.2.1. end # good def bar # FIXME: This has crashed occasionally since v3.2.1. baz(:quux) end ``` -------------------------------- ### Reverse Iteration: reverse_each vs. reverse.each Source: https://rubystyle.guide/index Suggests using `reverse_each` over `reverse.each` as it may leverage more efficient implementations provided by specific classes. ```ruby # bad array.reverse.each { ... } # good array.reverse_each { ... } ``` -------------------------------- ### Ruby Method Arguments Alignment: Good Practice Source: https://rubystyle.guide/index Shows how to align method arguments across multiple lines for improved readability, using standard indentation. ```ruby def send_mail(source) Mailer.deliver( to: 'bob@example.com', from: 'us@example.com', subject: 'Important message', body: source.text ) end ``` -------------------------------- ### Ruby `Struct.new` for Trivial Accessors Source: https://rubystyle.guide/index Illustrates using `Struct.new` as a more concise way to define trivial accessors, constructors, and comparison operators compared to manual `attr_accessor` and `initialize`. ```ruby Person = Struct.new(:first_name, :last_name) do end ``` -------------------------------- ### Prefer `sprintf` or `format` over `String#%` in Ruby Source: https://rubystyle.guide/index This Ruby snippet promotes the use of `sprintf` and `format` over the `String#%` operator for string formatting. It provides examples of both 'bad' (using `%`) and 'good' (using `sprintf` and `format`) practices, including named format tokens. ```ruby # bad '%d %d' % [20, 10] # => '20 10' # good sprintf('%d %d', 20, 10) # => '20 10' # good sprintf('%d %d', first: 20, second: 10) # => '20 10' format('%d %d', 20, 10) # => '20 10' # good format('%d %d', first: 20, second: 10) # => '20 10' ``` -------------------------------- ### Use `require_relative` for Internal Dependencies (Ruby) Source: https://rubystyle.guide/index Employs `require_relative` for internal library dependencies, improving clarity and efficiency compared to `require`. ```ruby # bad require 'set' require 'my_gem/spec/helper' require 'my_gem/lib/something' # good require 'set' require_relative 'helper' require_relative '../lib/something' ``` -------------------------------- ### Ruby: Returning Result from `if`/`case` Expressions Source: https://rubystyle.guide/index Highlights that `if` and `case` are expressions in Ruby and can be used to directly return a result, simplifying assignment. ```Ruby # bad if condition result = x else result = y end # good result = if condition x else y end ``` -------------------------------- ### Ruby `Data.define` vs. Class Extension Source: https://rubystyle.guide/index Demonstrates the preferred usage of `Data.define` for creating data classes without extending its instances, which can lead to superfluous class levels and errors. ```ruby Person = Data.define(:first_name, :last_name) ``` -------------------------------- ### Ruby: Avoiding `else` with `unless` Source: https://rubystyle.guide/index Demonstrates the Ruby style guide recommendation to avoid using `else` with `unless`. It suggests rewriting such structures to use `if` with the positive condition first for better clarity. ```ruby # bad unless success? puts 'failure' else puts 'success' end ``` ```ruby # good if success? puts 'success' else puts 'failure' end ``` -------------------------------- ### Omit `.rb` Extension for `require` and `require_relative` (Ruby) Source: https://rubystyle.guide/index Demonstrates omitting the `.rb` extension when requiring files, which is the standard and more efficient practice. ```ruby # bad require 'foo.rb' require_relative '../foo.rb' # good require 'foo' require 'foo.so' require_relative '../foo' require_relative '../foo.so' ``` -------------------------------- ### Ruby Naming Convention: Snake Case Source: https://rubystyle.guide/index Illustrates the use of `snake_case` for Ruby symbols, methods, and variables, which is the standard convention. ```ruby :some_symbol some_var = 5 def some_method # some code end ``` -------------------------------- ### Identity Comparison: Prefer `equal?` over `==` for `object_id` Source: https://rubystyle.guide/index Explains the difference between `Object#equal?` and `Object#==` in Ruby. `equal?` checks for object identity, while `==` checks for value equality. The guide recommends `equal?` when comparing `object_id`. ```ruby # bad foo.object_id == bar.object_id # good foo.equal?(bar) ``` -------------------------------- ### Ruby: Ternary Operator vs. `if/then/else/end` Source: https://rubystyle.guide/index Recommends using the ternary operator (`?:`) over `if/then/else/end` constructs for conciseness and commonality in Ruby. ```Ruby # bad result = if some_condition then something else something_else end # good result = some_condition ? something : something_else ``` -------------------------------- ### Ruby: Arguments Forwarding Source: https://rubystyle.guide/index Shows the modern approach to forwarding arguments in Ruby using the `...` syntax introduced in version 2.7. This is a more concise alternative to explicitly passing arguments. ```ruby # bad def some_method(*args, &block) other_method(*args, &block) end # bad def some_method(*args, **kwargs, &block) other_method(*args, **kwargs, &block) end # bad # Please note that it can cause unexpected incompatible behavior # because `...` forwards block also. # https://github.com/rubocop/rubocop/issues/7549 def some_method(*args) other_method(*args) end # good def some_method(...) other_method(...) end ``` -------------------------------- ### Ruby: `and`/`or` for Control Flow Source: https://rubystyle.guide/index Explains the use of `and` and `or` as control flow operators in Ruby for sequencing operations, while warning against their use in boolean contexts due to low precedence. ```Ruby # good: and/or for control flow x = extract_arguments or raise ArgumentError, "Not enough arguments!" user.suspended? and return :denied # bad # and/or in conditions (their precedence is low, might produce unexpected result) if got_needed_arguments and arguments_valid # ...body omitted end # in logical expression calculation ok = got_needed_arguments and arguments_valid # good # &&/|| in conditions if got_needed_arguments && arguments_valid # ...body omitted end # in logical expression calculation ok = got_needed_arguments && arguments_valid # bad # &&/|| for control flow (can lead to very surprising results) x = extract_arguments || raise(ArgumentError, "Not enough arguments!") # bad # Avoid several control flow operators in one expression, as that quickly becomes confusing: ``` -------------------------------- ### Ruby: `then` in Multi-line Expressions Source: https://rubystyle.guide/index Demonstrates the incorrect use of `then` for multi-line `if`, `unless`, `when`, and `in` statements, contrasting it with the preferred multi-line syntax. ```Ruby # bad if some_condition then # body omitted end # bad case foo when bar then # body omitted end # bad case expression in pattern then # body omitted end # good if some_condition # body omitted end # good case foo when bar # body omitted end # good case expression in pattern # body omitted end ``` -------------------------------- ### Mixin Grouping in Ruby Source: https://rubystyle.guide/index Demonstrates the preferred way to include multiple mixins in a Ruby class. It suggests splitting each mixin into a separate `include` statement for clarity. ```ruby # good class Person # multiple mixins go in separate statements include Foo include Bar end ``` -------------------------------- ### Use Ranges or Comparable#between? for Comparisons (Ruby) Source: https://rubystyle.guide/index Replaces complex comparison logic with more readable range inclusions or the `between?` method. ```ruby # bad do_something if x >= 1000 && x <= 2000 # good do_something if (1000..2000).include?(x) # good do_something if x.between?(1000, 2000) ``` -------------------------------- ### Ruby `Struct.new` vs. Class Extension Source: https://rubystyle.guide/index Shows the correct way to use `Struct.new` by direct assignment, avoiding extension of `Struct.new` instances to prevent potential inheritance issues. ```ruby Person = Struct.new(:first_name, :last_name) ``` -------------------------------- ### Ruby Spaces and Operators: Safe Navigation Source: https://rubystyle.guide/index Demonstrates the correct usage of the safe navigation operator (`&.`) in Ruby, emphasizing no space between the object and the operator. ```ruby # bad foo &. bar foo &.bar foo&. bar # good foo&.bar ``` -------------------------------- ### Ruby Spaces and Operators: Exponent Operator Source: https://rubystyle.guide/index Illustrates the exception for the exponent operator (`**`) in Ruby, showing that spaces are not required around it. ```ruby # bad e = M * c ** 2 # good e = M * c**2 ``` -------------------------------- ### Prefer add_dependency over add_runtime_dependency Source: https://rubystyle.guide/index Use `add_dependency` instead of `add_runtime_dependency` in your gemspec. `add_runtime_dependency` is considered soft-deprecated, and the Bundler team recommends using `add_dependency`. ```ruby # bad Gem::Specification.new do |s| s.add_runtime_dependency 'gem_a' end # good Gem::Specification.new do |s| s.add_dependency 'gem_a' end ``` -------------------------------- ### Ruby Magic Comments Placement (Above Code) Source: https://rubystyle.guide/index Demonstrates the correct placement of magic comments in Ruby files, ensuring they appear before all code and documentation, except for shebangs. ```Ruby # bad # Some documentation about Person # frozen_string_literal: true class Person end # good # frozen_string_literal: true # Some documentation about Person class Person end ``` -------------------------------- ### Ruby Multiple Magic Comments Formatting Source: https://rubystyle.guide/index Shows the preferred way to format multiple magic comments in Ruby, with each comment on its own line. ```Ruby # bad # -*- frozen_string_literal: true; encoding: ascii-8bit -* # good # frozen_string_literal: true # encoding: ascii-8bit ``` -------------------------------- ### Ruby: Block Forwarding Source: https://rubystyle.guide/index Illustrates Ruby 3.1's anonymous block forwarding, where the `&block` parameter can be simplified to just `&`. This enhances conciseness when a block is passed through. ```ruby # bad def some_method(&block) other_method(&block) end # good def some_method(&) other_method(&) end ``` -------------------------------- ### Avoid Cryptic Perlisms with `English` (Ruby) Source: https://rubystyle.guide/index Replaces Perl-style special variables with human-readable aliases provided by the `English` library for clarity. ```ruby # bad $:.unshift File.dirname(__FILE__) # good $LOAD_PATH.unshift File.dirname(__FILE__) # bad print $', $$ # good require 'English' print $POSTMATCH, $PID ``` -------------------------------- ### Factory Methods for Class Instantiation in Ruby Source: https://rubystyle.guide/index Illustrates the concept of using factory methods to provide alternative, sensible ways to create instances of a class in Ruby. This promotes cleaner instantiation logic. ```ruby class Person def self.create(options_hash) # body omitted end end ``` -------------------------------- ### Using `next` in Ruby Loops Source: https://rubystyle.guide/index Shows how to use the `next` keyword to skip iterations in Ruby loops, avoiding unnecessary nesting and improving code clarity. ```ruby # bad [0, 1, 2, 3].each do |item| if item > 1 puts item end end # good [0, 1, 2, 3].each do |item| next unless item > 1 puts item end ``` -------------------------------- ### Using Implicit `begin` Blocks in Ruby Source: https://rubystyle.guide/index Illustrates the use of implicit `begin` blocks in Ruby for exception handling, simplifying code structure compared to explicit `begin...rescue...end` blocks. ```ruby # bad def foo begin # main logic goes here rescue # failure handling goes here end end # good def foo # main logic goes here rescue # failure handling goes here end ``` -------------------------------- ### Manage Instance Variables Over Global Variables (Ruby) Source: https://rubystyle.guide/index Replaces global variables with module instance variables for better encapsulation and scope management. ```ruby # bad $foo_bar = 1 # good module Foo class << self attr_accessor :bar end end Foo.bar = 1 ``` -------------------------------- ### Ruby: `while`/`until` as a modifier Source: https://rubystyle.guide/index Demonstrates the Ruby convention of using `while` or `until` as a modifier for single-line statements. This pattern is preferred for its conciseness when the loop body is simple. ```ruby # bad while some_condition do_something end ``` ```ruby # good do_something while some_condition ``` -------------------------------- ### Use :: for constants and constructors in Ruby Source: https://rubystyle.guide/index Clarifies the correct usage of the `::` operator in Ruby, reserving it for referencing constants and constructors, not regular method calls. ```ruby # bad SomeClass::some_method some_object::some_method # good SomeClass.some_method some_object.some_method SomeModule::SomeClass::SOME_CONST SomeModule::SomeClass() ``` -------------------------------- ### Avoid `tap` in Production Code (Ruby) Source: https://rubystyle.guide/index Shows how to refactor code that uses `tap` for debugging into a more straightforward assignment and subsequent method calls. ```ruby # bad Config.new(hash, path).tap do |config| config.check if check end # good config = Config.new(hash, path) config.check if check config ``` -------------------------------- ### SCREAMING_SNAKE_CASE for Constants in Ruby Source: https://rubystyle.guide/index Constants in Ruby that do not refer to classes or modules should be named using SCREAMING_SNAKE_CASE. This example demonstrates the correct convention for naming constants. ```Ruby # bad SomeConst = 5 # good SOME_CONST = 5 ``` -------------------------------- ### Use `File::NULL` for null devices Source: https://rubystyle.guide/index Employ the platform-independent `File::NULL` constant instead of hardcoding null device paths like `/dev/null` or `NUL`. This ensures your code works correctly across different operating systems. ```ruby # bad - hardcoded devices are platform specific File.open("/dev/null", 'w') { ... } ``` ```ruby # bad - unnecessary ternary can be replaced with `File::NULL` File.open(Gem.win_platform? ? 'NUL' : '/dev/null', 'w') { ... } ``` ```ruby # good - platform independent File.open(File::NULL, 'w') { ... } ``` -------------------------------- ### Ruby: Condition Placement in Multi-line Conditionals Source: https://rubystyle.guide/index Illustrates the correct placement of conditions on the same line as `if`/`unless` in multi-line conditionals, contrasting it with the incorrect multi-line condition. ```Ruby # bad if some_condition do_something do_something_else end # good if some_condition do_something do_something_else end ``` -------------------------------- ### Ruby `class_eval` with Location Information Source: https://rubystyle.guide/index Demonstrates the correct way to use the string-interpolated form of `class_eval` in Ruby by providing `__FILE__` and `__LINE__` for accurate backtraces. ```ruby class_eval 'def use_relative_model_naming?; true; end', __FILE__, __LINE__ ``` -------------------------------- ### Prefer `proc` over `Proc.new` Source: https://rubystyle.guide/index Use the `proc` method for creating Procs instead of `Proc.new`. While functionally similar, `proc` is considered more idiomatic and slightly cleaner in syntax. ```ruby # bad p = Proc.new { |n| puts n } # good p = proc { |n| puts n } ``` -------------------------------- ### Ruby: Using `if` as a modifier Source: https://rubystyle.guide/index Demonstrates the preferred Ruby style of using `if` as a modifier for single-line statements. Also shows an alternative using control flow operators `and`/`or` for conciseness. ```ruby # bad if some_condition do_something end ``` ```ruby # good do_something if some_condition ``` ```ruby # another good option some_condition and do_something ``` -------------------------------- ### Use parentheses for Ruby method call arguments Source: https://rubystyle.guide/index Recommends using parentheses for method call arguments in Ruby, especially when the first argument starts with an open parenthesis. ```ruby # bad x = Math.sin y # good x = Math.sin(y) # bad array.delete e # good array.delete(e) # bad temperance = Person.new 'Temperance', 30 # good temperance = Person.new('Temperance', 30) ``` -------------------------------- ### Ruby: `loop` with `break` for post-loop tests Source: https://rubystyle.guide/index Shows the preferred Ruby method for loops with post-execution tests using `Kernel#loop` and `break`, contrasting it with older `begin/end/while` or `begin/end/until` constructs. ```ruby # bad begin puts val val += 1 end while val < 0 ``` ```ruby # good loop do puts val val += 1 break unless val < 0 end ``` -------------------------------- ### Avoid RUBY_VERSION in gemspec Source: https://rubystyle.guide/index Do not include `RUBY_VERSION` checks in your gemspec for conditional dependency management. `RUBY_VERSION` is determined during the release process, which can lead to users installing incorrect dependencies. ```ruby Gem::Specification.new do |s| if RUBY_VERSION >= '2.5' s.add_dependency 'gem_a' else s.add_dependency 'gem_b' end end ``` -------------------------------- ### Ruby: `while`/`until` syntax for multi-line blocks Source: https://rubystyle.guide/index Shows the correct Ruby syntax for multi-line `while` and `until` loops, emphasizing the omission of the `do` keyword. This adheres to standard Ruby style conventions. ```ruby # bad while x > 5 do # body omitted end until x > 5 do # body omitted end ``` ```ruby # good while x > 5 # body omitted end until x > 5 # body omitted end ``` -------------------------------- ### Use Bitwise Predicate Methods (Ruby) Source: https://rubystyle.guide/index Replaces direct bitwise operations with semantic predicate methods like `anybits?`, `allbits?`, and `nobits?` for better readability. ```ruby # bad - checks any set bits (variable & flags).positive? # good variable.anybits?(flags) # bad - checks all set bits (variable & flags) == flags # good variable.allbits?(flags) # bad - checks no set bits (variable & flags).zero? (variable & flags) == 0 # good variable.nobits?(flags) ``` -------------------------------- ### Avoid single-line methods in Ruby Source: https://rubystyle.guide/index Shows how to avoid single-line Ruby methods due to potential syntax ambiguities and readability issues, recommending multi-line definitions instead. ```ruby # bad def too_much; something; something_else; end # okish - notice that the first ; is required def no_braces_method; body end # okish - notice that the second ; is optional def no_braces_method; body; end # okish - valid syntax, but no ; makes it kind of hard to read def some_method() body end # good def some_method body end ``` ```ruby # good def no_op; end ``` -------------------------------- ### Ruby Multi-line Arrays Alignment: Good Practice Source: https://rubystyle.guide/index Demonstrates aligning elements of multi-line array literals for better readability, using proper indentation. ```ruby menu_item = %w[Spam Spam Spam Spam Spam Spam Spam Spam Baked beans Spam Spam Spam Spam Spam] ``` -------------------------------- ### Ruby: Method Calls (Parentheses vs. No Parentheses) Source: https://rubystyle.guide/index Demonstrates two acceptable styles for calling Ruby methods, particularly those with 'keyword' status. The preferred style omits parentheses for better readability, while the less popular style includes them for semantic uniformity. Consistency in the chosen style is crucial. ```ruby # good (most popular) puts temperance.age system 'ls' exit 1 # also good (less popular) puts(temperance.age) system('ls') exit(1) ``` -------------------------------- ### Use parentheses for Ruby methods with parameters Source: https://rubystyle.guide/index Explains the Ruby convention of using parentheses for method definitions with parameters and omitting them for methods without parameters. ```ruby # bad def some_method() # body omitted end # good def some_method # body omitted end # bad def some_method_with_parameters param1, param2 # body omitted end # good def some_method_with_parameters(param1, param2) # body omitted end ``` -------------------------------- ### Use . for class methods in Ruby Source: https://rubystyle.guide/index Demonstrates the correct syntax for defining class methods in Ruby using `self.method_name`, avoiding the incorrect use of `self::method_name`. ```ruby # bad class Foo def self::some_method end end # good class Foo def self.some_method end end ``` -------------------------------- ### Collection Accessor Design Source: https://rubystyle.guide/index Advises providing an alternate accessor method for collections that handles index access gracefully, preventing `nil` errors. ```ruby # bad def awesome_things @awesome_things end # good def awesome_things(index = nil) if index && @awesome_things @awesome_things[index] else @awesome_things end end ``` -------------------------------- ### Write to files using `File.write` or `File.binwrite` Source: https://rubystyle.guide/index When creating or overwriting a file's content in a single operation, use `File.write` for text mode or `File.binwrite` for binary mode. This is more concise than using `File.open` with explicit `write` calls. ```ruby ## text mode # bad (only truncating modes: 'w', 'wt', 'w+', 'w+t') File.open(filename, 'w').write(content) File.open(filename, 'w') { |f| f.write(content) } File.open(filename, 'w') do |f| f.write(content) end ``` ```ruby # good File.write(filename, content) ``` ```ruby ## binary mode # bad (only truncating modes: 'wb', 'w+b') File.open(filename, 'wb').write(content) File.open(filename, 'wb') { |f| f.write(content) } File.open(filename, 'wb') do |f| f.write(content) end ``` ```ruby # good File.binwrite(filename, content) ``` -------------------------------- ### Hash Transformation: transform_keys and transform_values Source: https://rubystyle.guide/index Recommends using `transform_keys` and `transform_values` for modifying hash keys or values, as they are more concise than `each_with_object` or `map` for these specific tasks. ```ruby # bad {a: 1, b: 2}.each_with_object({}) { |(k, v), h| h[k] = v * v } {a: 1, b: 2}.map { |k, v| [k.to_s, v] }.to_h # good {a: 1, b: 2}.transform_values { |v| v * v } {a: 1, b: 2}.transform_keys { |k| k.to_s } ``` -------------------------------- ### Ruby Magic Comments Placement (Below Shebang) Source: https://rubystyle.guide/index Illustrates the correct placement of magic comments in Ruby files with shebangs, placing them directly below the shebang line. ```Ruby # bad # frozen_string_literal: true #!/usr/bin/env ruby App.parse(ARGV) # good #!/usr/bin/env ruby # frozen_string_literal: true App.parse(ARGV) ``` -------------------------------- ### Ruby `%r` Literal for Regular Expressions with Slashes Source: https://rubystyle.guide/index Advises using Ruby's `%r` literal for regular expressions that contain at least one forward slash character ('/'). Provides examples of correct usage. ```ruby # good %r{^/(.*$)} %r{^/blog/2011/(.*$)} ``` -------------------------------- ### Prefer Double Quotes for Strings in Ruby Source: https://rubystyle.guide/index This snippet demonstrates the preferred use of double quotes for string literals in Ruby, unless the string itself contains double quotes or escape characters that need to be suppressed. It contrasts 'bad' and 'good' examples. ```ruby # bad name = 'Bozhidar' sarcasm = "I \"like\" it." # good name = "Bozhidar" sarcasm = 'I "like" it.' ``` -------------------------------- ### Ruby Spaces and Operators: Rational Literals Source: https://rubystyle.guide/index Shows the correct usage of spaces with the slash in rational literals in Ruby, where a space is not typically used. ```ruby # bad o_scale = 1 / 48r # good o_scale = 1/48r ``` -------------------------------- ### Order exception rescues specifically Source: https://rubystyle.guide/index When using multiple `rescue` clauses, place handlers for more specific exceptions before those for more general exceptions. This ensures that specific errors are caught correctly. ```ruby # bad begin # some code rescue StandardError => e # some handling rescue IOError => e # some handling that will never be executed end ``` ```ruby # good begin # some code rescue IOError => e # some handling rescue StandardError => e # some handling end ``` -------------------------------- ### Avoid Superfluous Comments in Ruby Source: https://rubystyle.guide/index Illustrates the anti-pattern of adding comments that merely restate what the code clearly does. It emphasizes writing self-documenting code instead. ```ruby # bad counter += 1 # Increments counter by one. ``` -------------------------------- ### Ruby Literal Array and Hash Creation Source: https://rubystyle.guide/index Demonstrates preferred Ruby syntax for creating arrays and hashes using literals (`[]`, `{}`) instead of constructors (`Array.new`, `Hash.new`), unless constructor arguments are needed. ```Ruby # bad arr = Array.new hash = Hash.new # good arr = [] arr = Array.new(10) hash = {} hash = Hash.new(0) ``` -------------------------------- ### Parameter Naming for Symmetrical Operators (Ruby) Source: https://rubystyle.guide/index For Ruby binary operators and operator-alike methods with symmetrical semantics (where operands are typically of the same or coercible types), the parameter should be named `other`. Examples include arithmetic operators and comparison operators. Non-symmetrical operators should not use `other`. ```Ruby # good def +(other) # body omitted end # bad def <<(other) @internal << other end # good def <<(item) @internal << item end # bad # Returns some string multiplied `other` times def *(other) # body omitted end # good # Returns some string multiplied `num` times def *(num) # body omitted end ``` -------------------------------- ### Conditional Assignment Indentation in Ruby Source: https://rubystyle.guide/index Illustrates proper indentation for assignments involving conditional expressions (`case` or `if`). Branches should maintain consistent alignment. ```Ruby # bad - pretty convoluted 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 result = if some_cond calc_something else calc_something_else end # good - it's apparent what's going on 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 result = if some_cond calc_something else calc_something_else end # good (and a bit more width efficient) 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 result = if some_cond calc_something else calc_something_else end ``` -------------------------------- ### Functional Code Style with `map` and `reduce`/`each_with_object` (Ruby) Source: https://rubystyle.guide/index Promotes functional programming by using `map` for transformations and `reduce` or `each_with_object` for building collections, avoiding explicit mutation. ```ruby a = []; [1, 2, 3].each { |i| a << i * 2 } # bad a = [1, 2, 3].map { |i| i * 2 } # good a = {}; [1, 2, 3].each { |i| a[i] = i * 17 } # bad a = [1, 2, 3].reduce({}) { |h, i| h[i] = i * 17; h } # good a = [1, 2, 3].each_with_object({}) { |i, h| h[i] = i * 17 } # good ``` -------------------------------- ### Ruby: `case` vs. `if-elsif` Source: https://rubystyle.guide/index Promotes the use of `case` statements over `if-elsif` chains when comparing the same value across multiple conditions for improved readability. ```Ruby # bad if status == :active perform_action elsif status == :inactive || status == :hibernating check_timeout else final_action end # good case status when :active perform_action when :inactive, :hibernating check_timeout else final_action end ``` -------------------------------- ### Use `Hash#key?` and `Hash#value?` in Ruby Source: https://rubystyle.guide/index Prefer `Hash#key?` over `Hash#has_key?` and `Hash#value?` over `Hash#has_value?` for checking key and value existence in hashes. ```Ruby # bad hash.has_key?(:test) hash.has_value?(value) # good hash.key?(:test) hash.value?(value) ``` -------------------------------- ### Single-line Class Definitions in Ruby Source: https://rubystyle.guide/index Illustrates the preferred two-line format for Ruby class definitions that have no body, making them easier to read and modify compared to single-line or `Class.new` alternatives. ```ruby # ok class FooError < StandardError end ``` -------------------------------- ### CapitalCase for Classes and Modules in Ruby Source: https://rubystyle.guide/index Use CapitalCase (also known as UpperCamelCase or PascalCase) for naming Ruby classes and modules. Acronyms like HTTP, RFC, and XML should remain uppercase. This example shows the correct and incorrect ways to name classes. ```Ruby # bad class Someclass # some code end class Some_Class # some code end class SomeXml # some code end class XmlSomething # some code end # good class SomeClass # some code end class SomeXML # some code end class XMLSomething # some code end ``` -------------------------------- ### Use Ruby 3.1 Hash Literal Value Syntax Source: https://rubystyle.guide/index When a hash key and its corresponding value are the same variable or symbol, use the Ruby 3.1 shorthand syntax (`key:`). ```Ruby # bad hash = { one: one, two: two, three: three } # good hash = { one:, two:, three: } ``` -------------------------------- ### Use Squiggly Heredocs for Indented Strings in Ruby Source: https://rubystyle.guide/index This Ruby code showcases the use of squiggly heredocs (`<<~`) introduced in Ruby 2.3 for handling multi-line strings with indentation. It contrasts 'bad' examples using `strip_margin` or standard heredocs with the 'good' squiggly heredoc approach. ```ruby # bad - using Powerpack String#strip_margin code = <<-RUBY.strip_margin('|') |def test | some_method | other_method |end RUBY # also bad code = <<-RUBY def test some_method other_method end RUBY # good code = <<~RUBY def test some_method other_method end RUBY ``` -------------------------------- ### Complex String Replacements with `gsub` in Ruby Source: https://rubystyle.guide/index Demonstrates using `gsub` with a block or a hash for advanced string replacements in Ruby. Handles simple substitutions and complex transformations based on word capitalization. ```ruby words = 'foo bar' words.sub(/f/, 'f' => 'F') # => 'Foo bar' words.gsub(/\w+/) { |word| word.capitalize } # => 'Foo Bar' ``` -------------------------------- ### Ruby DSL Method Calls: Braces and Parentheses Omission Source: https://rubystyle.guide/index Illustrates omitting both braces and parentheses for method calls that are part of an internal DSL, enhancing conciseness. ```ruby class Person < ActiveRecord::Base attr_reader :name, :age validates :name, presence: true, length: { within: 1..10 } end ``` -------------------------------- ### Ruby: Keyword Arguments Order Source: https://rubystyle.guide/index Provides guidance on ordering keyword arguments in Ruby methods. Required keyword arguments should precede optional ones to improve code readability and maintainability. ```ruby # bad def some_method(foo: false, bar:, baz: 10) # body omitted end # good def some_method(bar:, foo: false, baz: 10) # body omitted end ``` -------------------------------- ### Use Single Quotes for Strings Without Interpolation in Ruby Source: https://rubystyle.guide/index Prefer single-quoted strings (`'...'`) when you do not require string interpolation or special escape sequences (`\n`, `\t`, etc.). This is the default style recommended in this guide. ```ruby # bad name = "Bozhidar" name = 'De\'Andre' # good name = 'Bozhidar' name = "De'Andre" ``` -------------------------------- ### Modules vs. Classes for Class Methods in Ruby Source: https://rubystyle.guide/index Advocates for using modules with `module_function` when a collection of utility methods is needed, rather than creating a class with only class methods. ```ruby # good module SomeModule module_function def some_method # body omitted end def some_other_method # body omitted end end ``` -------------------------------- ### Ruby: Boolean Keyword Arguments Source: https://rubystyle.guide/index Recommends using keyword arguments for passing boolean values to Ruby methods. This approach is cleaner than default arguments or using option hashes. ```ruby # bad def some_method(bar = false) puts bar end # bad - common hack before keyword args were introduced def some_method(options = {}) bar = options.fetch(:bar, false) puts bar end # good def some_method(bar: false) puts bar end some_method # => false some_method(bar: true) # => true ``` -------------------------------- ### Ruby `method_missing` Best Practices Source: https://rubystyle.guide/index Provides guidelines for safely using `method_missing` in Ruby metaprogramming, including defining `respond_to_missing?`, catching specific prefixes, calling `super`, and delegating to other methods. ```ruby # bad def method_missing(meth, *params, &block) if /^find_by_(?.*)/ =~ meth # ... lots of code to do a find_by else super end end # good def method_missing(meth, *params, &block) if /^find_by_(?.*)/ =~ meth find_by(prop, *params, &block) else super end end ``` -------------------------------- ### Hash Value Retrieval: values_at vs. fetch_values Source: https://rubystyle.guide/index Shows how to efficiently retrieve multiple values from a Hash using `values_at` or `fetch_values`, contrasting with less efficient methods like individual access or `map`. ```ruby # bad email = data['email'] username = data['nickname'] # bad keys = %w[email nickname].freeze email, username = keys.map { |key| data[key] } # good email, username = data.values_at('email', 'nickname') # also good email, username = data.fetch_values('email', 'nickname') ```