Read more

Ruby: Referencing global variables with the built-in English library

Emanuel
June 19, 2020Software engineer at makandra GmbH

tl;dr

Don't forget require 'English' if you use a named global such as $LAST_MATCH_INFO. Otherwise this could result in an annoying bug.

With Ruby's build-in library English Show archive.org snapshot you can reference global variables with an english name. This makes you code easier to read and is also suggested by Rubocop's Style/GlobalVars Show archive.org snapshot cop.

Illustration web development

Do you need DevOps-experts?

Your development team has a full backlog? No time for infrastructure architecture? Our DevOps team is ready to support you!

  • We build reliable cloud solutions with Infrastructure as code
  • We are experts in security, Linux and databases
  • We support your dev team to perform
Read more Show archive.org snapshot

Example before:

if 'foo' =~ /foo/
  puts $~[1] # => foo
end

Example after:

if 'foo' =~ /foo/
  puts $LAST_MATCH_INFO[1] # => foo
end

Require pitfall in Rails

The English library is not loaded by default in Rails. So you or another library needs to require it. The chances are very high, that you application will fail in production without an explizit require e.g. when you use Rubocop or Capybara. These gems most often live in your development and/or test group of the Gemfile and require English for you.

Therefore to ensure that the library is loaded in all environments, add the following line to your config/application.rb or create an initializer like config/initializers/english.rb with the following content:

require 'English'

List of global aliases

$ERROR_INFO => $!
$ERROR_POSITION => $@
$FS => $;
$FIELD_SEPARATOR => $;
$OFS => $,
$OUTPUT_FIELD_SEPARATOR => $,
$RS => $/
$INPUT_RECORD_SEPARATOR => $/
$ORS => $\
$OUTPUT_RECORD_SEPARATOR => $\
$INPUT_LINE_NUMBER => $.
$NR => $.
$LAST_READ_LINE => $_
$DEFAULT_OUTPUT => $>
$DEFAULT_INPUT => $<
$PID => $$
$PROCESS_ID => $$
$CHILD_STATUS => $?
$LAST_MATCH_INFO => $~
$IGNORECASE => $=
$ARGV => $*
$MATCH => $&
$PREMATCH => $`
$POSTMATCH => $'
$LAST_PAREN_MATCH => $+

Rubocop - Style/SpecialGlobalVars

The code snippet of How to fix gsub on SafeBuffer objects was adjusted during a rubocop upgrade.

Rubocop tells you everything you need to know to fix the offense Style/SpecialGlobalVars:

Style/SpecialGlobalVars: Prefer $LAST_MATCH_INFO from the stdlib 'English' module (don't forget to require it) over $~.

In this scenario you should be very careful. If you forget to require 'English', your code may not work any longer as expected.

Emanuel
June 19, 2020Software engineer at makandra GmbH
Posted by Emanuel to makandra dev (2020-06-19 11:52)