14
.
11
.
2023
1
.
09
.
2019
Ruby on Rails
Ruby

Ruby Quirks

Jan Matusz
Ruby Developer

Ruby is a beautiful language to work with. It provides tons of amenities for developers.

Like every other language, though, Ruby has things that you may not be aware of, or may not fully understand --- and these quirks are the subject of today's blog post.

? character literal notation

It is a simple notation that allows to create a string out of a character (in Ruby > 2):

docs.ruby-lang.org does not provide too many details about it:

There is also a character literal notation to represent single character strings, which syntax is a question mark (?) followed by a single character or escape sequence that corresponds to a single codepoint in the script encoding.

A person named Josh Cheek commented about this in the rubyguides.com article:

Also, their existence is historical rather than practical, back when chars were still int literals (1.8, IIRC), it was useful to have a syntax for going from the char to the ordinal, which is what this was for. Then when chars became single-letter strings, they made the syntax resolve to that rather than deprecating it and breaking lots of code.

END & DATA

These keywords hold a very specific functionality, that is not often used --- at least in the web development specter of Ruby use cases. Probably it can be used in scripting / CLI tools.

__END__ specifies... well, the end of a Ruby program

When executing this keyword, nothing past it will be interpreted. Consider this code:

And then we run it:

DATA

DATA allows you to get access to whatever is past END. If we slightly modify the code above:

And then execute it:

This gist also should give you an idea of how you can use it.

::method

Usually, when you see code samples in Ruby all methods are invoked with a . --- such as 12.to_s, "1".to_i, User.create! etc.

Having said that, it is perfectly valid to call these methods using :::

It is not considered as a good practice --- the recommended way is obviously to call methods through a . operator.

However, if you want code obfuscation, you can go crazy using ::. For instance, adding two integers in Ruby is nothing else than calling a #+ method on one of these, and then passing the other one as an argument:

This means...

https://gist.github.com/Marahin/6c3f445343dfdedf723bbd7b853bc9f4#file-obf-rb

Looking crazy, isn't it

Shovel method on strings --- <<

Shovel method can be used on instances of String class. It can be provided with both an integer representation of the character (ASCII code) and another string:

redo and retry

These methods are similar in their functionality. redo allows you to, well, re-do the current iteration block, where retry repeats whole block.

Consider this code:

It does a couple of things:

  1. Defines theretry_on_raise function that accepts a block.
  2. Then, if the block raises any exceptions, it is going to retry the block once.
  3. Exactly 3 times it executes retry_on_raise.
  4. It randomly passes raise into the block so the method would have a chance to retry.
  5. Also it redos the iteration if the upcoming index is 2.

Whether you should use these two --- it is hard to say. retry is something I have seen multiple times in Rails applications. I think that when you have a good reason to use it, it is fine --- but then redo makes it a bit more complex.\ The developer would have to mind that it is no longer the whole block being called again, but a single iteration step.

In other words --- I think it really depends on the case.

Ruby Quicktips also has quite a few good examples worth checking out.

Literals

Numbers

Binary 1111is 15decimal. Ruby supports specifying values in different number systems by passing a proper prefix:

d or D stands for decimal, x or X for hexadecimal, 0 or 0o stands for octal, binary b. The alphabetic part of the prefix is case insensitive, hence it can but does not have to be capitalized.

Another interesting part in number literals is the underscore separator. The documentation does not specify any explicit usage for it, except for human readability improvements.

It is super nice to use it when you deal with constants that specify a big number. It makes it harder to do human errors such as missing a single 0 in a big number.

Ranges

You must have used some kind of range at a given point while working with Ruby. Maybe using rand(1..10) or an iteration of some kind.

But do you know the difference between ... and .. range? Its pretty simple: 1..10 is an inclusive range (starts from 1, ends at 10), and 1...10 is an end-exclusive range (ends at 9).

Symbols

While it may be common knowledge for most of you, I have experienced that some people do not realize you can actually put string interpolation into symbols.

In the wrong hands, it may be a terrible idea, since symbols are not garbage collected --- but sometimes it is really useful.

Ruby has pretty good documentation for literals, so if you are interested in seeing more, head over to docs.ruby-lang.org!

Proc & .

In CultureHQ's Weird Ruby I had stomped upon something that I did not know myself.

Usually when handling Procs, I just called them by .call method --- seems verbose, explicit and understandable to any developer that might come after me.

Yet it seems that you can also call Proc by square brackets method ([something]).

