# Why can't Ruby automatically cast variables?

**URL:** <https://www.ruby-forum.com/t/why-cant-ruby-automatically-cast-variables/70613>\
**Category:** Ruby\
**Created:** [September 30, 2006, 9:48pm UTC](https://www.ruby-forum.com/t/why-cant-ruby-automatically-cast-variables/70613 "2006-09-30T21:48:04Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![joe](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/b9e5f3/32.png) [@joe](https://www.ruby-forum.com/u/joe)\
**Post date:** [September 30, 2006, 9:48pm UTC](https://www.ruby-forum.com/t/why-cant-ruby-automatically-cast-variables/70613/1 "2006-09-30T21:48:04Z")

</div>

One thing that annoys me about Ruby is that casting variables is  
required:

i = 5  
a = ‘logan’

puts a + i.to\_s

Or

a=‘2’  
b=3

puts a.to\_i + b

Why can’t (or can?) Ruby just handle ‘puts a + i’ or ‘puts a+b’?

Joe

---

<div class="post-metadata">

**Author:** ![joe](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/b9e5f3/32.png) [@joe](https://www.ruby-forum.com/u/joe)\
**Post date:** [September 30, 2006, 9:59pm UTC](https://www.ruby-forum.com/t/why-cant-ruby-automatically-cast-variables/70613/2 "2006-09-30T21:59:06Z")

</div>

Joe R. MUDCRAP-CE wrote:

> a=‘2’  
> b=3
> 
> puts a.to\_i + b
> 
> Why can’t (or can?) Ruby just handle ‘puts a + i’ or ‘puts a+b’?

That’s not type casting, that’s type coercion. BIG difference.

Language-level automagical number / string type coercion is a Perl / PHP  
-ism, and it’s a feature of those languages I loathe and despise for the  
bugs it tends to cause.

Numbers are numbers. Strings are strings. Strings that happen to  
represent numbers are still strings. Ruby is a strongly-typed language,  
a Very Good Thing from a code maintainability point of view, that’s why  
type coercion is always explicit.

Ruby sometimes does this on the library-function level, but in the  
examples you described, the meaning is always ambiguous. Especially  
since adding an integer to a string means the integer is considered to  
be the ASCII code of a character.

If I do ‘logan’ + 115, does that mean I want the result to be ‘logans’  
because 115 is the ASCII code for ‘s’, should be ‘logan115’, or should  
it be just 115 because ‘logan’ isn’t a number and thus automagically  
coerces to 0? And for ‘2’ + 3 it gets even worse, which of those should  
be coerced to what and why?

This is, in my opinion, best left explicit. The possible interpretations  
are way, way too numerous and difficult to keep in one’s head at once.

David V.

---

<div class="post-metadata">

**Author:** ![joe](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/b9e5f3/32.png) [@joe](https://www.ruby-forum.com/u/joe)\
**Post date:** [September 30, 2006, 10:11pm UTC](https://www.ruby-forum.com/t/why-cant-ruby-automatically-cast-variables/70613/3 "2006-09-30T22:11:07Z")

</div>

Joe R. MUDCRAP-CE wrote:

> a=‘2’  
> b=3
> 
> puts a.to\_i + b
> 
> Why can’t (or can?) Ruby just handle ‘puts a + i’ or ‘puts a+b’?

It does. It just doesn’t handle it the way you might prefer. If Ruby  
did automatic coercion, then someone else would wonder why Ruby doesn’t  
"correctly: handle the ‘+’ operation.

Given this code:

a=‘2’  
b=3

puts a+b

This is sending the message ‘+’ to the String object referenced by ‘a’.  
Strings have a particular implementation of the ‘+’ message, and it  
assumes that the arguments will be something that implements certain  
behavior. (I.e., is sufficiently String-like ).

By default, the above code barfs with “… can’t convert Fixnum into  
String (TypeError)”

You can teach the Integer class how to stringify itself, though:

class Integer  
def to\_str  
self.to\_s  
end  
end

But note that there is an important side-effect: Integers mistakenly  
used in place of a String will now silently convert themselves, which  
may not be the behavior you (or users of your code) will always want.

Ruby has strong dynamic typing; objects need only respond to the set  
messages your code needs to send to them in order to be useful (AKA duck  
typing). That’s the dynamic part. But Ruby will not automagically alter  
the behavior of objects. That’s the strong part.

* * *

James B.

“Blanket statements are over-rated”

---

<div class="post-metadata">

**Author:** ![joe](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/b9e5f3/32.png) [@joe](https://www.ruby-forum.com/u/joe)\
**Post date:** [October 1, 2006, 4:35am UTC](https://www.ruby-forum.com/t/why-cant-ruby-automatically-cast-variables/70613/4 "2006-10-01T04:35:27Z")

</div>

Joe R. MUDCRAP-CE wrote:

> David V. wrote:
> 
> Point taken. I can’t imagine wanting to do ‘logan’ + 115 and have it be  
> ‘logans’ (as opposed to just doing ‘logan’ + ‘s’), but I’m sure there  
> are applications for adding ASCII values.

That’s a convention / burp of Ruby. Indexing a string with an integer  
instead of a Range returns the ASCII code of the character at that  
position. Adding an integer to a string does cause an exception to be  
thrown. However,

irb(main):001:0\> foo = ‘quux’  
=\> “quux”  
irb(main):002:0\> foo[-1] = 115  
=\> 115  
irb(main):003:0\> foo  
=\> “quus”  
irb(main):004:0\> foo[-1] = ‘bar’  
=\> “bar”  
irb(main):005:0\> foo  
=\> “quubar”

That means the behaviour is reflexive and at least somewhat consistent,  
a minor redeeming quality.

As far as I know, in Ruby 1.9, and 2.0, indexing a String will return a  
one-character string instead of making that a special case, so the need  
for this type conversion will disappear.

(Technically, an int -\> char conversion isn’t a change of data. However,  
since Ruby doesn’t have the char data type, the above behaviour is  
contextual overloading of the integer datatype - a special case when an  
integer isn’t treated as a character, and that is, at least for me,  
confusing.)

> > That’s not type casting, that’s type coercion. BIG difference.
> 
> Hmm, what’s the difference? IIRC, PHP’s docs referred to (int)$stringvar  
> as casting, which seems the same as to\_s, to\_i, etc.

Casting is usually an explicit conversion, coercion an implicit one. PHP  
documents are correct on that, except PHP performs a much larger set of  
type conversions that way than most other languages where type casting  
appears (C, Java; C++ and C# let you overload type conversion, but don’t  
do type conversion between wildly heterogenous types out of the box).  
Noted explicitly, it’s not really a problem, since you don’t have to pay  
attention to the context to see whether the type conversion does or does  
not happen.

Coercion is an implicit conversion that the language runtime does for  
you. The problem with it is that it’s not readily visible when it  
happens, and tends to contribute to language “gotchas” - unobvious rules  
you have to keep in your head when reading code. Ruby has a one of those  
with String#match() - if the argument to the method is a String, it gets  
coerced to a Regexp. Of course, I had to fire up irb to find out if the  
method receiver or the argument is the coerced object.

Extensive “magical” behaviour of a programming language in the long term  
leads to people ending up with more of the language in their head  
especially when not dealing with write-only code to maintain it, and  
keeps information needed to read the code out of sight. It isn’t harmful  
in some cases - for example for String#format, the printf-specifiers  
already indicate that a certain argument will be interpreted for example  
as an integer, and it’s redundant to have to restate this. It’s not good  
when the coercion would be ambiguous though, and actively harmful  
(PHPism) when conversion doesn’t ever fail cleanly - like a string that  
doesn’t contain a single number that coerces into 0.

David V.

---

<div class="post-metadata">

**Author:** ![joe](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/b9e5f3/32.png) [@joe](https://www.ruby-forum.com/u/joe)\
**Post date:** [October 1, 2006, 2:54am UTC](https://www.ruby-forum.com/t/why-cant-ruby-automatically-cast-variables/70613/5 "2006-10-01T02:54:51Z")

</div>

David V. wrote:

Point taken. I can’t imagine wanting to do ‘logan’ + 115 and have it be  
‘logans’ (as opposed to just doing ‘logan’ + ‘s’), but I’m sure there  
are applications for adding ASCII values.

> That’s not type casting, that’s type coercion. BIG difference.

Hmm, what’s the difference? IIRC, PHP’s docs referred to (int)$stringvar  
as casting, which seems the same as to\_s, to\_i, etc.

Joe

---

<div class="post-metadata">

**Author:** ![joe](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/b9e5f3/32.png) [@joe](https://www.ruby-forum.com/u/joe)\
**Post date:** [October 2, 2006, 5:37pm UTC](https://www.ruby-forum.com/t/why-cant-ruby-automatically-cast-variables/70613/6 "2006-10-02T17:37:20Z")

</div>

Joe R. MUDCRAP-CE wrote:

> a=‘2’  
> b=3
> 
> puts a.to\_i + b
> 
> Why can’t (or can?) Ruby just handle ‘puts a + i’ or ‘puts a+b’?

How would it know whether you wanted to concatenate the two, or add  
them?

---

<div class="post-metadata">

**Author:** ![joe](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/b9e5f3/32.png) [@joe](https://www.ruby-forum.com/u/joe)\
**Post date:** [October 2, 2006, 10:03pm UTC](https://www.ruby-forum.com/t/why-cant-ruby-automatically-cast-variables/70613/7 "2006-10-02T22:03:35Z")

</div>

Sammy L. wrote:

> Joe R. MUDCRAP-CE wrote:
> 
> > a=‘2’  
> > b=3
> > 
> > puts a.to\_i + b
> > 
> > Why can’t (or can?) Ruby just handle ‘puts a + i’ or ‘puts a+b’?
> 
> How would it know whether you wanted to concatenate the two, or add  
> them?

By reading my mind.

Joe

---

<div class="post-metadata">

**Author:** ![joe](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/b9e5f3/32.png) [@joe](https://www.ruby-forum.com/u/joe)\
**Post date:** [October 5, 2006, 10:57pm UTC](https://www.ruby-forum.com/t/why-cant-ruby-automatically-cast-variables/70613/8 "2006-10-05T22:57:51Z")

</div>

On 9/30/06, Joe R. MUDCRAP-CE [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Hmm, what’s the difference? IIRC, PHP’s docs referred to (int)$stringvar  
> as casting, which seems the same as to\_s, to\_i, etc.

PHP is not to be taken as an authority on anything. Especially Ruby.

(int)$stringvar is casting. stringvar.to\_i is _conversion_. The  
automatic handling of such conversion is called coercion.

-austin

---

<div class="post-metadata">

**Author:** ![joe](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/b9e5f3/32.png) [@joe](https://www.ruby-forum.com/u/joe)\
**Post date:** [October 6, 2006, 12:50am UTC](https://www.ruby-forum.com/t/why-cant-ruby-automatically-cast-variables/70613/9 "2006-10-06T00:50:02Z")

</div>

On 30/09/06, Joe R. MUDCRAP-CE [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> a=‘2’  
> b=3
> 
> puts a.to\_i + b
> 
> Why can’t (or can?) Ruby just handle ‘puts a + i’ or ‘puts a+b’?

I don’t suggest you actually use this, but:

class String  
def coerce(lhs)  
[lhs, self.to\_i]  
end

```
alias_method :old_plus, :+
def +(rhs)
  if rhs.is_a?(Numeric)
    return rhs + self
  else
    return old_plus(rhs)
  end
end

```

end

1 + ‘1’ #=\> 2

‘2’ + 2 #=\> 4

‘foo’ + ‘bar’ #=\> “foobar”

Paul.
