Just use the ordinary (non-sugar) form.

request.path.match(/\A\/(?<slug>(?!admin|assets)\w+)/)&.[](:slug)
Answer from sawa on Stack Overflow
🌐
Thoughtbot
thoughtbot.com › blog › ruby-safe-navigation
Ruby safe navigation
July 18, 2024 - Ruby’s safe navigation can hide some subtle edge cases. We explore approaches to think about conditional logic, alternatives to &., and when &. is the best tool for the job.
🌐
Mitrev
mitrev.net › ruby › 2015 › 11 › 13 › the-operator-in-ruby
The Safe Navigation Operator (&.) in Ruby - Georgi Mitrev
The most interesting addition to Ruby 2.3.0 is the Safe Navigation Operator(&.). A similar operator has been present in C# and Groovy for a long time with a slightly different syntax - ?..
🌐
Ruby-Doc.org
ruby-doc.org › core-2.6 › doc › syntax › calling_methods_rdoc.html
File: calling_methods.rdoc [Ruby 2.6]
&., called “safe navigation operator”, allows to skip method call when receiver is nil.
🌐
Fullstackheroes
fullstackheroes.com › tutorials › ruby › safe-navigation-operator
The safe navigation operator (&.) in Ruby - Full Stack Heroes
Ruby's safe operator is used when you don't want your app to throw an exception if a method is called on a nil object.
🌐
Reddit
reddit.com › r/ruby › til: the safe navigation operator (&.) in ruby
r/ruby on Reddit: TIL: The Safe Navigation Operator (&.) in Ruby
May 22, 2021 - Celebrate the weird and wonderful Ruby programming language with us! ... РусскийTiếng ViệtFrançaisPortuguês (Brasil)ČeštinaPolskiEspañol (Latinoamérica)RomânăไทยSuomiDeutsch ... Safe navigation is a great shortcut for dealing with nil values, but doing more work with languages like Typescript lately have made me realize that using this too much can also be a smell since most Ruby bugs I deal with wind up being some variation of undefined method foo for nil:NilClass
🌐
Rip Tutorial
riptutorial.com › safe navigation operator
Ruby Language Tutorial => Safe Navigation Operator
Ruby 2.3.0 added the safe navigation operator, &.. This operator is intended to shorten the paradigm of object && object.property && object.property.method in conditional statements.
🌐
ShiftAsia
shiftasia.com › community › better-null-check-with-safe-navigation-operator-in-ruby
Better null-check with Safe Navigation operator in Ruby
February 20, 2024 - To overcome this problem, Ruby provides a shorthand operator called the Safe navigation operator (&.) or lonely operator that helps you avoid the NoMethodError, which was introduced in Ruby 2.3.0.
🌐
Wikipedia
en.wikipedia.org › wiki › Safe_navigation_operator
Safe navigation operator - Wikipedia
1 month ago - In programming languages where ... the safe navigation operator stops the evaluation of a method/field chain and returns null as the value of the chain expression. It was first used by Groovy 1.0 in 2007 and is currently supported in languages such as C#, Swift, TypeScript, Ruby, Kotlin, Rust, ...
Find elsewhere
🌐
Ruby
bugs.ruby-lang.org › issues › 11537
Feature #11537: Introduce "Safe navigation operator" - Ruby - Ruby Issue Tracking System
Also this is clearly a bit of a contrived example, it does highlight some of the more unexpected behaviors of the .? operator. ... Applied in changeset r52214. ... I know this is already decided and the commit is out there, but since you are adding new syntax and a new feature to the language, I suggest you reconsider https://bugs.ruby-lang.org/issues/9076 · With that change, instead of adding special syntax for safe nil traversing, you get generalized syntax for the implicit block argument.
🌐
Beezwax
blog.beezwax.net › rubys-safe-navigation-operator-and-is-it-a-code-smell
Ruby’s Safe Navigation Operator &. and is it a Code Smell? | beezwax blog
February 14, 2024 - Ruby's safe navigator operator "&." isn't inherently bad. In fact if you have something like "foo && foo.bar" in your code, Rubocop will admonish you for not using safe navigation.
Top answer
1 of 3
5

