Ruby, Ruby, Ruby, Ruby!


I’m not done learning JavaScript yet, so I thought: do you know what, let’s look at some other languages now. I don’t know anyone who’s finished a Udemy course anyway, and 33% completion is very good so it’s time for me to move on (edit: I have completed at least one Udemy course) to the greener grass on the other side of the troll bridge. I wanna get that whole multilingual thing going on. Amser dysgu!

A while ago, I bought a book called Seven Languages in Seven Weeks. Then I read the intro, which let me know that it probably was not suited to newbie coders who haven’t even mastered one language yet – so I put it aside. For about a month.

I just can’t leave an idea alone once it’s gotten into my head.

Seven Languages in Seven Weeks is “a pragmatic guide to learning programming languages”, and although it takes you through the basics and quirks of a few (seven) languages, it’s not trying to teach you to solve all of your problems in them. It’s about learning the different types of languages, the way they’re compiled and run and the many styles of syntactic sugar. It teaches you how to learn languages, basically.

I used a lot of words, sorry. Compiling = turning the human-readable code you wrote into Machine Language the computer can understand, which is 1s and 0s. Syntax is the way you structure code in a language, and syntactic sugar is a way of describing that – for example, to return a string (bunch of letters) in your console using JavaScript you would say:

console.log("Apparently putting curry sauce on your chips is a Northern thing??")

while doing the same thing in Ruby would be written as:

puts "I'm from West Wales and everyone I know does it. Why would you not?!"

Optimistically, I decided that it would probably be fine and I could work my way through the languages in the book at least a little bit. It took me a week to get through the first day of the first language, excluding homework time (the book assumes you have 20mins in your lunch break you can spend doing this, and that you also have time to read/research outside of that time), and another week for the second ‘day’. I also found that I was understanding fewer of the concepts over time, especially around passing behaviours and objects down an inheritance tree? I use a question mark there because I am not even sure I used the right words to describe what I don’t understand. It’s on my list of things to research, so if you have some nice resources to share about this then send them my way!

Feeling put off by the (nicely explained but still difficult to understand) concepts that needed deeper thought and research to really ‘get’, I put the book away again… For about a week.

Did I mention that I just can’t let ideas go? Especially when they cost me money. xD

Engineering Breakfast

We have a workshop slot every two weeks at our company, which is called the Engineering Breakfast. Contrary to its name, we have only eaten breakfast foods once during the activity.

When I first joined Fresh8, the slot was being used for doing a Tech Radar (in which you list different techniques, tools, platforms and languages/frameworks, and then decide whether or not to adopt, trial, assess or hold their use). Looking back with my current knowledge, I’d love to do this again because it’s a super valuable workshop activity. I’m also trying to work out how to make a personal Tech Radar to help continue to define and improve my learning journey. Back then though, I had no idea what was going on, and kept being asked to contribute when I’d only been in the tech industry for three weeks… I only have stressful memories of it, thinking that I was going to be “found out” for not deserving my newfound job.

The engineering breakfast slot was intended to be an open time where anyone could share a skill or run a workshop, but it’s very hard to keep something like that going without a designated organiser, so it goes empty more often than not. My cool managey lead person decided to get some simple activities together so that we could at least do something to help each other learn, and so we’ve been trying out new languages.

He put together some really simple exercises around strings and arrays, and told us all to install the prerequisites for whatever language we wanted to use ahead of time. I was going to try Swift or Io, but installing things without npm or homebrew is strange to my spoiled mind now, so I fell back on Ruby since I already had that installed and ready to go. (I’ve since installed swipl for running prolog code, so I guess I got over this quickly).

There’s two ways of running your Ruby code (after installing iton your machine). You can write it in a file and then type “ruby <path to file>” in console. Or for playing about you can type “irb” in console to open the interactive ruby shell.

puts "This string will be returned in console"
>> This string will be returned in console

That’s your simple “Hello, world” scenario.

The first challenge that um, challenged me was “Write a program that asks the user for their name and greets them with their name.” It’s super simple, but I didn’t know how to take user input from the console, and use it in the next action. In my mind, there was going to be a super complex answer but in reality I just needed to know which words to type in a search engine – “Ruby CLI user input”. Apparently most of learning to code is knowing how to find the information you want, which is why I reckon it’s so hard to learn your first language. You don’t even know what to ask to get the answer you need.

puts "What is your name?"
>> What is your name?
<< Bruce
name = gets
puts "Hello, #{name}"
>> Hello, Bruce

Turns out it’s very easy. “gets” is used to get the user input, and above I have assigned it to the value of “name”. Then in the next line I use the variable “name” in a string to return whatever the user introduced themselves as. There is a weird secret to gets however, which caused a problem for me and Joe that we had to enlist the help of a developer to reveal during the third challenge:

Modify the previous program such that only the users Alice and Bob are greeted with their names.

puts "What is your name?"
name = gets

if name == "Alice" || name == "Bob"
    puts "Hello, #{name}"
    puts "Go away, I don't know you."

The code above first asks what the user’s name is, then gets their reply and assigns it as the value of name. Then it checks what the value of name is, and if it’s Bob or Alice, it says hi. If the name doesn’t match either of those, it tells you to go away. The problem we had was that even if we typed Alice or Bob, it would tell us to go away. We tried using puts everywhere to log what the value was in different places in the code block – returning the value of gets, returning the value of name inside the else block… It always came up “Alice” or “Bob”, exactly as we had typed it in, but then it would say that it didn’t match!

