 Hello Singapore. Thank you. So, let me introduce myself. Akira from Japan, like this on the internet. As I introduce, I'm a Ruby committer. Lives in a Ruby's village in the Ruby island. Also, a Rails committer. Well, I guess Aaron. Aaron Patterson and me are the only two persons who have the direct commit access to both of these repositories, I mean Ruby and Rails. Also, I'm a gem author. Mainly Rails plugins, like the one at the top, Kaminari, the PageNational Library for Rails. But my recent role is like an event organizer, mainly, rather than a code writer. Organizing the Ruby conference in Japan as the main person. So, let me promote my event a little bit. It's called Ruby Kaigi. It's going to be held in September in Hiroshima. It's a guitar on sale. You can find more information here on that beautiful website. Looking like this. And so, just don't miss it. Okay? So, this is me. I'm really glad to be here and be able to do a keynote here today. Thank you very much for having me. So, today, I'm going to show you things like these. The new features that Ruby Team recently introduced in the major version 2 to the language and how Rails uses these new features of Ruby. Right? And things I did for, like, around these new features. Okay? So, let's begin. Firstly, both of these versions of Ruby and Rails. These are the rough timeline. Sorry. So, you see, Rails 4 came together with Ruby 2. And the important part is this square. Rails 5 supports only Ruby 2.2. As I said, sorry. So, in other words, we bumped up the major version of Rails because we wanted to drop support for Ruby 2.0 and Ruby 2.1. So, these are the supported version of Rails 4 and 5. This means that Rails 5 can use Ruby less than 2.2 features. But Rails 5 cannot use Ruby 2.3 new features and 2.4 new features and 2.5 new features. Right? It still supports Ruby 2.2. Right? So, what are the new features in recent versions? These are some of the new things that I'm going to cover in my talk today. Okay? So, let's start off with module prepend. This is actually one of my favorite features of Ruby 2. Now, let's go back to history a little bit and see how we were dealing with monkey patches before Ruby, I mean prepend being introduced into Ruby. Before module prepend, we were using something called alias method chain to extend existing methods. It's a part of active support and the implementation was just this, two alias methods. It was initially implemented back in 2006. So, it was, as I showed you, it was very beautifully simply implementation. Not just it's super useful, it's very simple indeed. And this is how we use the feature. For example, there's a method called foo. You can extend foo's behavior with defining foo with bar and calling foo without bar from inside foo with bar. But this feature actually had a little bit of downside, I mean like pitfall. Because this feature was not a language core feature, it was just a workaround basically. So, it creates some like intermediate methods. In the previous example foo with bar and foo without bar, these methods are actually publicly called from outside. And you can't tell what's going to happen when these methods are called. What I'm talking about is these methods foo with bar and foo without bar. It's actually in the list of public methods. So, what's wrong with these methods? Here's an example that I showed you. Extending foo with bar. It looks like it's working. So, the difference is that you extend foo with bar and with baz for the first example. And the next example is extending the same method with baz first and then bar next. And you see that the result changes when you call foo without bar method. So, like this, you cannot really tell what's going to happen when you call that public method foo without bar. But it's still callable. So, in the real world example, for example, think of this case, you have two Rails plugins that extend one same method listed in this gem file. And when you change the order of these gems in the gem file, your code may break in some case. So, we needed a more robust monkey patching tool. And so, Yehuda Cots proposed module prepend as the Ruby language core feature in Ruby 2.0. So, this is the feature, module prepend. It uses module instead of aliases. Of course, they know, I guess. It's a very clean way of making monkey patching because it's not going to create any, like, ugly methods like with something or without something. But still, there's a pitfall when you mix it, alias method chain and prepend. So, this is an example of mixing. So, if you, there's a existing class C and firstly, you extend the method with alias method chain and then extend it with prepend. It just works, right? But if you put prepend first, then alias method chain is going to die. It's going to cause infinite loop. So, this means alias method chain and prepend can never coexist. You're going to be killed, okay? So, alias method chain is so dangerous, so you discourage to use it. You please did never use it anymore. And especially if you're a plug-in author or a library author, please stop using alias method chain right now. And actually, you can use both in one codebase if you really would like to by, like, switching by Ruby version. But since it's slightly different, so it's actually hard to support both. So, because of this, many James stopped supporting Ruby one because it's hard to support both one and two. This is the reason I like this feature because it killed Ruby two. Sorry, Ruby one. By the way, I showed you some code calling module prepend that actually these methods are public since Ruby two one. So, there was a small room of improvement in the code I showed you previously. The send include or send prepend was known as a very common idiom in Ruby. But, yeah, it's so popular, but I didn't like it. I wanted to do the simpler, so I proposed to make them public. So here's my proposal for Ruby two one. And in the ticket, Matt wrote he didn't like it. But he still kindly accepted my proposal. But Matt, you still don't like this, right? So anyway, public include is available in Ruby. So, you can actually find dot include calls everywhere in Ruby, sorry, in Rails and in plugins and gems. So, just forget send include. Next topic, refinements. Refinements is another new strategy for monkey patching with very unique scope. It's known as file scoped monkey patching. Let me explain. Who have ever actually used refinements by yourself? Have you ever used refinements? Okay, only two in this room? Okay. I know nobody uses it. So, I actually created some gems using refinements. One is called database rewinder. So, it defines a method in active record connection called execute multiple. And it calls execute multiple inside the plugin. So, this execute multiple method is actually a public method, but it's only visible from inside the plugin. Users can never touch this method. So, it's very useful, right? So, I personally call this super private method. It's private inside the plugin. More accurately, it's actually file scoped inside each file in the plugin. So, it's about plugin and in the Rails code base, I introduce refinements for Rails 5.1 to extend array some. This is the code. It originally was creating something called a rig sum publicly, but I changed this implementation to user refinement in order not to reveal that a rig sum method to the users. So, in this case, I already told this, I guess. So, refinements was used to conceal that internal method. So, I investigated this feature when implementing this and I found something weird. I found it's actually not file scoped. The documentation was lie. And so, I reported to the red mine. Yeah, I told you it's file scoped, but it's a lie, I'm sorry. So, here's an example showing the lie. You can define a refinement in a module. In this case, anonymous module extending object and then define the object that is being refined. Then it works. So, what if we turn them around like this? Firstly, define a method. Then define the refinement extending the method. Then it doesn't work. So, it's not actually file scoped, but file scoped plus physical position scoped. Am I correct, Matt? I thought it's a bug, but Matt said it's an intended behavior. I think this is very annoying behavior. It's so complex, but it's said to be intended by Matt. Anyway, please mind this and please beware when you're actually using refinements. I guess it's the weirdest feature in Ruby so far. So, just be careful. Anyway, this funny feature was proposed and implemented by Mr. Shugo Maeda, who's Matt's boss and his company. And this guy created another weird feature in Ruby called Protected. So, here's another topic concerning method visibility. And another weird feature in Ruby. So, here's an example taken from his own RubyKaigi slides. This is the correct way of using Protected, but it's never used in this way. And Matt, again, he tweeted, if he would design Ruby again, he will not include Ruby in the language feature, because I guess he doesn't like the feature. So, actually Protected is very frequently used inside the Rails code base, but almost these use cases of Protected is misusing Protected. You just can rewrite Protected since private and your code should still work. So, I tried doing this for Rails like three years ago, but I had to change like 140 files and like about 200 additions, 200 deletions. And the tests were still working, still passing. But I gave up pushing this off the upstream because it kind of broke some documentations. That happened three years ago, but I finally pushed this last year by separating that huge patch into like several small patches. So, it's actually in Rails 5.1. Rails 5.1 does no longer abuse Protected scope. So, Protected is dead in Rails method. So, he also should never use Protected again. By the way, Shugo, the creator of these funny features, is working on his another project recently. It's a text editor in Ruby. So, he's going to do a presentation about his new project text editor in next coming Ruby conference called Ruby Taiki. So, don't miss it. So, here's another topic. Private. There's a tiny improvement around method visibility in Ruby 2. So, in order to define a private method, we had to define the method like this. In this case, all methods defined below that private become all private, right? Or if it's unlike this, you can do this also. In this case, the private call takes a symbol of the method name, right? So, just like C++ or Java, recent Ruby's can do this. Or public. It's revolutionally handy, right? So, you don't have to repeat the method name twice. So, it's a very simple trick. The author of the patch just changed the return value of the def statement. So, it's internally actually doing this, right? Passing the return value of def statement to the private statement, right? So, this patch was written four years ago. And I suppose this feature is very much important, especially for the Rails team, I guess. Because this is the Rails style. There's a kind of group of people who want to write private this way in this unique style. Well, I'm not sure if it's a group of people. Anyway, there's always kind of like the battle between this style and this traditional style. So, everybody's happy with this, right? We don't have to fight anymore, okay? So, that's why I say this feature is very important for you, Aaron. But private def is actually very rarely used inside Rails. I just get repped today and I found only 17 occurrences in private def in Rails. The reason is because there was a documentation problem in private def until very recent. So, Rails uses RDoc to generate documentation documents. And RDoc couldn't properly generate the document for private methods if it's defined that way. And it breaks the Rails API document if you use this. So, the problem was like this. If you use private def and then if you define any public method below, that public method also is like treated as a private method. So, that private def changes the scope globally. So, why did RDoc have such bug? Because the parser is different from Ruby's parser. Because RDoc has its own Ruby parser, okay? The parser is this thing, rubilex.rb. Actually, it's a lexer. The file is like this. According to the comments, it's a Ruby lexical analyzer written by Keiju-san, who's the author of IRB. And it requires IRB inside, right? It's not a console tool. It's a document generator, but it requires IRB to use IRB parser's feature. So, there are three parses in Ruby. Pars-y and Ritter in the central library and this IRB parser thing. Actually, Ritter is a Ruby parser in the central library. So, I guess RDoc should use this instead of creating its own parser, right? So, why doesn't RDoc? Because RDoc was created before Ruby was being created. This is the history. So, I tried to rewrite the parser of RDoc to use Ritter, but I just failed. It was so tough, too tough for me. So, I gave up doing this, but I brought this task to my Ruby Meetup. And actually, someone is using, I mean working on this, to replace RDoc parser to use Ritter. And it's going to be... And this person will present about this at the next RubyKaigi. So, don't miss it. So, anyway, this is the history of Ruby parser's N. Yes, this one at the top, IRB, was created in the last century. It's been 20 years, approximately, from the first birth of IRB. So, everyone, let's celebrate the 20th birthday of IRB. Yeah! And I guess the anniversary event is going to be happening in RubyKaigi by the creator of IRB himself. Anyway, let's go back to the private problem. How much minutes do I have? 20 minutes? Okay, okay, okay. So, I said I gave up replacing the RDoc parser. But instead, I just made a tiny patch resolving my problem for Rails. This is my patch. You can check online. So, this patch enables just correctly parsing private ZEF on RDoc without replacing the whole parser. So, this happened last year. So, it took, like, three, more than three years to support private ZEF and being Rails committers to allowing Rails committers to use this new syntax. But it's now available because RDoc has been released with my patch and Rails 5.1 depends on that version. So, you're free to use private ZEF now. Yeah, okay. So, the next topic is keyword arguments. This something looks like keyword arguments in Rails since it's version one. Like this. So, these are the method definitions of some kind of keyword arguments. Or like this. It takes very well. So, it generally uses Ruby hash to pass in something looks like arguments. I mean, keyworded arguments. And the method call looks better than, like, passing in these arguments without names. But on the other hand, the method definition looks, like, very weird. I mean, it tells nothing to the users. Just, like, pass in some kind of hash naming options, or you can pass in everything like star args. It really tells the method signature tells nothing to the users. And it's actually included in Rails tool chain in active support. So, this is how Rails extracts the options from the given var args. There's a method on array called exact options. And since it's just a hash, you can define a default value inside the method like this. And, yes, inside the method. And also, never forget to write a documentation about the default values outside the document. I mean, I saw the method. So, you can also verify the option keys in this way to make sure you haven't got any unexpected keys. This just raises when unexpected keys look given. Again, you have to write both the code and the document. So, then Ruby 2 finally got the core language feature keyword arguments. It was implemented by Mame, the man of insane. So, we can now rewrite the keyword arguments ish something in Rails from this to be like this. Here's a patch rewriting the method. So, you see the method signature becomes more like clear to the users what to take, what keys to take, and what default values to take. Also, the implementation becomes shorter. And I guess it runs faster because it's all these hash manipulation and array manipulation is written in C. So, I created a branch using keyword arguments. I mean, introducing keyword arguments in Rails code base back in four years ago before Ruby 2 release. And then I found some problem, some specification problem of keyword arguments in Ruby. Rails very often defines a key, a method key that is exactly like a Ruby keyword like if, like validate if, validate unless, etc. So, a keyword argument, a keyword method is actually can be defined like this. And it can be called like this, but you can never like access that variable. It causes syntax error. So, with keyword, I mean, now we can create a never can access variable in Ruby. We brought this problem to Ruby core and discussed with this. And so, we introduced a new feature in Ruby 2.1. It's called binding local variable get. This way, we can get the value. This example defines a local variable named nil. So, it works, right? And so, I like to propose to Rails to use keyword arguments as the first class citizen API in Rails. Thank you. I haven't actually proposed this yet, but I'll work on this maybe after this conference. Again, it should run faster, it should make the code more readable and clean, and it should make more obvious documentation. So, I guess I'm going to do this. So, the next topic is require relative. Yes, require relative. This feature is originally introduced into Ruby because of Rails. And it's supposed to run faster than normal require because the implementation is much more simple. But Rails doesn't really use this feature today. Most of the requires in Ruby is normal require instead of require relative. So, there's a huge room for performance improvement, I guess, using require relative. So, I created a patch doing this. I rewrote all requires into require relative. And benchmarked. The result was no significant performance improvement. So, I haven't pushed this upstream, but I don't know why it's not fast. I discussed with Koji and he said maybe bundler is doing a good job redefining require and making it faster. I'll investigate more after this conference. Anyway, require relative is basically a good thing. So, you may use it. I recommend you to use it instead of require. It should be faster, I guess. Here's another topic. Instruction sequence load and dump and load. Okay, these are public APIs since Ruby 2, I guess. And Koichi created something using this. But he said his version doesn't really make Rails faster. But this year Shopify created something, resembles to Koichi's one. And they say it's making Rails boot time faster. It's very interesting. It's kind of still veiled, mysterious. But I heard one of the creative this plugin is coming to RubyKaigi. And so if you'd like to know more about this plugin, I mean this feature, just come to RubyKaigi. Because another huge topic, encoding in Ruby. So in recent versions of Ruby, every string object has its own encoding. And we use various encoding. Actually even Matt uses another encoding other than UTF-8 until like five years ago. But Rails has to be basically UTF-8 only framework. Rails doesn't have to deal with multiple encodings internally. I mean, this can be the basic strategy against encodings in Rails. Just keep every string to be UTF-8 and convert everything from the outside to UTF-8. So for example, you can use any encoding writing view templates by using another file encoding or putting magic comments on the top. But I mean, nobody's doing this in Rails. Nobody's writing non-UTF-8 templates. So I guess I told this like two years ago in RailsConf. But I'm planning to drop multiple encoding support for ActionView. Actually there's a kind of 70% done patch in my machine but I still haven't created a test passing patch. I'm sorry, I'm just so lazy. I'll do this after. So anyway, there's a library in ActiveSupport called ActiveSupportMultiByte since like 10 years ago which includes a huge set of Unicode database in this file. So since the encoding handling has been improved in Ruby like this and it has recently very important improvements in 2.4. So by using these features, we can totally remove these, remove that ActiveSupport version of multiple encoding support from ActiveSupport and use the Ruby Core feature by em17n instead. Actually we need to do this as soon as possible because the maintainer of the ActiveSupportMultiByte has just retired from all this sort of thing. So currently nobody's maintaining that ActiveSupportMultiple something. So I'd like to propose to totally remove that ActiveSupportMultiByte from Rails maybe in the next version. We've already created a pull request. It's still under discussion but I hope to merge this into the next version. Okay, next topic, frozen strings. So we've got so many like let me freeze some strings in Rails kind of for request in the past few years because it kind of makes Rails faster a little bit. So these are frozen cons of freezing strings in the Rails code base. It really makes the code ugly for example like this. It calls dot freeze dot freeze dot freeze dot freeze dot freeze dot freeze for every string literal. It's just ridiculous. Honestly I really don't like, I don't want to see this anymore. So I proposed to introduce a new magic comment feature in Ruby just because I didn't want to see that coded. To be more accurate there was already existing proposal adding magic comments and I just voted a strong plus one for this proposal. And so Matt accepted this proposal and so it was introduced to Ruby 2.3 as a full feature. This is the magic comment frozen string literal true. Also Ruby 2.3 introduced a less known feature, a minus operator for string literal. The minus string literal, you've never heard of this before I guess. It's actually a little bit faster than calling dot freeze method on string. Maybe you never should care about this but it's just a tip. So anyway I would like to put the magic comment to all files in Rails. But it's a little bit too fast. I mean too early for Rails 5 because Rails 5 still supports Ruby that does not support frozen string magic comments. So maybe we should wait until Rails 6 to do this and here's another topic concerning performance. So Rails 5 does not support Ruby younger than 2.1 because Ruby 2.2 introduced this feature. Ruby 2.2 collects the symbol garbage. Due to this, well before symbol GC Rails was abusing strings instead of symbols. Rails converts every symbol from the outside world to strings but I guess we don't have to do this anymore. We just use symbol as it is everywhere in the Rails in the process. We could do this and we could reduce garbage strings by doing this. I guess, I just guess. It's another idea making Rails simpler. So here is another recent topic of Ruby. It's just unified fixed num and big num into . If your code still accesses fixed num or big num, it warrants. So if you find any Ruby gem that warrants, just don't use it. Stop using it and find an alternative. Okay, finally, it's next topic. I'd like to talk about some methods that it recently implemented in accept support and then port it into Ruby. Like this, object try, got new literal in Ruby. Or strip here duck, also get new written literal. Here's another minor methods, numeric, positive and negative. Or array, append and prepend. And as Nick stated, VHH told something like this on Twitter. Active port can serve an experimental lab for future core features in Ruby. Okay, can I just have two more minutes? Here's another method, sum, array sum and innumerable sum. So this case is a little bit complex. There used to be active support version of sum and Ruby kind of ported array sum and innumerable sum. But in a different spec. So the behavior is slightly different, differs between Ruby version and Rails version. But the Ruby version is faster than the Rails one. So we want to call the Ruby version if possible. And then fall back to the Rails version if something's wrong with Ruby version. So here is the situation. As I told you before, somehow done using refinements. It kind of works, but it's so complex that implementation is so complex. Maybe we can make the simpler when we drop supports for the Ruby that doesn't have array sum. So anyway, there's such difficulties for Rails team to support multiple versions of Ruby. But for the users, you just can use the newest Ruby and use every new features of Ruby. You can do that for your applications. So like I showed, Ruby is getting better and better day in day and introducing new features for every version. So I encourage you to upgrade your Ruby immediately to the newest one and use new features. Enjoy new features. So this is the end of my talk. Ruby is evolving and Rails is also getting better. And as a commuter of both, I'm kind of doing some like work for both team. And there are so many more other things to do for both Ruby and Rails. So if you're interested in my talk, I encourage you to join us. The development of these language and plug-in and frameworks. That's it. Thank you very much. So thank you for having me for this conference. And see you hopefully at another conference. At Ruby Kaigi. Thank you very much. All right. Do you have any questions? Do we have time still? We'll take a few questions, yeah. Anyone? Oh, yeah. Yeah, you can just push the mic, actually. My first question today. Actually, it's a comment. So I did a lot of benchmarks with keyword arguments in Ruby 1.9, 2.0, 2.1, 2.2 with the representable gem because we started switching from the options equal hash to the keyword arguments and it was like four times slower than because there was some improvement in 2.2. But it was so slow that we had to stay with the hash thing because they used Ruby hash in the actual implementation. True, yeah. So it's been improved since 2.3, I guess, 2.2 or 2.3. It's actually still slow in micro benchmark. Do you mind? Do you mind that slowness? Okay. I just promised to run the benchmarks again with 2.3, 2.4. Okay. I'll send you a pull request. Cool. Does anyone else have questions? Yeah. You can push the mic. So you mentioned with keyword arguments, if you use a Ruby keyword as the key, you will create some unreachable variable there? Yes. If you run in verbose mode, there will be a warning from Ruby? I don't think so. Okay. Thank you. Okay. All right. I think there are no more questions. Thank you very much, Matsuda. Thank you.