There are 2 seperate operators here:

  1. Safe navigation operator &. - It is safe navigation operator which was introduced in Ruby 2.3.0. It basically returns nil if the callee is nil instead of raising excecption undefined method called for Nil class. eg:

    a = 1
    a.next
    # => 2
    a&.next
    # => 2
    a = nil
    a.next
    # => NoMethodError (undefined method `next' for nil:NilClass)
    a&.next
    # => nil ## No exception, returns nil
    

    You can read about it more here and documentation

  2. Unary & : This operator is a little more complex. It is almost equivalent to calling #to_proc but not quite that. But for this discussion let us think like that. So, if you have a Proc, calling with & in front of it will call #to_proc on the Proc and convert it into a block

    multiply_by_2 = Proc.new { |x| x * 2 }
    # => #<Proc:0x00007fb4771cf560>
    # &multiply_by_2 almost equivalent to { |x| x * 2 } but is not correct syntax
    [1, 2].map(&multiply_by_2)
    # => [2, 4]
    # equivalent to  [1, 2].map { |x| x * 2 }
    

    But what happens if we give a symbol like :abc to & operator instead of a proc. It will try to call #to_proc on the symbol and ruby has defined Symbol#to_proc which roughly translates to something like this:

    def to_proc
      # this will return some block like { |x| x.send(:abc) }
      lambda { |x| x.send(self) }
    end
    

    So &:abc roughly translates to this block { |x| x.abc } using the below transformation

    &:abc =====> :abc.to_proc =====> { |x| x.send(:abc) } ====> { |x| x.abc }
    

    So, instead of doing [1, 2, 3].map { |x| x.next }, you could do [1, 2, 3].map(&:next) as &:next is roughly equivalent to the block { |x| x.next }.

    See unary & (which is the main source of what I have written here) for more reading.

2 of 3
1

It's ruby syntax, & calls to_proc on the object and passes the result as a block to the method.

An explanation from the pickaxe book, programming Ruby 1.9 and 2.0

Blocks Can Be Objects

Blocks are like anonymous methods, but there’s more to them than that. You can also convert a block into an object, store it in variables, pass it around, and then invoke its code later. Remember we said that you can think of blocks as being like an implicit parameter that’s passed to a method? Well, you can also make that parameter explicit. If the last parameter in a method definition is prefixed with an ampersand (such as &action ), Ruby looks for a code block whenever that method is called. That code block is converted to an object of class Proc and assigned to the parameter. You can then treat the parameter as any other variable. Here’s an example where we create a Proc object in one instance method and store it in an instance variable. We then invoke the proc from a second instance method.

class ProcExample

  def pass_in_block(&action)
    @stored_proc = action
  end

  def use_proc(parameter)
    @stored_proc.call(parameter)
  end
end

Use it like so

eg = ProcExample.new
eg.pass_in_block { |param| puts "The parameter is #{param}" }
eg.use_proc(99)

produces:

The parameter is 99

🌐
Medium
ashvinchoudhary.medium.com › safely-navigate-with-the-safe-navigation-operator-in-ruby-on-rails-45b4394466a3
Safely Navigate with the Safe Navigation Operator in Ruby on Rails | by Ashvin Choudhary | Medium
June 7, 2023 - What is the Safe Navigation Operator? The Safe Navigation Operator (&.) is a feature introduced in Ruby 2.3 and later versions, specifically designed to handle situations where you need to access methods or attributes on an object that might be nil.
Top answer
1 of 5
7

To quote from the syntax documentation for the safe navigation operator:

&., called “safe navigation operator”, allows to skip method call when receiver is nil. It returns nil and doesn't evaluate method's arguments if the call is skipped.

As such, the arguments of your log method are not evaluated if the logger is nil when you call it as

logger&.log("something happened at #{Time.now}")

With that being said, note that the Ruby core logger offers a different solution to your exact issue, namely to avoid having to evaluate potentially expensive arguments if the log level is to high.

The Ruby core logger implements its add method something like this (simplified):

class Logger
  attr_accessor :level

  def initialize(level)
    @level = level.to_i
  end

  def add(severity, message = nil)
    return unless severity >= level
    
    message ||= yield
    log_device.write(message)
  end

  def info(message = nil, &block)
    add(1, message, &block)
  end
end

You can then use this as

