Skip to content

Instantly share code, notes, and snippets.

@pjones
Created November 18, 2015 19:54
Show Gist options
  • Save pjones/dc6157e575b0d27ac4c6 to your computer and use it in GitHub Desktop.
Save pjones/dc6157e575b0d27ac4c6 to your computer and use it in GitHub Desktop.
The new safe navigation operator in Ruby 2.3
#!/usr/bin/env ruby
################################################################################
#
# Watch out for the unusual argument evaluation rules with the new
# safe navigation operator in Ruby 2.3.
#
# It short circuits just like the logic operators. This is different
# than how the `try' method works in ActiveSupport.
#
################################################################################
class Test
def foo; self; end # Always returns `self'
def bar; nil; end # Always returns `nil'
def putsN (n); puts(n.to_s); end
end
################################################################################
# Use the &. operator to guard against nil values:
t = Test.new
x = 1
t&.foo&.putsN(x += 1) # x is now 2
t&.bar&.putsN(x += 1) # x is still 2
t.putsN(x) # see for yourself
################################################################################
# Works a lot like:
x = 1
(y = t.foo) && y.putsN(x += 1) # x is now 2
(y = t.bar) && y.putsN(x += 1) # x is still 2
t.putsN(x)
################################################################################
# But differently than:
class Object
def try (name, *args)
send(name, *args) unless nil?
end
end
x = 1
t.try(:foo).try(:putsN, x += 1) # x is now 2
t.try(:bar).try(:putsN, x += 1) # x is now 3!
t.putsN(x)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment