Since I started my Ruby learning process, one of the most basic and important things I consider, is the POLS (Principle of the Least Surprise).

This week, a new question about “string pattern formatting”, came up on the forum.

Considering this code:

'%0.2f' % ((f.to_f - 32) / 9 * 5)

Which is the meaning of the second “%” ?

After some research, I found two options on that “formatting” subject.

- You can format your data immediately, using the printf method.

f = -123.12345

puts sprintf('%0.3f', f)

- You can create a template, and interpolate data with it later.

template = '%s, has always been in %s with %s.'

puts template % ['Oceania', 'war', '

puts template % ['Luke Skywalker', 'love', 'Leia Organa']

OK, there is a nice functionality, but about POLS ?

For sure I have little experience with Ruby, but the fact, you can use the modulus operator over strings, really surprises-me.

I deal with a great assort of programming languages over 2 decades now, and never ever, applied the modulus operator over strings.

Think about this code:

puts 'abc' % 'def' # <= 'abc'

puts 'abc' % 10 # <= 'abc'

And there is another point. Negative numbers:

Witch should be the -5 % 3 result ? 2 ? -2 ?

In fact in Ruby, -5 % 3 = 1

Why ?

Some programming languages adopt the C89 standard about that subject. That is the way Ruby does:

remainder = a % n

is the same of:

remainder = a - n * floor_funtion(a / n)

where floor_function from a decimal value, returns the highest integer, less than or equal to it.

So, in Ruby this is the formula for modulus remainder result:

r = ((a) - ((n) * ((a) / (n))))

* Extra parenthesis, to put negative values easily and clear.

Ahh, take a look at those SuperRubyBoy's operators !

## 7 comments:

You have to keep in mind that in Ruby there are NO operators... just method calls (or rather, messages) "masked" as operators (with the possible exception of the ternary ?: operator).

"abc" % 10 is just syntax sugar for "abc".%(10), just like 1 + 2 is equivalent to 1.+(2) and so on.

Given that, the truth is that you're NOT applying the "modulus" operator to a string, you're just calling a regular method which happens to have a "special" name.

If your really want to bend your mind have a look at this: http://jicksta.com/articles/2007/08/29/superators-add-new-operators-to-ruby

Thanks ste,

That is the reason of this blog. To force myself into Ruby thinking way.

Now I realize that I miss something on this Ruby translated formula:

r = ((a) - ((n) * ((a) / (n))))

It is not working with decimals.

Could You help ?

-5 mod 3 = 1 because -5 = 3(-2) + 1.

I have to say that this section has been frustrating to understand......but reading what you wrote has helped me a lot. Thanks! :)

Hi Ricardo, finally I understood the % concept. Thank you for your explanation!

Very Interesting!

Thank You!

The string interpolation with percent and percent operator are somewhat surprising to me (i think the importance of the operation is a bit exaggerated by assigning a separate and somewhat random operator to it).

However, what is wrong with -5 % 3 being 1? It is the remainder of division of -5 by 3 (which is the unique number in the interval 0..2 congruent to -5 mod 3). Indeed:

0 <= 1 <= 2, and - 5 - 1 = - 6 is divisible by 3.

Post a Comment