00:00:11.830
Good afternoon, everyone. My name is Michael Hartl, and I'm here to talk to you about how to learn enough Ruby. First, let me tell you a little bit about myself. In the Ruby community, I'm probably best known as the author of the Ruby on Rails tutorial.
00:00:30.350
The Ruby on Rails tutorial is a book, a video series, and an online course that teaches how to make professional-grade web applications using Ruby on Rails. It is part of a company called Learn Enough, which I founded a few years ago with a couple of friends. The learning tutorials actually started with the command line, but one of them is "Learn Enough Ruby to Be Dangerous." Today, we're going to take some material from that tutorial and turn it into a presentation.
00:00:56.120
Ruby is a relatively large language, but the good news is that you don't need to learn everything about Ruby to be productive. You only need to learn enough to be dangerous. We won't be covering every detail of Ruby in this 30- to 40-minute talk, so I want to emphasize that you don't need to worry if you're not following everything. This talk is about getting a taste of Ruby and a sense of what it can do, regardless of your current level.
00:01:26.509
We're also going to discuss some of the things that Ruby has in common with other programming languages as well as the features that make Ruby unique. More importantly, I hope to get you excited about what you can do with Ruby. It truly is a beautiful language and allows you to accomplish remarkable things in just a few short minutes. The things we're going to talk about can be divided into three acts.
00:01:52.970
Our first act will focus on Interactive Ruby (IRB), where we'll do something reasonably useful and then encapsulate it into something shareable, packaging it as a Ruby gem. After that, we'll use that gem in a simple web application. Please note that what we're going to do is somewhat dangerous, so it's not recommended to try this at home—this will involve live coding.
00:02:17.540
So, let's start with IRB, which stands for Interactive Ruby. This term was used this morning in the keynote and refers to a Read-Eval-Print Loop (REPL). I'm sure many of you are already familiar with this, but let’s get on the same page by starting with something simple: two plus two. In IRB, when we input this expression, it reads it, evaluates it, and then prints the result. In this case, we get four, and it's a loop because it returns us back to the interactive prompt.
00:02:51.099
Now let's create a variable called 's' and assign it the string "Hello, World!" In Ruby, strings can be defined using double quotes, but single quotes work too. When we evaluate the variable, it simply returns the string itself. If you want to print it for formal ease, you can use `puts s`, which will display it without the quotes, and it will return `nil`, a special Ruby value that represents nothing. This is somewhat unusual, as most programming languages don't have an equivalent.
00:03:12.769
In Ruby, strings are objects, and we can call methods on them. For instance, we can use `s.length` to determine the length of the string. This is useful because the string's length might not be something you can just eyeball. We can also check if a string is empty using the `empty?` method; in Ruby, this is denoted with a question mark. This method returns a boolean value—true or false. For example, applying this method to our string `s` will return false, while applying it to an empty string will return true.
00:04:03.000
One of my favorite operations with strings is to split them into their component parts. We can do this using the `split` method. If we split on a space, it behaves differently than you might expect. It actually splits on whitespace, treating multiple spaces as just one. If you want to split on literal spaces, you need to use a regular expression. This allows you to define exactly how to separate elements in the string.
00:04:35.640
To demonstrate this further, a common challenge I like to tackle in a new programming language is to determine if a string is a palindrome, which means it reads the same forwards and backwards. To accomplish this, we need to reverse the string. While there is a method for this in Ruby, you can also split the string on the empty string to get the individual characters. After splitting, you can reverse the resulting array and then join it back together. Finally, you check if the original string equals this reversed string.
00:05:50.080
In our example, the string `"Hello, World!"` is not a palindrome, but an interesting one to test is `"deified"`. When we implement this test, it does qualify as a palindrome. Unlike many languages, Ruby allows you to reverse a string easily using its built-in capabilities.
00:06:27.300
Next, we want to encapsulate this palindrome-checking logic in a reusable way. We can do this by defining a function that we’ll name `palindrome?`, as it will return true or false. In Ruby, you can define the function using the `def` keyword followed by the name of the function and its argument, which in this case is a string. The return value is implicitly the result of the last expression in the method definition.
00:07:38.800
Next, we should test our new method. Using our example of `"Hello, World!"`, we can assert that it is not a palindrome. When testing `"deified"`, we should find that it is indeed a palindrome. However, let’s consider adding the same functionality to the Ruby string class. In Ruby, you can reopen the string class and add new methods to it directly.
00:08:18.560
We can create a new method called `palindrome?` that can operate directly on string objects. Notice that it doesn’t require an argument; it can refer to itself using the `self` keyword. This allows us to seamlessly test for palindromes on any string. Now that we've packaged our palindrome logic in a method, let’s move to the next act, which is creating a Ruby gem.
00:09:19.290
To create a Ruby gem, we will use a program called Bundler. The command we will use is `bundle gem` followed by the name of our gem, which will be `ruby-conf-palindromes`. Bundler generates the skeleton for the gem, including application code and test code. After navigating into the generated gem directory, we can take a look at what it has prepared for us.
00:09:58.790
Once inside the gem directory, we can see the skeleton structure of a Ruby gem. It provides us with the necessary files, including a spec file for managing tests. Running the test suite immediately will bring up an error, but this is useful feedback, as it indicates that there are aspects we need to specify before publishing this gem.
00:10:44.180
We need to fill in details in the specification file like the homepage URL. After adding a valid example URL, we can run the test suite again. This time the tests run, though they may fail due to the default skeleton setup. At this point, we need to modify the expected assertions in the tests to ensure we see some passing results. This process emphasizes writing tests that pass, so we’ll modify the default test to return true.
00:12:05.579
Next, we can introduce a mini test reporter to improve the display of our results in the terminal. However, installing it requires an internet connection, and as this is a live coding session, we may encounter issues along the way. Without it, we still aim to write our first test to check non-palindromes, but let’s keep the current state in mind.
00:12:54.080
When writing tests, we expect our assertions to check failed cases, such as the string ‘Hello, World!’. This will yield an error since we haven’t yet defined the `palindrome?` method. At this point, we utilize the principles of test-driven development to reintroduce just enough code to allow this test to run correctly. Therefore, we reopen the string class again to add our `palindrome?` method.
00:13:58.270
This time, we need to adjust the implementation slightly to ensure that it only returns nil when there's an empty string. Ruby’s handling of nil values provides a unique case compared to other programming languages, making falsy checks more straightforward. After confirming our function works properly, we will extend the testing further to ensure it catches palindrome cases appropriately.
00:15:21.640
Upon further testing with phrases containing spaces and punctuation, we see a famous one, `"A man, a plan, a canal, Panama!"` Simply checking the string for equality won’t work. Instead, we’ll need to scan for letters using a regular expression that captures all alphabetical characters while ignoring others. We can then join filtered letters and compare that to the reversed string to check for palindrome status.
00:16:48.740
Finally, we proceed to show the application of our gem in a web app context. This will utilize Sinatra, which provides a minimal web framework for Ruby applications allowing easy setups for listening to web requests.
00:17:34.900
In our Sinatra app, we start by defining the routes and associated methods that take user input—specifically the phrase being checked for palindrome status. The input will be accepted from a web form which will result in checking the input string using our previously defined palindrome logic.
00:18:34.760
As we set up the front-end view of our application, we ensure to provide feedback to the user. This includes displaying whether the phrase submitted is a palindrome or not. Any input will be handled gracefully, allowing seamless integration between the various components concerns in our application.
00:19:51.400
After confirming our application logic is functioning correctly, we can expand our application to include additional features or edge case handling like empty strings or phrases with punctuation since they can provide interesting challenges in palindrome logic.
00:20:35.580
In this context, we ensure the empty string is excluded from being treated as a palindrome. By modifying our gem code appropriately and reaffirming the tests are still passing, we maintain our development rigor to keep everything functioning correctly.
00:21:38.420
With the gem now fully functional and the web app operational, we can return and look at the broader perspective of Ruby itself. If you're interested in learning more, resources are available on the website Learn Enough, especially regarding Ruby and web development.
00:22:54.470
This session has provided a remarkable overview of what Ruby can facilitate, and I truly appreciate everyone attending this afternoon. It’s always a pleasure to share insights from RubyConf and meet fellow Ruby enthusiasts.
00:23:22.560
We still have some time for questions, so feel free to ask anything you are curious about, whether it's related to the topics we discussed today or significance within the Ruby community.
00:23:48.950
A question has come in about the phrase 'learning enough to be dangerous.' This phrase has a double meaning: it alludes to the fact that you can indeed be productive without learning every detail about a language.
00:24:10.150
It encourages learners to gain some foundational knowledge to understand concepts and utilize them practically, highlighting the reality that this journey does not require exhaustive expertise.
00:24:49.140
If you have further questions—about Ruby, Rails, or insights on effective learning approaches—I'm here to help you on your journey towards becoming proficient in these technologies.
00:25:15.320
Now, as we conclude, I would like to extend an invitation to tonight’s event at the JW Marriott bar. We will gather for the 10th semiannual Ruby on Rails Tutorial Beer Night—an informal gathering with fellow Ruby developers.
00:25:52.350
The event is very lighthearted, themed around open-source collaboration, and if you're interested, feel free to attend! There is no obligation, but if you enjoy my tutorial and find it useful, buy me a beer!
00:26:48.959
I appreciate your attendance, and it's been wonderful sharing this experience with all of you. Thank you so much for being here!