00:00:06.319
Video equipment rental costs paid for by Peep Code Screencasts.
00:00:19.520
Um, okay. My name is Bruce Williams. I'm going to be talking about the next Ruby, which is Ruby 1.9.
00:00:25.119
First of all, to give you a little bit of background on me, that's my name in big red letters at the top.
00:00:32.640
I live here in Austin, Texas.
00:00:39.440
So, seriously.
00:00:44.800
As you can tell, we have a very large and vibrant Ruby community here.
00:00:50.559
With very small voices, the community here is growing at a pretty good rate.
00:00:56.559
It's nice to have all of you here.
00:01:02.079
So, you know, grab somebody from Austin if you're looking for a good restaurant or a good bar. There's plenty of both.
00:01:09.360
I've been a Rubyist since 2001, back when you didn't make any money doing it, and it was just a lot of fun.
00:01:14.880
Now you can make money doing it, and it's still a lot of fun.
00:01:20.479
So that worked out really well. I'm a language tourist.
00:01:27.040
What I mean by that is I'm a Rubyist by trade and it's my tool of choice, but I play with Erlang, Haskell, and whatever makes sense.
00:01:33.920
Ruby has a long lineage, and we owe a lot to many languages.
00:01:40.560
I think we should float around a bit and take a look at other languages as well.
00:01:46.799
If you had to distill my life into a series of URLs, those would probably be it.
00:01:52.799
That's where I blog when I blog, which is probably not as much as I should.
00:01:58.079
You can find me on GitHub there using my name.
00:02:04.320
I work at a company called Five Runs, which is here.
00:02:11.200
We have the Tune Up and the managed products, which you can see to the right.
00:02:17.760
Basically, I just annoy people and talk about what I'm eating for dinner and things like that.
00:02:24.959
My Twitter, I can't claim there's anything useful that comes out of that.
00:02:32.080
So why Ruby 1.9? Why care about Ruby 1.9?
00:02:37.440
How many people here are using 1.8.6 most of the time (MRI)?
00:02:43.920
Okay, keep your hands up. Now, if you're using 1.8.7, keep your hands up.
00:02:51.480
How about 1.9? How about 1.9 in production?
00:02:58.080
Dave, you don't count; you're an early, early adopter.
00:03:05.040
Actually, recently, oh yeah, okay Dave, I guess you do count, but only because you paid.
00:03:12.959
Ruby 1.9 recently did a poll; I don't know if any of you took part in it.
00:03:20.000
They found a pretty good percentage of people—about 10 to 15 percent—last time I looked.
00:03:25.040
Now the poll is gone, so I can't find it, which is perfect for me because I'm speaking about it today.
00:03:31.599
About 10 or 15 percent are using Ruby 1.9 on a regular basis.
00:03:37.840
Thinking back a little bit, Ruby 1.9 reminds me a lot of Ruby 1.7.
00:03:43.840
Back when everybody was using 1.8.6, there was 1.8.7, and people played in the world of 1.7 before 1.8 came out.
00:03:51.200
It's a little bit different now because people have businesses that rely on 1.8.
00:03:56.319
They're a little less willing to go forward willy-nilly and grab stuff because we're very much into robust enterprise software in this community.
00:04:03.840
However, Ruby 1.9 does a lot of good things for us.
00:04:09.280
We get a whole bunch of new syntax and language features.
00:04:14.560
As the next version, it's not strictly backwards compatible with 1.8.
00:04:21.040
There are definitely some issues when you're migrating code, which I'm going to discuss.
00:04:26.240
It definitely has better performance characteristics.
00:04:33.040
And of course, it has more bugs; that's just the way software works.
00:04:39.680
Although, it's probably easier to maintain these days.
00:04:45.199
What I am going to talk about is the new syntax and language features because that's what I really enjoy.
00:04:51.280
I am going to talk about migrating stuff over; I'm not going to talk about performance.
00:04:58.000
That's something that you can find loads of numbers about from the people who are far smarter than me.
00:05:03.040
1.9, as a whole, is much, much faster than MRI 1.8.
00:05:08.560
I'm not going to talk about the bugs that exist besides the ones that have immediately popped up to me.
00:05:14.240
Because I'm not psychic, I don't know where they are.
00:05:20.400
If I were, I would be helping Mats fix them, but that's not the case.
00:05:26.400
So, still on the thread of things I'm not going to talk about: I'm not going to talk about the other implementations of Ruby.
00:05:32.639
Most of which target 1.8, anyway, with the exception of Mac Ruby, which has the benefit of sitting on top of 1.9.
00:05:39.760
I'm going to be talking about YAR, so Yet Another Ruby.
00:05:46.800
Just the plain vanilla Ruby. Not that I'm not excited about those other implementations.
00:05:53.520
So clearly, don't go out and grab 1.9 right now; this is where you would go to grab it.
00:06:00.000
Ruby 1.9 is in Subversion these days. I think 1.8 is a branch as well that you can track.
00:06:06.960
It's a version if you want to get it; it's still changing on a regular basis.
00:06:12.240
Certainly more stable than it used to be.
00:06:15.840
The klaxon I guess was because it used to be very unstable.
00:06:22.080
You can get 1.9 directly from the downloads page or from Subversion, and that's essentially how you build it.
00:06:27.440
Make sure you build it with some type of program suffix or something like that so you don't get confused about what Ruby is on your system.
00:06:35.759
I use 1.9 as mine.
00:06:41.759
A little bit about the standard library: I apologize for this being a little out of date.
00:06:46.800
I've done this version of this talk a couple of times and this one didn't get updated very well.
00:06:52.640
So there may be some stuff here that is different, but in general what you have is RubyGems.
00:06:59.919
They are now part of the standard library. They're built-in Solar, Rake, JSON, Ripper, etc.
00:07:05.919
Some of these may seem a little crazy; you may not know what profiler is, for instance.
00:07:13.120
Secure Random for those of you that are Sran users is for you if you really want random.
00:07:19.840
Here's one for you to look at, and of course the HMAC digests.
00:07:25.120
CSV was replaced by the faster CSV implementation, which I believe we have someone to thank for.
00:07:31.200
That's a vast improvement, and in things that have disappeared, at least the last time I looked, SOAP, Wisdom and Base64 were removed.
00:07:36.800
So for Base64, you're going to take a look at pack and unpack.
00:07:42.800
Now we're going to talk about risk factors: parts of your code that you're going to have a problem converting over to 1.9.
00:07:49.760
Because you're going to do it eventually, and you should at least be looking at it.
00:07:56.480
The first thing I’ll say is that you need tests.
00:08:02.160
If you don't have tests now on your code, first of all, you should have tests on your code.
00:08:10.080
You have to have tests because people at conferences will annoy you to death if you don't.
00:08:16.640
VDD, BDD, BDD; that needs to be said at least three times in every talk.
00:08:22.800
Because it's new and cool and life-changing.
00:08:28.160
Actually, yeah, I like it as a concept, just not as a buzzword.
00:08:34.080
So yeah, write tests! James Edward Gray had a great quote in a Ruby talk thread many months ago.
00:08:40.160
He talked about when he was switching over Faster CSV to 1.9.
00:08:46.639
He talked about the fact that there are a lot of issues you didn't realize that were there.
00:08:53.680
Your tests really helped him find them.
00:08:59.680
That's something I keep coming back to when I've been converting some code over.
00:09:05.760
If I didn't have my tests, it would be a lot harder to find these things.
00:09:10.480
With Ruby, obviously, you're not going to find some bugs unless some branches of code are being executed.
00:09:16.160
So the idea is to get those branches to execute, and tests are the way to do that.
00:09:22.720
This is a really big change in 1.9: text processing.
00:09:28.639
If you're writing parsers, Faster CSV is a good example of this kind of stuff.
00:09:35.039
Regal parsers for instance, and Hpricot and Mongrel, etc., are good examples.
00:09:42.160
You've got the issue now where we have new encoding support.
00:09:48.560
Now when you're using the string sub-method and indexing into a string with a single index, you're going to get a character back.
00:09:55.039
You're not going to get a number back, which is what most of us expected.
00:10:00.480
That’s a thing we’ve brought up for years: yeah, when you index into a string, you get back a number.
00:10:06.000
So that's gone now; we don't have to have that conversation with people.
00:10:13.120
We need to convert over the code that relies on it.
00:10:19.760
Now you can actually manage different encodings for your actual source files.
00:10:25.679
This is kind of cool.
00:10:31.840
Thank you very much. I wonder who that is? I have a wife and two kids, and it's during my talk.
00:10:37.680
That's okay.
00:10:44.000
Okay, where was I? Thank you, dear.
00:10:49.280
Yes, encodings: we have these new encoding conventions, that's kind of an extra feature.
00:10:55.680
You certainly do need to know about string, ord, and various unpack methods.
00:11:02.080
Be familiar with unpack in general, and pack as well. They're very powerful.
00:11:07.680
Now we'll look at some examples of changes in Ruby 1.8 and Ruby 1.9.
00:11:12.800
Generally, in Ruby 1.8 to get what you see in Ruby 1.9, you do something like 0.1 or 0, 1.
00:11:20.000
A major difference there is that it's not backward compatible at all.
00:11:26.000
The recommended approach for instance, for those doing regal parsers is to unpack your string into numbers.
00:11:31.200
You can either convert one way or the other or use character or to pull stuff out.
00:11:38.000
Next, pulling the same kind of stuff out on the left-hand side, I'm only pulling out bytes.
00:11:44.480
So it doesn't really work nicely for me. But on the right-hand side, it actually pulls out the multi-byte character, which is nice.
00:11:50.800
This is obviously using some encoding trickery.
00:11:57.600
Now granted, actually typing this in TextMate with bi-directional text and trying to put an index on the end was a complete nightmare.
00:12:04.160
So I’ve taken the string and then taken the thing next to it and sat it down.
00:12:10.080
It looks like it should. TextMate gets a little confused by bi-directional.
00:12:16.000
For those of you who are dying to type Arabic, your time isn't here yet.
00:12:23.840
You see some unpacked stuff here with actually pulling out the Unicode multi-byte.
00:12:30.000
You know; use ri unpack to see all the crazy options.
00:12:36.000
If you do C-star, you get a bunch of crazy negatives for the Arabic word, so that's not very helpful.
00:12:41.920
Now this is another point: this should only affect you if you're insane.
00:12:48.680
There's this really neat trick, very clever, I always put clever in quotes.
00:12:55.040
Because it’s a synonym for stupid.
00:13:01.760
This kind of stuff, usually a bug, is when someone hasn't realized they're accidentally assigning to a variable that's outside the scope using a block argument.
00:13:08.000
You see some people do crazy things, like assigning an instance variable inside a block.
00:13:15.760
This shouldn't exist in any code you ever show anybody else.
00:13:22.320
And you see the output difference here; the very last loop is going to assign the last yield.
00:13:30.720
The block variable won't take place here; it’s going to shadow it.
00:13:37.120
It'll warn you if you're using Ruby -w, which you should be.
00:13:42.960
So you're going to want to name your variables in your blocks something different.
00:13:48.560
If there's anything here that...
00:13:54.000
So in a solution, just don't do that.
00:14:01.200
We're not going to talk about arrow lambdas just yet.
00:14:07.360
There's a way of declaring a variable as local so that you can use it inside without assigning outside.
00:14:13.680
Just pretend that little arrow is the lambda.
00:14:19.680
Inside of it, you can see you're reassigning d, but on the right side, you aren't because you're declaring it local.
00:14:26.160
But you will still get the shadow warning.
00:14:33.920
This is kind of cool; the principle of least surprises has changed.
00:14:40.960
Hash select now returns hashes, which is nice.
00:14:47.360
You don't get an array of arrays, which I used to just flatten and splat to a hash.
00:14:54.000
So you're creating an array and making a hash, which follows the principle that when you do a select it should return a hash.
00:15:01.200
You probably could remove code to migrate this code since you're generating a hash again.
00:15:08.000
You might be expecting arrays back and doing other things with it, so be careful.
00:15:14.160
You see, if you had a hash called conferences, you could select on it and pull stuff out.
00:15:20.560
Another issue is that the array does matter on select.
00:15:27.120
In the past, with one block argument, it would get both the key and value assigned.
00:15:34.000
Nowadays, it looks out.
00:15:40.000
So Sam Ruby actually originally did this talk at Scotland on Rails in Edinburgh.
00:15:44.640
That's another regional conference across the ocean.
00:15:50.160
I put out a PDF, and people looked at it on Ruby Inside.
00:15:55.680
Sam Ruby recently came out and did another talk; he's much more focused on string encoding.
00:16:02.080
This is a really good point he made: one of the main obstacles for us to decide if 1.9 is cool.
00:16:08.560
Especially in production applications, is the fact that we have all these gems.
00:16:15.680
It’s not like we're Red Hat Enterprise Linux where we have some kind of idea of maintenance status.
00:16:22.160
These gems are just sitting around; they might have 1.8 code that's not compatible.
00:16:28.960
If you get 1.9, install some gems, and some of your dependencies aren't working right, that's a real problem.
00:16:36.880
As a community, we need to do something about that.
00:16:41.680
We need to identify these gems.
00:16:48.560
Certain gems, for instance Rails, run fine on 1.9.
00:16:55.680
The dependencies run fine on 1.9.
00:17:01.760
What 37 Signals is using probably runs fine on 1.9.
00:17:07.680
That's great, but there's a lot of other stuff that you may be using.
00:17:13.920
Maybe you have some crazy list of gems that nobody outside your industry uses.
00:17:19.200
You're going to need to do something about that if you want to continue to use your software with 1.9.
00:17:24.400
So there's no easy solutions there.
00:17:31.760
Now, new features: let's talk a little bit about the mostly syntax changes.
00:17:37.200
Some of the encoding changes I don't want to go too deep into.
00:17:42.560
M17N—obviously, there's a lot.
00:17:48.560
I try not to put a lot of text on the slide, but here it is.
00:17:54.000
The main points here are that strings have encodings nowadays.
00:18:01.200
Your source files can actually have an encoding.
00:18:07.040
You can read things in encodings.
00:18:14.080
That encoding affects a lot of things: regular expressions, various methods on strings.
00:18:21.840
You can't just do .each on strings these days.
00:18:27.520
You have to iterate over characters in each line and each byte.
00:18:33.760
You can examine what the encoding is on the string; you also have different ways of setting what your encoding is.
00:18:40.000
You can use command line stuff from Ruby and also magic comments.
00:18:47.360
If you have the Emacs style comment because you're using X, you can use those.
00:18:54.000
I'm sure there's something for Vim as well.
00:19:01.760
If you're using TextMate, whatever else—there are basic versions that don't give hints.
00:19:08.640
Obviously, I already talked to you a bit about string sub and how to pull stuff out of a string.
00:19:14.000
It supports a lot of different encodings; this was a complete list a few months ago.
00:19:21.120
It might be different nowadays; it's just a lot of stuff here.
00:19:28.720
UTF-8 is obviously the big one for most people that want to do surface languages.
00:19:35.600
Being able to pull stuff out of files and do I/O stuff with different encodings—that is now possible directly.
00:19:42.000
You notice in the second example I'm using an open version of the new hash with a symbol.
00:19:48.560
It reminds you a little bit of keyword arguments, probably, or maybe a little bit of JSON.
00:19:54.240
This is a really, really cool feature.
00:19:59.680
It's one of the features that checks off that enterprise box that people pass around.
00:20:06.080
This is a good thing; it's something people complain about a lot.
00:20:12.000
We don't have support for Unicode, etc., and that’s been a valid concern for years.
00:20:19.360
It's been worked on, and we're going to continue to work on it.
00:20:26.160
This is really cool because if you're a text-processing person like I am, having good regular expressions is really important.
00:20:32.080
One of my main reasons for switching from Python to Ruby years ago was that Ruby's regular expressions were much more natural.
00:20:38.240
But it was missing some really, really cool features from newer regular expression engines.
00:20:45.440
Now, Oniguruma has been integrated into Ruby 1.9.
00:20:51.840
It provides cool things like named grouping, various look-aheads, and look-behinds.
00:20:57.920
It also supports encodings, which is obviously an important feature.
00:21:04.000
There are some differences with enumerables and the enumerators.
00:21:10.320
In Ruby 1.8, you have to require enumerators.
00:21:17.680
In 1.9, all enumerable methods will return an enumerator.
00:21:22.640
You can call next on that enumerator.
00:21:29.360
You can stop complaining about not having hash each with index.
00:21:38.560
This has been a constant complaint for years.
00:21:45.760
Now you have it; you can even add your own crazy things onto an enumerator if you like.
00:21:51.760
However, this does change things like each with index, so you have to be aware.
00:21:58.560
Dot instead of underscore. If you use RSpec, you're going to be confused where to use a dot and an underscore.
00:22:04.000
You'll probably figure it out just fine.
00:22:10.720
In enumerables, there are some other cool things you can do.
00:22:16.400
You’re familiar with symbols of Proc from Rails.
00:22:22.480
That's now in 1.9. Some like it, others don't—that depends on who you ask.
00:22:28.800
There's also something reduce, which is essentially the same as inject.
00:22:35.120
You can pass it either a symbol or a symbol to proc.
00:22:41.840
It flattens things down; you can think of this like dot sum.
00:22:47.680
There's lots of methods on enumerable that make sense to take a look at.
00:22:53.840
Some of which are here: cool things like take and group.
00:22:59.040
Group is now part of Ruby, which is nice.
00:23:05.440
Back in the old days, you only had sort, then got sort by, and now you have min by and max by.
00:23:11.680
You can do count, which I believe is essentially dot size.
00:23:17.760
So there are new features; we got take and drop, a way to quickly grab something out.
00:23:23.040
Hash changes: at least the last time I checked, hashes track their insertion order.
00:23:30.240
You can actually go over a hash in the order things were inserted.
00:23:36.320
This is probably familiar to those using PHP with associative arrays.
00:23:43.680
Now, you can see I'm putting stuff in, taking stuff out, and what you're putting in is staying ordered.
00:23:50.720
Tap is a little thing on an object; if you're familiar with Active Support, this is similar.
00:23:58.000
This is very similar to returning, and some say it's not great for performance.
00:24:04.880
Just be aware it's there, and it's kind of neat.
00:24:10.000
What it's doing is passing itself to that block; you can do stuff with that block.
00:24:15.680
This is kind of cool, especially for things where you're fiddling with an object in a method.
00:24:22.560
Returning that object back means you want the scope to be explicit.
00:24:28.960
This is probably the thing when people think of 1.9; it’s the new proc literal.
00:24:35.040
Forgive me if I use the words proc and lambda interchangeably, as they are interchangeable for me.
00:24:42.320
The main thing here is we actually now have something built into the parser.
00:24:48.640
It's flexible compared to using the goal marker type.
00:24:55.200
You can pass blocks to them; it's great.
00:25:01.520
You can also do things like default arguments, which is nice.
00:25:08.720
Also, you can declare things as local variables, which is experimental.
00:25:16.080
I thought I had another slide, but I guess I don't.
00:25:23.440
So simple changes: we’ve got proc; like I mentioned, there’s less sibling rivalry.
00:25:29.920
You know that Rails created this idea of using symbols for keys in hashes, etc.
00:25:37.440
Stuff coming in from parameters were strings.
00:25:43.920
You check them out; especially when you were indexing, it would all fall over.
00:25:49.760
Now you can actually pretend to be a string in certain ways.
00:25:56.560
I know the idea of symbols being frozen strings was flirted with.
00:26:01.920
That was removed due to performance concerns.
00:26:08.080
But now they pretend to be the same, though you can't use = to check them.
00:26:14.160
That would be a bit too much.
00:26:20.000
But triple equals works, so case statements work.
00:26:26.080
Threads have moved to a native threading model from a user threading model.
00:26:33.440
There are actually three different models if you open up thread.c.
00:26:39.760
You do things like that for some reason, like reading through C code.
00:26:45.680
One is user threads, one is native threads with a giant VM lock, and one with finer grain locks.
00:26:52.000
The one built-in now, I believe, is model 2.
00:26:58.560
I don’t read a lot of C in my leisure time.
00:27:05.760
Also, I’m not a VM guy, so I haven't dug in deep.
00:27:10.640
When 1.9 comes out, hopefully this Christmas, we’ll have all the locks down.
00:27:16.560
This is cool; it's nice to run Ruby, kick off a bunch of threads.
00:27:23.680
Performance should be much better; you can look at Top and see the thread count.
00:27:32.000
This has been another checkbox we needed.
00:27:37.040
Especially for people coming from the Java world, this is something they absolutely needed.
00:27:42.720
It's been something that has kind of hounded us.
00:27:47.680
Fibers are essentially semi-coroutines.
00:27:54.640
You can think of them as lightweight, user-level threads.
00:28:00.320
They're manually scheduled.
00:28:06.000
They're kind of neat, especially for I/O frameworks.
00:28:12.640
But this isn't something I generally do.
00:28:18.280
There are good blog entries to read on fibers.
00:28:25.760
Dave has a really good series of articles on fibers.
00:28:31.680
We're going to go into questions. We have about 15 minutes.
00:28:44.960
So questions?
00:28:50.560
I don’t think I can explain the history behind the tap method.
00:28:56.960
Mats may be willing to talk about that later.
00:29:02.560
The tap method seems to owe a bit of debt to returning.
00:29:07.840
So there seems to be that connection.
00:29:13.440
That reminds me of Smalltalk semicolons for chaining.
00:29:20.960
If you can put that up there, you can chain things onto the same object.
00:29:27.280
I can't say specifically why it's called tap. Maybe tapping into the chain?
00:29:33.040
It also reminded me of jQuery if I can go back but in a less gross manner.
00:29:41.760
I really like jQuery.
00:29:49.040
I can’t tell you the etymology of it, but from a usability perspective it owes a lot to returning.
00:29:55.200
There’s a good subset of people in the Rails community that use returning as a pattern.
00:30:02.480
So, yes?
00:30:09.040
Just give us your personal opinions on the changes that happened to lambda.
00:30:14.960
At first, I really hated it.
00:30:22.880
Partially because I’ve used Ruby long enough, seeing any change can be scary.
00:30:29.760
But I love lambdas; it’s my background.
00:30:36.560
At first, it took me back because it felt like a step away from clarity.
00:30:43.520
But knowing all the new, cool things means that there will be great use cases.
00:30:49.680
I'm hoping the Ruby community self-regulates with all this.
00:30:55.760
We can create a schedule of punishments for horrible lambdas.
00:31:01.960
I have disliked making things as obscure as possible to read.
00:31:07.840
I love elegant code.
00:31:13.920
The utility is also pretty significant.
00:31:20.960
One point I want to stress is that the syntax may feel less clear.
00:31:26.280
So, it’s okay to let it sit for a bit.
00:31:32.000
You can play with it; you might feel more comfortable after a while.
00:31:39.040
Does that kind of answer your question?
00:31:44.640
I think I do have time for two more questions.
00:31:49.440
Okay, so do we have another question?
00:31:57.520
If not, thanks for your time, and thank you Mats for being here.
00:32:03.040
Video equipment rental costs paid for by Peep Code Screencasts.