So here’s the secret: “puts” hides newlines. In Ruby, you can split a string onto a second line (to write haikus, obviously) by adding “\n” where you want it, but when there is a newline in a string you can’t see it with puts. It just puts the thing on a new line, and doesn’t show you the \n you typed in. When the user enters their name, the next thing they do is press enter so there is actually an invisible new line at the end of the name value. After typing Alice, the value returned was actually “Alice\n” so it never matched our if statement.

To return the actual value, we can use “p” instead of “puts”. It does the same job, but doesn’t tidy things up for you:

name = gets
puts name
>> Bruce
p name
>> "Bruce\n"

Luckily, Ruby gives us an easy way of getting rid of unnecessary spaces: the chomp! In one bite, it takes away the unnecessary newline for you.

puts "What is your name?"
name = gets.chomp

if name == "Alice" || name == "Bob"
    puts "Hello, #{name}"
    puts "Go away, I don't know you."

By adding just one word to the code (name = gets.chomp), we made it work because it chomps the input before assigning it to name. Now when the user types in Alice, that’s what will be checked against instead of “Alice/n”.

The last challenge I’ll talk about is “Write a program that asks the user for a number n and prints the sum of the numbers 1 to n.” We spent a long time on this one, writing out while loops that increased a value x every time it went through the loop and then added that to n and added that to an ongoing tally… And ended up running ourselves in logic circles working out why our answers were always coming out slightly wrong. I found it useful to get out a sheet of paper and write what the values of each variable were at the start and end of each go around the loop.

I can’t remember what the code looked like at this point, but I had a value for x that started at 1, then would get y added to it during the loop. I think y was always x + 1. In my head, this made sense. But when I actually wrote it out, what I assumed was looping four times to add 1 + 2 + 3 + 4 was actually only looping twice:

Image showing some workings. It reads
Loop 1: x = 1
y = 2
(1 + 2 = 3)
x = 3
Loop 2: x = 3
y = 4
(3 + 4 = 7)
x = 7

Instead of the sum of the range 1 to 4 (10), my code was returning the sum of 3 and 4 (7).

While skimming through the Ruby chapter in Seven Languages for inspiration, I found an easier answer: inject. I say easier, but what I mean is “does the job in a smaller number of words”. It took a while for me to understand what inject actually does, even after using it.

puts "Tell me a number"
>> Tell me a number
number = gets.to_i

First thing’s first, we have an easy method for turning the user’s input into a number, which is to_i (to integer). Otherwise, when the user enters 12, it will be turned into a string “12” and we can’t do maths on that. We get the value returned, turn it into an integer and call that “number”.

rangesum = (1..number).inject(:+)

The next line gets a range of numbers using (1..number). The ‘..’ kind of fills in everything in between for you, so in the case that the user answered 4 then it would be 1..4, or 1,2,3,4. Inject then takes the range of values from here and injects something else in between each one. In this case inject(:+) takes the symbol ‘+’ and puts it between every value between 1 and number. Therefore rangesum is equal to 1+2+3+4, which it calculates for you as 10. All that’s left is to tell the user the result!

puts "The sum of numbers between 1 and #{number} is #{rangesum}"
>> The sum of numbers between 1 and 4 is 10

I don’t know who would find this useful or interesting to have read, but it was definitely fun learning a few bits n bobs in a new language, even if it’s a language that works very similarly to one I already know fairly well.

I feel that I improved my search-engine-fu when it comes to solving problems with code, so it was time well spent. It was also great when everyone shared their results after using a variety of different languages in the group. We had a lot of rust, and some julia and swift learners, and it was cool to browse through people’s solutions in those languages to see which looked intuitive to read and which used more/less lines than the others to achieve the same goal.

Ruby is a pretty great language in my opinion, since it’s designed to be human-readable. There are some things that I just didn’t understand at first, like 1..4 as a range, and then using methods like inject on that. Not everything is easily understood without having knowledge of the syntax, but I definitely ‘got’ it more quickly than I have trying to learn the logic language Prolog ahah…

Bonus: ASCII Art with Ruby

If you grew up in a certain generation, then you probably know what ASCII art is already. It’s basically all those symbols and squiggles that people way cooler than you on the internet were able to make pictures out of, but that never came out right when you tried to paste them on your Bebo profile.

| | | )_) )_) )_) ~ ~~~ )___))___))___)\ ~~~ ~ ~~~ )____)____)_____)\ ~~ ~~ ~~ _____|____|____|____\\\__———\ /——— ^^^^^ ^^^^^^^^^^^^^^^^^^^^^ ^^^^ ^^^^ ^^^ ^^ ^^^^ ^^^

Thanks, copy-paste, for getting rid of the spaces and newlines, and ruining this lovely boat!

              |    |    |
             )_)  )_)  )_)
  ~  ~~~    )___))___))___)\    ~~~ ~
   ~~~     )____)____)_____)\\   ~~
 ~~   ~~ _____|____|____|____\\\__
---------\                   /---------
  ^^^^^ ^^^^^^^^^^^^^^^^^^^^^
    ^^^^      ^^^^     ^^^    ^^
         ^^^^      ^^^

Ah-hah! If I use a code block then it preserves the empty space. Thanks, wordpress! All I really wanted to say about this is that \ is an escape key in many coding languages, which means to ignore the following character, eg ‘Hello I\’m Bruce’ will stop this string from ending at ‘Hello I’. So they kind of disappear in ASCII art if you, like me, want to return them as strings to spice up your life with some nauticery. The fix is easy – you just have to use two \\ instead of one \. Double up yo’ slashes.

Then you get to make little illustrated stories, which is obviously the one true thing coders should be doing with their time:

1 thought on “Ruby, Ruby, Ruby, Ruby!”

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.