It made me think so I dug into Class: Proc documentation, and found out there are several ways to call a Proc instance:

In general, it is a good practice to write code that can be understood by others --- be it your team members or developers that may take over the project eventually. Hence I would say that .call or .yield would be the way to go here, as personally I would have had no idea on what ["Thomas", 23] really does.

I think that there is a good chance I am not the only one and .call would make it way more explicit.


I hope this article has raised at least a couple of eyebrows.\ Ruby is an awesome tool --- but like any other, it has its weird moments.\ Feel free to share your thoughts in the comments section!

If you're interested in more blog posts like this please visit our Visuality Blog or our Medium Page.

If by any chance you're planning to visit DLD Conference in Tel Aviv do not hesitate to visit us, we can talk a bit more about our company!

Jan Matusz
Ruby Developer

Check my Twitter

Check my Linkedin

Did you like it? 

Sign up To VIsuality newsletter

READ ALSO

Writing Chrome Extensions Is (probably) Easier Than You Think

14
.
11
.
2023
Antoni Smoliński
Tutorial
Frontend
Backend

Bounded Context - DDD in Ruby on Rails

17
.
03
.
2024
Paweł Strzałkowski
Ruby on Rails
Domain-Driven Design
Backend
Tutorial

The origin of Poltrax development - story of POLTRAX (part 2)

29
.
11
.
2023
Stanisław Zawadzki
Ruby on Rails
Startups
Business
Backend

Ruby Meetups in 2022 - Summary

14
.
11
.
2023
Michał Łęcicki
Ruby on Rails
Visuality
Conferences

Repository - DDD in Ruby on Rails

17
.
03
.
2024
Paweł Strzałkowski
Ruby on Rails
Domain-Driven Design
Backend
Tutorial

Example Application - DDD in Ruby on Rails

17
.
03
.
2024
Paweł Strzałkowski
Ruby on Rails
Domain-Driven Design
Backend
Tutorial

How to launch a successful startup - story of POLTRAX (part 1)

14
.
11
.
2023
Michał Piórkowski
Ruby on Rails
Startups
Business

How to use different git emails for different projects

14
.
11
.
2023
Michał Łęcicki
Backend
Tutorial

Aggregate - DDD in Ruby on Rails

17
.
03
.
2024
Paweł Strzałkowski
Ruby on Rails
Domain-Driven Design
Backend
Tutorial

Visuality at wroc_love.rb 2022: It's back and it's good!

14
.
11
.
2023
Patryk Ptasiński
Ruby on Rails
Conferences
Ruby

Our journey to Event Storming

14
.
11
.
2023
Michał Łęcicki
Visuality
Event Storming

Should I use Active Record Callbacks?

14
.
11
.
2023
Mateusz Woźniczka
Ruby on Rails
Backend
Tutorial

How to rescue a transaction to roll back changes?

17
.
03
.
2024
Paweł Strzałkowski
Ruby on Rails
Backend
Ruby
Tutorial

Safe navigation operator '&.' vs '.try' in Rails

14
.
11
.
2023
Mateusz Woźniczka
Ruby on Rails
Backend
Ruby
Tutorial

What does the ||= operator actually mean in Ruby?

14
.
11
.
2023
Mateusz Woźniczka
Ruby on Rails
Backend
Ruby
Tutorial

How to design an entity - DDD in Ruby on Rails

17
.
03
.
2024
Paweł Strzałkowski
Ruby on Rails
Domain-Driven Design
Backend
Tutorial

Entity - DDD in Ruby on Rails

17
.
03
.
2024
Paweł Strzałkowski
Ruby on Rails
Domain-Driven Design
Backend
Tutorial

Should I use instance variables in Rails views?

14
.
11
.
2023
Mateusz Woźniczka
Ruby on Rails
Frontend
Backend
Tutorial

Data Quality in Ruby on Rails

14
.
11
.
2023
Michał Łęcicki
Ruby on Rails
Backend
Software

We started using Event Storming. Here’s why!

14
.
11
.
2023
Mariusz Kozieł
Event Storming
Visuality

First Miłośnicy Ruby Warsaw Meetup

14
.
11
.
2023
Michał Łęcicki
Conferences
Visuality

Should I use Action Filters?

14
.
11
.
2023
Mateusz Woźniczka
Ruby on Rails
Backend
Tutorial

Value Object - DDD in Ruby on Rails

17
.
03
.
2024
Paweł Strzałkowski
Ruby on Rails
Domain-Driven Design
Backend
Tutorial