Skip to content

andycandrea/this_or_that.rb

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

23 Commits
 
 
 
 

Repository files navigation

This || that

This repo is meant to act as a collection of resources describing similar methods, classes, patterns or techniques in Ruby and Rails. These entities might be similar in name, functionality or usage but have some differences that may or may not be readily apparent.

The provided resources largely describe differences in usage and semantics and might not include differences in performance or version compatibility. For more information, including different ways in which items in this list may differ, see the recording from RailsConf 2024 and the slides from the talk.

When reading the resources, consider any accepted answers and discussion and note that some information might be more or less relevant for different versions of Ruby and/or Rails.

This is a work in progress and is not expected to be exhaustive. I do hope, however, it will continue to get closer over time. If you have any suggestions, additions, clarifications or corrections, please feel free to open an issue or a pull request.

NOTE: aliases, such as update and update_attributes from ActiveRecord, are (largely) not included in this list. There may, however, be differences in which versions of Ruby or Rails introduced a method and its aliases.

To see a searchable table of contents, click the list button on GitHub visible here:

image


Arrays

<< vs push vs concat

Array#[0]/Array#[-1] vs Array#first/Array#last

bsearch vs find

flat_map vs map.flatten

insert vs unshift

Kernel#Array vs Array.new vs []


Hashes

Hash#[] vs fetch vs dig

Hash.new(default) vs Hash.new { default }

merge vs deep_merge

merge vs reverse_merge vs ** vs merge! vs store vs update


Ranges

Range#cover? vs Range#include?

.. vs ...


Other Enumerable

Comparisons under this section apply to multiple Enumerable classes.

each_with_object vs reduce(:to_h)

Enumerable vs Enumerator

group_by vs index_by vs index_with


Strings

'' vs "" vs String.new vs Kernel.String

casecmp vs casecmp? vs downcase ==

delete_suffix vs chomp

Normal vs dashed vs squiggly heredocs

start_with? vs end_with? vs [0]== vs [-1]==

tr/tr! vs sub/sub! vs gsub/gsub!


Numbers

Kernel#format vs Float#round().to_s

to_i vs Integer()


Regular expressions

=~ vs match vs match? vs Regexp#=== vs String#scan


Classes, instances and hierarchy

ancestors.include? vs Module#<= vs Module#<

Class vs instance methods

Class instance variables vs class variables

include vs extend vs prepend

instance_eval vs class_eval vs eval

Global variables vs constants

  • Exploring Ruby's Global Constants and Variables by Ariel Juodziukynas
  • Some global variables can special meanings in Ruby: link to docs
    • Note that some of these will change over time while your app is running depending on what code gets run (e.g. the regex matching ones), so don't define them manually and expect them to be stable
  • Constants are namespaced to the class/module they are defined in; "global" constants are really nested under Object
    • For a list of such constants, you can run Object.constants
  • Constants can be privatized with private_constant

Inline vs nested modules

is_a? vs kind_of? vs instance_of?

Local vs instance vs class vs global variables

.new vs #initialize


Class comparisons

Integer vs Rational vs Float vs BigDecimal vs Complex

Fixnum vs Bignum vs Integer

Module vs Class

NoMethodError vs NotImplementedError

Object vs BasicObject

Struct vs OpenStruct vs Data

Time vs DateTime vs ActiveSupport::TimeWithZone

Thread vs Fiber


Operators and "operators"

This section includes methods that can be called via syntactic sugar that look like operators.

== vs === vs eq? vs equal?

.. in conditionals vs .. elsewhere

  • In most cases, .. is used to construct a Range (see "Ranges" section above)
  • In conditionals (including ternary operators), .. is the flip-flop operator

or vs ||

a + b vs b + a

  • Methods (including mathematical operations) are not inherently commutative in Ruby
  • a + b is equivalent to a.+(b); if a and b are different classes, a different underlying method will likely be called when swapping the order
  • Examples
    • ===
      • String === "" vs "" === String
      • /string/ === "string" vs "string" === /string/
      • (1..5) === 3 vs 3 === (1..5)
    • *
      • "a" * 3 vs 3 * "a"
    • +
      • Time.zone.now + 1.day vs 1.day + Time.zone.now

a ||= b vs a || a = b vs a = a || b


General Ruby

abort vs exit vs exit! vs raise

alias vs alias_method vs alias_attribute

as_json vs to_json

attr_accessor vs mattr_accessor vs cattr_accessor vs attr_internal_accessor

Backticks vs system vs exec vs fork vs IO.popen vs Open3.popen3 vs PTY.spawn

Blocks vs procs vs lambdas

case in vs case when

  • Case when docs
  • Case in/pattern matching docs
    • Of note if you're new to Ruby's pattern matching: "if the value of the expression does not match any branch of the case expression (and the else branch is absent), NoMatchingPatternError is raised." In other words, an else may prevent an uncaught exception that you might not expect to be necessary.

clone vs dup

defined?(yield) vs block_given?

define_method vs define_singleton_method

  • define_method is defined on Module whereas define_singleton_method is defined on Object
  • define_method is typically used to define an instance method on a class or module whereas define_singleton_method is for defining a method on a single instance of a class

instance_variable_set vs local_variable_set

local_variables vs defined?

Long vs short coercion

loop vs while true

Monkey-patching vs define_method vs class_eval

Positional vs arg-based privacy

  • How to define a private method in Ruby?
    • Note the inline option available since Ruby 2.1
  • Note that positional privatization does not affect class methods
    • Doing a def self.method after a private will not make it a private class method

private vs protected vs public

Refinements vs monkey-patching

rescue vs ensure vs else

respond_to? vs defined? vs method_defined?

retry vs redo

Ruby bang methods, e.g. downcase vs downcase!

throw/catch vs raise/rescue

to_s vs inspect

Various ways to call a method


Comparing topics between Ruby and Rails

count vs length vs size

delegate vs def_delegator vs def_delegators vs SimpleDelegator vs DelegateClass vs method_missing

distinct vs uniq

sort vs sort_by vs order

try vs &.


Rails exclusives

any? vs count > 0 vs exist?

deliver vs deliver_now vs deliver_later

each vs find_each vs find_in_batches vs in_batches

each { render ... } vs render ..., collection: ...

f.select vs select_tag

flash vs flash.now

form_for vs form_tag vs form_with

has_one|many through: vs delegated associations

  • Depending on how you use includes (or alternatives) and the association read method, either has_many :foos, through: :bar or delegate :foos, to: :bar could lead to unnecessary extra queries or n+1s
  • Try to get your team on board with a default so that there are shared patterns to help the team avoid unnecessary queries

includes vs preload vs eager_load

Path helpers vs URL helpers

perform vs perform_now vs perform_later

Rails bang methods, e.g. update vs update!

select vs collection_select

  • rails collection_select vs. select
  • Extra caveat
    • collection_select will do a SELECT * unless you tell it otherwise and will hydrate entire ActiveRecord model objects for each row if you do something like:

      collection_select(..., ..., Author.all, :id, :name)
    • If you don't already have everything in memory or don't need to reuse the collection, you'll likely get some performance improvements if you instead use select like:

      select(..., options_for_select(Author.pluck(:name, :id))
    • This does a SELECT name, id and doesn't build the entire models up in memory.

    • As always, do what feels right in the context of your app/team unless you really need every last bit of performance

select vs pluck

tag vs content_tag

update vs update_attribute vs update_all vs update_columns vs toggle vs touch vs …

About

Resources to differentiate similar methods/classes in Ruby/Rails

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published