Skip to content

Instantly share code, notes, and snippets.

@sobstel
Last active November 10, 2023 20:20
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sobstel/dab11bcac14c2b82281f563c90713ba5 to your computer and use it in GitHub Desktop.
Save sobstel/dab11bcac14c2b82281f563c90713ba5 to your computer and use it in GitHub Desktop.
Effective Ruby

Effective Ruby

#1 (Almost) Everything is true

  • Every value is true except false and nil.
  • The number zero is true in Ruby.
  • Use the nil? method to differentiate between false and nil.

#2 All objects could be nil

  • Coerce nil objects into the expected type (eg use to_i and to_s).
  • Array#compact/Hash#compact removes all nil elements.
  • Array#dig/Hash#dig returns nil if any intermediate step is nil.

#3 -

#4 Constants are mutable

  • Always freeze constants to prevent them form being mutated (eg TIMEOUT = 5.freeze).

#5 -

#6 -

#7 Different behaviours of super

  • When you override a method from inheritance hierarchy the super keyword can be used to call the overriden method.
  • Using super with no arguments and parentheses is equivalent to passing it all of the arguments that were given to the enclosing method.
  • If you want to use super without passing the overriden method any arguments, you must use empty parentheses (eg super()).

#8 -

#9 -

#10 Struct for structured data

  • When dealing with structured data which doesn't quite justify a new lass prefer using Struct to Hash.
  • Assign the return value of Struct::new to a constant and treat that constant like a class (eg Reading = Struct.new(:date, :high, :low))

#11 -

#12 Different flavors of equality

  • Never ovveride the equal? method. It's expected to strictly compare objects and return true only if they're both pointers to the same object in memory (have the same object_id).
  • The Hash class uses the eql? method to compare objects used as keys during collisions. The default implementation probably doesn't do what you want. You need to implement <=>, then alias eql? to == and write a sensible hash method.
  • Use the == operator to test if two objects represent the same value.
  • case expressions use the === operator to test each when clause. The left operand is the argument given to when and the right operand is the argument given to case.

13 Compare via <=> and the Comparable module

  • Implement object ordering by defining a <=> operator and including the Comparable module.
  • The <=> operator should return nil if the left operand can't be compared with the right.

14 -

15 Class instance variables over class variables

  • Prefer class instance variables to class variables.
  • Classes are objects and so have their own private set of instance variables.

16 Duplicate collections before mutating them

  • Method arguments are passed as references, not values (except Fixnum objects).
  • Duplicate collections passed as arguments before mutating them, eg @collection = collection.dup.
  • The dup and clone methods only create shallow copies. For most objects, Marshal can be used to create deep copies.

17 Use the Array method to convert nil and scalar objects into arrays

  • Use the Array method to convert nil and scalar objects into arrays
  • Don't pass Hash to the Array method; it will get converted into a set of nested arrays

References

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment