Ruby history and design goals
Before we jump into Rails and start building our first application, let's cover the basics of Ruby. Ruby was created in 1993 by this dude, aka Yukihiro Matsumoto, or Matz as he's known on the interwebs. There'd be no Rails without there first being the Ruby programming language. So Matz created Ruby by taking parts of his favorite languages to create his ideal programming language. Matz designed Ruby for programmer productivity and fun with a focus on the language being understood by humans first and computers second, which is why Ruby is such a fantastic language to learn, especially for beginners, because it's very easy to read and understand.
Using IRB: the interactive Ruby REPL
So, the best way to play around with Ruby is by using the IRB or interactive Ruby interpreter. You can use IRB to quickly test out your ideas as well as learn Ruby. To get started, open up a terminal window. You can find the terminal in your applications menu or the command prompt on Windows and type irb and press enter. So IRB is a read-eval-print loop, or REPL. Basically it reads your inputs, evaluates it, and then shows the result. So let's give it a little try. Let's type a little greeting surrounded by quotation marks. Try typing "good morning beautiful!" and then hit enter and it prints out "good morning beautiful." So what exactly just happened? Well, IRB evaluated the expression we wrote and output the results. In this case, it output the string itself. So what if we wanted to print the results to the screen? Well, we could say puts "good morning beautiful". Puts is a command to print something out in Ruby. So what does the arrow nil part mean? Well, that's the result of the expression. In Ruby, a method always returns something. Puts always returns nil, which in Ruby and other languages means zilch, zero, or nothing. Just a quick note, you can get out of IRB by pressing Ctrl+D and it will exit you out. If you need to get out of a current operation, for example, if I type an unterminated string like "good morning and then hit enter, IRB is going to be confused. So what we can do is hit Control+C to escape out of that current command and retype it. Also, if you hit Command+K, you can clear your current screen.
Ruby data types: overview & numbers
So in Ruby your data comes in various types. We have numbers, strings, booleans, arrays, symbols, and hashes. So briefly I want to talk about each one. First off: numbers. Ruby can do math operations such as addition, subtraction, multiplication, but it can also do evaluations such as even or odd values. For example, let's give it a try. Let's try 5 + 5. It returns 10. 5 - 2 returns 3. 10 * 8 gives 80. And in Ruby for the division we do 8 / 2 as division. So 8 / 2 would be four. And then we can even check like I mentioned before if a value is odd or even. So if I did 8.odd? it would return false because 8 is an even number.
Strings: creation, concatenation, and repetition
Strings are words or phrases surrounded by single or double quotes. For example, we can do "I am a string." We can also combine strings together by simply adding them. So if I did "what's" + "up" it combines those two together to form "what'sup." As you can see Ruby does not put in a space by default, so what we need to do is add a space to the second string and then hit enter again and then it adds them together as a single line. You can also multiply strings if you want. For example, if I did "ho " * 3, it would do "ho ho ho."
Booleans and logical operators
A boolean is an expression that evaluates to either true or false. Most of the time you'll use a boolean operator, either a logical operator or a comparison operator to compare boolean values. In Ruby you can do and, or, and not to compare values between each other, which will result in either a true or false value. And is represented by two ampersands, or is represented by two pipe characters, and not is represented by an exclamation point. For example, true && true returns true. True && false returns false. True || true returns true. True || false would return true as well. If I did !true, that returns false. And if I did !false, that returns true.
Comparison operators
Comparison operators are used to test the relationship between objects. The available operators you can use are equals, which is represented by two equal signs put together (==); not equals, which is represented by an exclamation point and equals (!=); less than or equal to (<=); greater than or equal to (>=); and also less than (<) or greater than (>). So if I try to compare two values: if I do 1 == 1, that's true. If I do 5 != 5, that's obviously false. Is 3 < 4? That is true. If I do 3 >= 4, that's false. Is 1 < 3? That's true. Is 1 > 3? That is false.
Arrays: creation, indexing, concatenation, and mutation
In Ruby an array is basically a list of objects. They can be any type of object including other arrays. You can create an array by surrounding a list of objects with square brackets. For example, we could say my_array = [1, 'two', 3, 'four']. So we can mix and match integers and strings because we can use whatever type of object we want. One thing to note is that arrays are indexed from zero. For example, if I did my_array[1] to pull out the second value, you might expect 'two', but instead it's actually the element at index one — arrays start from zero. So this would be index 0, 'two' would be index 1, and 3 would be index 2. We can also add data to an array either by adding a new array or using the << operator. For example, my_array + [5, 6, 7] returns a new array that is the combination of the old array and the new array. We can append data to our current array, so if we did my_array << 8, for example, it will show [1, 'two', 3, 'four', 8]. One thing to note is this: if we use addition to add two arrays together it will create a new array, but if we append a new item with << it will modify the existing array. For example, my_array after << 8 is now saved; whereas when we added arrays with + that was not saved unless you assigned it back.
Symbols: memory-efficient identifiers
Symbols are similar to strings as they're made up of characters, but instead of being wrapped in quotation marks, they're usually prefixed by a colon. One of the main uses for symbols are hash keys. We'll get into hashes in a second, but unlike strings, symbols are unique, which makes them more memory efficient. You can see this for yourself by creating a string and a symbol and calling the object_id method on them both. For example, if we do "ruby".object_id we get this big long number. And if we do :ruby.object_id we get a much smaller number, which makes it more memory efficient.
Hashes: key-value collections
Hashes are a collection or a set of key-value pairs. It's similar to an array except that the indexing — the hash key — can be any data type, not just an integer index. When you need to access a value inside of a hash, you'll just need to pass the corresponding key through square brackets. For example, if I do a variable called who_am_i and assign that to a hash { first_name: 'McKenzie', last_name: 'Child' } and hit enter. Now if we want to find a value of an existing key, we can simply do who_am_i[:first_name] and that returns the value.
Variables: assignment and naming conventions
As you've seen a few times already, variables are simply a value assigned to a name. A variable can contain nearly all types of values, including numbers, strings, arrays, or a hash. A variable is assigned using the equal operator, not to be confused with == which is used for testing equality. One thing to note: a variable name can include a letter, number, or underscore, but it must begin with either a letter or an underscore. When using a multiple-word variable name, it's best practice to use an underscore in between them. For example, my_name is a valid variable name. So again, if I say my_name = "McKenzie", that's a valid assignment.
Methods: defining and calling reusable code
A method is simply a block of reusable code. Creating a method is simple. They start with def followed by the name of the method and then they go on until they reach an end, and everything in between the def and the end is what gets run. For example, if I say def good_morning and I'll say puts "good morning beautiful" and then end. So now if I try and run the good_morning method it'll say "good morning beautiful."
Conditionals: if and unless
Ruby has a few conditional operators that you can use to control the flow of your program. They include if, unless, elsif, and else. Let's briefly talk about each one. The if statement takes a boolean expression and only executes the code if the expression evaluates to true. For example, we can assign a variable of age and say age = 72. So I can say if age > 65 puts "you're a senior citizen" end. And you can see it output "you're a senior citizen" because age was indeed greater than 65. Unless is the opposite of an if statement where it takes a boolean expression and only executes the code if the expression evaluates to false. For example, if we do age = 22, I can say unless age > 65 puts "you're young" end. And since the age wasn't greater than 65, the puts value did indeed get run.
Elsif, else, and control flow examples
An elsif statement is used to manage the flow of a program. It has to be used within an if or unless block and takes a boolean expression. It only runs the code if the previous statements do not run and its expression evaluates to true. For example, if age = 22, we can say if age < 2 puts "you're still a baby" elsif age < 13 puts "you're a child" elsif age < 19 puts "you're a teenager" else puts "you're an adult" end. And because age is equal to 22 none of the other values evaluated to true, so it did the else statement and said "you're an adult." An else block is very similar to the elsif in that it has to be used within an if or unless block and it only gets run if the other statements do not get run. But the difference between an else and an elsif is the else does not take any arguments. For example, if age = 22 again, we say if age > 50 puts "you're getting old" else puts "you're still young" end. And because we're only 22, the if statement does not get run, so the else statement gets run instead.
Iteration with each and closing remarks
So when you're working with a collection of objects, for example an array or a hash, sometimes you want to perform an operation on each item within that collection. For that Ruby provides a method called each, and each method can accept one or more parameters which are listed inside of the pipe characters. For example, let's say we have an array with the values of 1, 2, 3, 4, 5 assigned to a variable called list. So list = [1, 2, 3, 4, 5]. If we wanted to take each value, multiply the value times 8 and output the results, we would do list.each do |number| puts number * 8 end. The number wrapped in the pipes is the argument and we're multiplying the argument times 8 and then printing. You can see it outputs 8, 16, 24, 32, and 40 which is each original number in the list multiplied by 8. We could also write the same thing by doing list.each { |number| puts number * 8 }. All right. So now that we know some of the Ruby programming language, in the next video we are going to get right into it and create our very first Rails application.