---
title: Ruby under the influence [of Scala]
teaser: 'Learning Scala has changed the way that I write my Ruby.

  '
tags: ruby,scala
author: Rachel Mathew
published_on: 2019-03-27
---

I recently rolled off of a Scala project and onto a Rails project. I noticed
that the Rails that I’ve been writing has changed as a result of learning Scala,
so I thought it would be interesting to document some of these changes.

## Types Systems

The most obvious differences are due to Scala’s static type system. Scala is
typed language meaning that all variables have a defined or inferred type, and
those types are verified for correctness at compile time. Moving from Scala's
type system back to Ruby’s dynamic types has made me more thoughtful about the
types that I am passing around.

In Scala function definitions are often written in the form of:

```scala
def add(x: Int, y: Int): Int
```

X, and y are parameters with a type of Int and Int is also the return type. Now
when using my add method Scala won’t let me use `add` with non-integer params.

Building off of this example, if for some reason there was a case where I wanted
to add two variables but there was a chance that either of those variables could
be nil, Scala has a different way of representing that type, and that's using
the option type. Where an option is either None (similar to Ruby's nil) or an
Int. Now our function would look something like this:

```scala
def add(x: Option[Int], y: Option[Int]): Option[Int]
```

This function definition is now telling us that x or y could be none, or Int.
It's easy in Ruby to forget to think about how your code handles nil cases,
whereas Scala forces you to be explicit about when you're working with a
possible None type.

Now if we were looking at how I would write that same function in Ruby, I would
try to communicate the type information through my naming:

```ruby
def optional_addition(optional_int_1, optional_int_2)
```

The way that I implement `optional_addition` would also change. While my Ruby
`def add` might error when given nil, I would want `def optional_addition` to
have some logic for handling that nil case.

## Creating New Types

Scala’s type system, similar to most typed languages, can produce clearer more
reliable code and the more information that can be encoded into the type system
the better.

One way to do this in Scala is through the use of case classes. A case class is
similar to a model in Rails. They look similar to this:

```scala
case class Cat(name: String, color: String, gender: Gender)
```

Where Gender might be another case class that only allows a select set of
‘gender values’ . Now we know that every instance of cat will have a name, color
and gender.

Rails models accomplish similar type guarantees via validations to ensure that
attributes and associations are present. Because these are usually only
available at the interface with our database, we tend to not have these checks
elsewhere in our system. By comparison, in Scala I would create case class for
small objects that weren’t necessarily backed by database tables, and were often
confined to a small part of my system.

While I’ve seen Rails models that aren’t backed by database tables, it feels
clunky to create a model for an object which won’t be used very often. Instead
I’ve found myself reaching for Ruby’s structs which don't have a built in
mechanism to ensure data/type integrity, but will guarantee that there are the
correct number of attributes.

```ruby
Struct.new("Cat", :name, :color, :gender)

Struct::Cat.new("Tom", "blue", "female")
```

## Collection manipulation

To be honest I can’t recall if I had a tendency to favor `.each` in Ruby, but
since learning Scala I definitely have a preference for favoring methods such as
`.map`, and `.collect`. Scala, similar to Ruby, is a mix of functional and
object oriented programming, however the Scala that I've been writing has skewed
to being more functional. As such I've gravitated towards methods such as `.map`
that behave in a more functional way by returning the collection created by
applying the block to each element of the collection. I have been avoiding
methods used only for side effects, like `.each`.

```ruby
[1,2,3].each do |b|
  b + 1
end

# Returns: [1,2,3]
```

vs.

```ruby
[1,2,3].map do |b|
 b + 1
end

# Returns: [2,3,4]
```

## Wrap Up

I’m sure that as I write more Rails, and more Scala, I’ll continue to notice
differences in the way that I code, these are just my initial observations. I
always find it interesting to watch how my coding evolves as I learn new things,
and I hope that this was an interesting reflection.