logger = Logger.new(1)
logger.info { "something happened at #{Time.now}" }

Here, the block is only evaluated if the log level is high enough that the message is actually used.

2 of 5
3

Expression Parsed But Not Executed

The argument to logger&.log isn't evaluated when logger.is_a?(NilClass) == true. Every Ruby expression that's evaluated should have an impact, so consider:

test = 1
nil&.log(test+=1); test
#=> 1

If the argument were evaluated by the interpreter, test would equal two. So, while the parser certainly parses the expression in your argument, it doesn't execute the inner expression.

You can verify what the parser sees with Ripper#sexp:

require 'ripper'

test = 1
pp Ripper.sexp "nil&.log(test+=1)"; test
[:program,
 [[:method_add_arg,
   [:call,
    [:var_ref, [:@kw, "nil", [1, 0]]],
    [:@op, "&.", [1, 3]],
    [:@ident, "log", [1, 5]]],
   [:arg_paren,
    [:args_add_block,
     [[:opassign,
       [:var_field, [:@ident, "test", [1, 9]]],
       [:@op, "+=", [1, 13]],
       [:@int, "1", [1, 15]]]],
     false]]]]]
#=> 1

This clearly shows that the parser sees the incremented assignment in the symbolic expression tree. However, the assignment is never actually executed.

🌐
Fuzzyblog
fuzzyblog.io › blog › ruby › 2019 › 11 › 16 › the-ruby-safe-navigation-operator.html
The Ruby Safe Navigation Operator
As its name reflects, the safe navigation operator allows us to safely call a method on a object that can be nil, in the same way as try! does in ActiveSupport. In that regard, if the object is not nil, it sends the method to the object, returning nil otherwise.
Top answer
1 of 4
115

&. works like #try!, not #try.

And here is description of #try! (from documentation):

Same as #try, but will raise a NoMethodError exception if the receiving is not nil and does not implemented the tried method.

So, &. saves you from calling a method on nil, but if the object is present it will try to call the method as usual, including raising NoMethodError if the method is not implemented.

#try, on the other hand, saves you from calling a method on nil and calling a method that is not implemented. It will return nil in either case, and never raise NoMethodError.

The quote is from Rails Documentation, and so it's important to emphasize that Ruby does not provide #try; it's provided by Rails, or more accurately ActiveSupport. The safe navigation operator (&.) however, is a language feature presented in Ruby 2.3.0.

2 of 4
24

I am arriving to the party a bit late here, the other answers have covered how it works, but I wanted to add something that the other answers have not covered.

Your question asks What is the difference between try and &. in Ruby. Ruby being the key word here.

The biggest difference is that try doesn't exist in Ruby, it is a method provided by Rails. you can see this or yourself if you do something like this in the rails console:

Copy[1, 2, 3].try(:join, '-')
#=> "1-2-3" 

However if you do the same thing in the irb console, you will get:

Copy[1, 2, 3].try(:join, '-')
NoMethodError: undefined method `try' for [1, 2, 3]:Array

The &. is part of the Ruby standard library, and is therefore available in any Ruby project, not just Rails.

🌐
Ruby in Rails
rubyinrails.com › 2017 › 11 › 17 › safe-navigation-operator-ampersand-dot-in-ruby
Safe navigation operator in Ruby
November 17, 2017 - Ruby 2.3 has introduced safe navigation operator to not throw exception if a method is called on the nil object. This is handy when we don't want code to break if the objects are nil.
🌐
Medium
medium.com › @hetalsharma9422 › the-safe-navigation-operator-in-ruby-on-rails-simplifying-code-and-preventing-errors-975457df23eb
The Safe Navigation Operator (&.) in Ruby on Rails: Simplifying Code and Preventing Errors | by Hetal sharma | Medium
April 23, 2023 - The Safe Navigation Operator (&.) is a shorthand notation for checking if an object is nil before calling a method on it. The operator was introduced in Ruby 2.3 and is commonly used in Ruby on Rails.
🌐
Visuality
visuality.pl › posts › safe-navigation-operator-vs-try-in-rails
Safe navigation operator '&.' vs '.try' in Rails - Blog - Visuality
Safe navigation operator &. is provided by Ruby. It returns nil only if the receiver of the method is nil as well.