 This is unprecedented. I have more time than I expected. It's usually the other way around. Luckily, I have about 90 slides, so I think that I can fill it hopefully. My name is Ola Bini. I work for ThoughtWorks. I'm a consultant. I've actually spent the last six months in a legacy Java project, so it's really fantastic to be back in Adobe Crowd again. It's been a bit of hell. Anyway, so I've been involved in... Well, Java is not that bad always, but in this case it's been very bad. You probably know about JRuby at this point. That's kind of where I've done most of my open source work. I'm one of the core developers for JRuby, so I do a lot of Java, but I do Java so that you don't have to, basically. In the course of working on JRuby, I found stuff, and some of the stuff you probably have encountered and some of it you probably haven't. It's funny. Ruby is a big language. If you start looking at it, the only way Ruby could be bigger is if you had a static type system, because that tends to kind of inflate the size of the language. But Ruby is probably... Well, it's not as big as Perl, but it's big. So I wish to just look at some features that Ruby had that you might not know about, and I might want to talk a little bit about whether you should be using them or whether you should not be using them. Hopefully, there will be something new for everyone in here, but I can't guarantee that you haven't seen everything in here. So I'm going to be talking about regular expressions and strings a little bit. I'm going to be talking about Proxon blocks, expressions and operators, a little bit of collections, and a little bit of loading. So the biggest section here is regular expressions and strings, and obviously you have used these features of Ruby. How many people know that you can write comments inside of regular expressions? You do it like this. You use the regular comment operator, and everything inside of there will just be completely ignored. You can also use the X flag in a regular expression, and that means that all of the white space will be ignored. And comments in Ruby count as white space, so you can actually lay out your regular expression like this, and the comments will be also ignored. And if you actually want to match something inside of it, you can use slash s to match it, or you can use slash blank, and that will match it. The extended flag is quite nice to make it possible to lay out regular expressions in a way that makes them a little bit more readable. And you can use it if you don't want to do other ways of putting together regular expressions. Martin Fowler has advised that instead of putting together a regular expression like this in one big chunk, you should just dividing up in small, small pieces that you can name and then put together instead. In general cases, I actually like that better, but using the extended flag for white space formatting is a great aid for readability. A one-nine feature that I like a lot is this, where you can actually use name groups instead of referring to things using numbers. So here we give names, and then we match specific numbers. Notice that I'm also using the X flag to make the layout a little bit better. And then we can refer to it using the square bracket syntax. You can also refer to these name groups in the local context with local variables of the same names if you want to. So basically, you can use them in all the places where you can use group indices. You can use it in Oniguruma, if you had that in one night. And it always increases readability. In fact, I would really hope that using indices for regular expressions stopped being used at all. Another feature of springs that I don't see used a lot is this feature that allows you to use regular expression capture inside the square brackets. Where basically, you can just give a regular expression and ask for the match. And you can give it a regular expression that has a little bit more complicated. And it returns nil if it can't match. You can also match groups using this feature. So you can extract a specific group at the same time and you will just get nil if you don't do it. And most of the cases where people use the global variables, stuff like $1 and so on, can usually be replaced by this kind of feature in a much cleaner way. The only thing you can't do, as far as I know at least, you can't match more than one group and get that back. That's something that I've been missing in some cases where you want to match two different groups and want to get that back. In that case, you can instead use the match method on regular expressions instead. So this is a great date for readability of regular expressions. And most regular expression usages in open source code is something that can be replaced by this. So you can also use the symbols to extract the name groups in these cases. And yeah, it's actually a no-brainer to use it. Ruby has a lot of string support. We all know this version of strings. We know about this, no interpolation here. We probably know about the percent sign. But did you know that you can do this where the matching of parentheses actually work out? So this string is a valid string and will contain the two inner parentheses. This works for square brackets. It works for angle brackets. But you can also use basically any other null alpha character to delimit strings like this. You can also add a queue. Lowercase queue will be without interpolation, but it will still use the matching. So you can use the curly braces inside of it. If you use uppercase queue, you can do interpolation. If you use s in front of it, you can do symbols. And the same feature of matching up of angle brackets and square brackets and so on works fine here. So you can create a symbol that have a matching pair of angle brackets by just putting that inside of it. Same thing works for x for doing execution. The same thing works if you do w for word creation. You can actually create words that contain square brackets. For example, if you were to put square brackets around the word two, that would be part of the word that gets created. If you have uppercase w, you get interpolation. Regular expressions work roughly the same way. You have to use the R, but after that you can also use all the matching braces like this. For some instance, there is no way of doing a capital R. The lowercase r actually gives interpolation directly, but you can't. There is no symmetry in lowercase r and uppercase r. Basically, string can be delimited with double quotes, single quotes, and many versions with the parenthesis. Almost any non-alpha numeric can be used before and after, but the matching braces are treated specially. You can use several characters in between, so you can use lowercase q for non-interpolation, uppercase q for interpolation as the default. You can use s for creating symbols, w for area words, uppercase w for area words with interpolation, and x for another version of backtake. Present r and the same kind of delimiters as string can be used to allow regular expression creation. In most cases, I would recommend against using these. It's very, very seldom I've seen the need for them, and the fact that they're there at all in many of these cases, I had no idea about the simple creation, for example. But in some cases, they will make stuff more readable. So if you have a case like this, you can replace it with something like parenthesis, for example, or regular expression that matches lots of slashes. In almost all cases, in local source code, I've seen square brackets being used for that, so I've considered that the most idiomatic use. But in any case, it kind of depends on what the string contains, and using the regular string single and double quotes is almost always the best choice. Prox and blocks have also changed a lot in Ruby 1.9, and I'm going to talk a little bit about one change. But for that, at this point, almost everyone knows about the two-prox trick, so I'm not going to spend much time on it. Basically, it works by using the ampersand. The ampersand will make sure that whatever is on the right-hand side of it will call, Ruby interpreter will call two-prox on that thing if it's not already something that is a block. And that will out-occur something into a proc, if that's sent in, if you add that symbol. The same approach can be used with other Ruby objects. I've seen open source projects that create a small interpolation language, just in strings and turn them into procs, for example. What would a two-prox on a regular expression do? I have no idea. It's a good pattern in terms of making symbols and operations with symbols a little bit more readable. It removes lots of duplication in many of the common cases. However, there is a performance cost to doing it, so keep that in mind. Another trick that I like a lot is the overriding of the triple equals. Specifically, if you combine that with a proc. In this case, the case statement will call triple equals, and we have a method that generates procs on the fly, and proc has a triple equals that uses the double bang to call itself and then turn that into a Boolean result, and then evenly divisible with returns of proc on the fly. Case statements always call triple equals, so you can use that, and you can encode some pretty nice stuff and create some DSLs using this approach. Triple equals is already defined in many places, though, so it's a good thing to know about real expressions, ranges, classes, modules, strings, and symbols. In general, you hide a lot of cost when you do things like this, so it's something that you should do at the upper levels in domain-specific languages, but in general, the further down the stack you get, the more cost you will be encoding and hiding by doing it, but it's a good feature to know about, and the general triple equals trick is quite useful to know about. In many cases, Ruby hides a lot of operations like this that it does for you on the fly. For example, another thing that I'm not going to be talking about, but if you use binary operations, there is a coercion protocol that allows you to actually hook into how Ruby coerces one number into another type of number to make it match up for a binary operation, and you can hook into this if you want to. So Ruby has three ways of creating blocks. Well, actually, I should have included stabby lambda, but stabby lambda, if I remember correctly, does the same thing as the lambda keyword. Now, if you look at, this is Ruby 1.8, and what this one does is that lambda and proc lowercase both the return keyword will return from inside of the block. However, using proc.new will return from the full method, and that's what you can see down here. In Ruby 1.9, lowercase proc do the same thing as uppercase proc.new. Now, this behavior is something that is a little bit unintuitive in some cases. There is a very good reason for having it like this, though. Basically, in the implementations, blocks reified with proc lambda have a flag called lambda, which is whether they had this lambda feature, and the way they work is more like internal methods. What that means is that the return statement will return from the block itself instead of returning from the closing method. Now, when you use blocks, when you send in a block to the each method, for example, use return, return will return from the enclosing method, and that's almost always what you want. A lexical return is what that's called. That's almost always what you want when you actually use the block features, but when you say the way a block for later usage, in many cases, you might when I'm able to use it like it can return from itself instead. One specific case where this is really useful is if you use define method. When you do define method, you definitely want the return keyword to work like you would expect it to do. This is one of those features that is there. Most people don't really remember exactly the cases. I had to go back and run all the examples again to remember exactly what it actually does, but be mindful of the difference because there is a difference here. So one of my absolute favorite examples of a feature that I don't like in Ruby is something called a flip-flop operator. What the flip-flop operator does is that it basically keeps track of the state of itself. It roughly does the same thing as having a boolean flag inside of it saying whether it's turned on or not. So in this code example, we have an X statement here. The flip-flop operator here masquerades at the two dots that kind of look like a range operator. The way we can see that this is a flip-flop operator is because the end points are actually boolean expressions or semi-boolean expressions. Now what the flip-flop operator will do is that the first time it encounters this, it will evaluate the left point and it will return false for this expression until the first time this expression returns something that is truthy. And at that point, this whole expression will continue to return true and evaluate the second expression until this expression returns true and then it will turn off again. So it will basically turn on and off between two different states and it will evaluate either the left hand or the right hand expression depending on whether it's on state or off state. So in this case here, I'm parsing the input that looks like it could come from a C file and try to extract all the macros. Or all the if-defs, sorry. This feature is an interesting one. In fact, it turns out that it was broken in JVB for about two years. It was so broken that it threw a null pointer exception if you actually executed that expression and this was when JVB was starting to get C use. So as far as I can tell, no one was actually using it because it took so long time for us to actually figure out that it was broken. In general, this is an interesting feature for one-liners. It's one of those pearl heritage things that is really useful for short throw away scripts. You can do one-liners that are quite useful with it. But in general, I don't want to really see it in production code. This one is also funny. Let's see. This is a little bit tricky to explain what goes on. In terms of Ruby implementations, there are two different super implementations. There's one super call that is just the regular super call, but there's another super call that is called said super in the Ruby implementations. What we see here is said super. This is one of those few cases where it actually makes a difference whether you have parentheses or not. Said super is the super key with no arguments and no parentheses. Otherwise, it's a regular super keyword. This code has a super class called A. I meant to call foo. It takes three arguments and prints them. It then does a subclass of A, overrides foo, splats the arguments, sets the third element to a specific value, and then calls said super. Now, in the first case here, this will actually print one, two, 42. The second case will print one, nil, 42. And why it does this is because it seems like these splatted arguments here actually points to the same memory area that Ruby uses to send along the arguments to the super method. This looks like a bug. I was sure it was a bug because we found this example in JRuby once again by basically this was not working as the Ruby implementation did it. And we were sure this was a bug until we decided to not fix it and we ran some of the core libraries. And it turns out that there are core libraries that depend on this behavior. So that also means you can do things like this. If you add to the splatted orcs list an element and you call it correctly down here, one, two, three, this will actually raise an exception because it got too many arguments. This is one of those interesting features that if I ever see you use it, you are not on my team anymore. But it's used in the standard library so we had to implement it correctly. As far as I know, this is actually encoded in the Ruby specs. Please don't use it. If you ever want to see funny code or interesting code that uses clever Ruby tricks, I would say go look at the source code for camping. And in fact, you can look at both the expanded code and the small code. The small code uses some tricks that are very clever and very interesting, but the expanded code also do some really nice things. One of my favorite DSL things is this way of using a superclass or an expression in a superclass point. So you can actually generate new classes on the fly here if you feel like it. This just calls the method matcher. Matcher will generate the new class on the fly that matches the specific regular expression given and then inherit from that. Now, you've probably seen this behavior all the time because it's really idiomatic to use that when creating new structures. So you say inherit from struct.new. But you can actually put anything you feel like in that position. So you can generate a class on the fly. You can inherit it from it. And this struct idiom is probably the only place where I expect people to see it. But it's a nice way of creating good DSLs. So something uses it to on the fly create routes and inherit from them to tie them to actions. One of those things that I have a problem with in Ruby is that I actually sometimes kind of care if I'm giving an argument or not. So what's the difference? If I have a default argument like this, I can't see the difference between a nil that's given or a nil that's not given. It's not very common to care about this, but it could happen. There is actually a way of handling this case. And the solution kind of looks like this. What you do in the place where you define the... I think it dropped my... I don't think this was a very good idea. Let's see. Okay, I'm back. So basically, you put some code in the evaluation of the default case here. And that code will only be evaluated when the default case is taken. And since you can actually create a new variable here, you can say that flux default equals true is actually something that only is going to happen if the default case is taken. So if someone sends in a nil, that will not be taken. So there is no real way of distinguishing between these cases, but you can do things when you evaluate arguments. In fact, you can put any code you want into that position. You can define new methods. I've seen that done. You can define new classes. You can replace the whole currently running program. I don't know if that's useful, but you can send all the missiles and... Yeah. As far as I know, there is only one language that has a feature built in, and that's common lisp with C loss. We keep coming back to lisp. You should really not use this feature, except if you really want to and need to. But it's... Yeah. It can be useful occasionally. I guess this talk is not really about useful stuff. It's more about fun stuff. But now the collection stuff... I don't know. There are a lot of things where, maybe I'm going to be blaming all of you for being ignorant about these things, and all of you already know all of these things. However, in open source code and in production code, people don't know the innumerable APIs well enough. And I guess my message here is just use the innumerable APIs because they are really quite useful. And everything you might want to do is there. Sipping is really quite useful. All, any, none, one. Each cons, really, really useful. Each slice. Or max, pi. There are lots and lots of useful innumerable methods. And in many cases, people just sit down and write out stuff, and it's so easy to write these things in Ruby, so people have a tendency to just rewrite them over and over again. So if you don't know them all by heart, you will duplicate the logic, probably badly. Most of them take a block. Actually, most of them are even better at taking a block in 1.9 than they were before. You should use them all the time. It's funny, though. There is one method that's missing in innumerable, and I haven't gone around to submit a patch to it, and that's Flatmap. I don't know why no one else has a use for it, but it's very, very useful. That brings me to one case, which I don't have covered, actually. How many people have tried to include a module into innumerable and been surprised when that doesn't work? I get surprised every time because I try to add features to innumerable using another module because that's the way you should be adding stuff to other things, and it never works, and I keep coming back to it. You can't add a module to another module and expect all the including classes to have access to that behavior. It's very surprising behavior to me, and I keep forgetting about it. Anyway, lazy innumerables. We have this all over the place in Ruby 1.9, and it's also one of those things that is just very, very convenient to have. Basically, all innumerable methods, almost all, that take a block will return an innumerator if not given a block. An innumerator is innumerable, so you can do it recursively. You can combine them and you can chain them. Yeah, no real question about it. There are some old-school Ruby tricks that people don't really know about. This one, for example, is very common in the standard library, and the basic idea is that you can put stuff, anything, in a Ruby file, after the double underscore end bar. It's called a data segment, and you can automatically get access to it using the global constant data. You can read from it because it's an IO-like object. Many old libraries use this way to put their own test cases inside of the file itself. They put test cases as a separate Ruby file inside of the same file, and then if you run that file as the main program, it will execute the test cases as the main program. So you can end a Ruby file with this symbol, and everything after it will not be evaluated, so you can store anything there. You can put pictures there if you want to. And there's an IO object available. So this pattern is what you might see if you look in the standard library, where you evaluate data if the currently running file is the program. Oh, it can be useful in some cases. If you have large amounts of data, that is really, really part of the file itself. Sorry. Dollar, double quote. Loaded features allow you to see what's been loaded in the system. So you can ask, okay, which features have been loaded, but you can also do something really quite interesting. You can actually add strings to it, and if you do a require on that string afterwards, it will look to the Ruby system as if you've already added or required that file. So say, for example, you don't want to install a dependency. Say, for example, that you're trying to run without Ruby gems. You can actually add Ruby gems to a list of loaded features, and Ruby will think that it's already loaded Ruby gems. Now, this can cause all kinds of havoc, but it's also been occasionally useful if you want to fake out loading dependencies and so on. So this is a way of hooking into the basic part of the require framework of Ruby. And for God's sake, please don't use the short form. Use the long form. And that goes for all of these things. Use the English names, please. A useful tool for debugging. It's probably not something for your production code. So there are many things that I haven't talked about. I haven't talked about all the globals, for example. There are many of those. I haven't talked about taint and save levels. I haven't talked about all the hook methods, the meta-programming stuff. There are many regular expression flags. How many here knows what the O regular expression flag does? Exactly. Compile ones. But there are a few other ones that are quite useful. Here knows have much more features than I thought when I started looking at them. You can use Emacs style literals for characters in Ruby. All Emacs people. That's like three or four people, but... It is really two languages. It's Ruby, and it's the language that you can use inside of the defined keyword. I haven't really talked about that either. I did talk quickly about the bang-bang operator, which is not really an operator. Ruby has a lot of really interesting features. I don't know. I hope that you now know a few more of those. We have about ten minutes until we're supposed to go on break. So if you have any questions? Yes. Yes, I am going to make the slides available online. Any more questions? Yes. How easy is that to pick two words? As far as I know, it's not documented anywhere, so I recommend you go and read the source code for those pieces in either CRuby or JRuby. I know where they are in JRuby. I don't know where they are in CRuby. I honestly don't remember the protocols right now. It's a little bit tricky because the whole idea is that you have to look into the switching. So Ruby tries to switch the order of the arguments when it tries to do a binary operation. Yeah, exactly. Thank you very much.