All right, good morning people. After a bright talk this morning by Ajey, it's time to get dark and dirty, OK. So I'm from Josh Software, and it started in 2007. These are my Twitter handles. And I'm also an author. I have a couple of books which are out. Well it doesn't look so dark anymore, does it? So what is my talk gonna be about? Don't worry. It's not gonna be anything scary. I love Ruby. But as with every marriage, and I hope there's no Ruby in the crowd - OK. As with every marriage you also need to know the other side. You know the side you were - you didn't know when you were just going around. But it's the same thing with Ruby. You have to know what you're looking at. And my talk is going to be about the weirdness and the gotcha moments. In short, in my talk, if you find 'Ah-ha!' moments, it's working. Oh, we have a varied audience today. So to ensure sanity, I have tagged my slides. My slides are tagged with my good friend bumblebee to keep it neutral, that these are for beginners. So you must pay attention. And the experts, try to give the beginners a chance to give the answer. And the experts, you know, take your inspiration from Optimus Prime. And the beginners can choose to tune out, but whatever you learn, the better. So let's get started with the infamous infinity. Now, we all know what infinity is, right? And since we are all programmers, obviously we should know the answer to this one. What's the answer? There are no surprises here. No surprises there. No division by zero. We know this. What about, what about this? Oops. This actually works. So we know that everything in Ruby is an object. So that looks like a, that looks like a class. So let's see what the hell that is anyway. If you type this out, what do you think I get? So... what's going on here? So infinity is a constant define in the float class. Where do you see it, you don't see it there. I can use this constant to form range comparisons. I can use it with equality operators and stuff like that. Imagine three equal to equal to infinity. But it works. Oh well. So. This is the way I get people warmed up. Let's do something with more of an adrenaline rush. Base conversions. It's a lot of fun. So what do you think is the output of this particular thing? Now, I don't want all the math geeks going to their calculators, but essence is converting a number to a string in the octal format. So again, no surprises. Should be fine. But let's push the tempo. Now what? That, actually works. The next time you are reading about, and you hear a name like getafix, ?? (00:03:57:07). You know oblix, asterix. It need not be a name, it could be a number. Well, now what? Push the limits. Oops. So now if you look at it a little logically, the radix as a portion ?? (00:04:15:18) is supported only in thirty-six, because you have twenty-six alphabets and ten digits. So it can go only up to a radix of thirty-six. So if there are some innovators out there, who want to actually get a new alphabet into the English dictionary, we could probably have a radix of thirty-seven. OK. Let's move on to the star. Not the rock star, but the star operator. And to start with, let's see what it has to do with Splat Expander. Oh boy, we see more and more of Ruby code right now. So what do you think is name and occupation here? As we can see we have a struct which takes, which has two somethings, name and occupation, and I create an object off the struct. Now what do we see? Nothing fancy. We're still good. Right? So the Splat Expander is actually taking my arguments and given me the right name and the right occupation. But we don't do things like this, do we? We usually - we are Rails programmers. We work in Rails, so we usually have stuff like this. We use keyword arguments. We all have keyword arguments to initiate a class like this and stuff. What is the output now? It's Optimus Prime, so, the experts? What is name and occupation? Here it's changed. That's because the struct always has an array of arguments. It does not differentiate between this. This will not work on a class. Well, let's get to something more funny. What about this? How many here have used this before? We know how to convert an array into hash. How many of you have used this notation before? All right-y, I have two people in the audience. Excellent. What happens now? What does this do? It actually converts to a hash. And out of curiosity what if I add a seventh element in the array? Error. No like, dude, I don't know what to do, what should I do with the last one? Well, let's try some more stars. Who all thinks that the output of this is gonna be three, six, and nine? Who all think otherwise? What's the output? Awesome. And now? That was easy wasn't it? Now what? String ?? (00:07:04:24). That's all actually works. And let's take it to the next level. How many here know about Stabby, Stabby proc? Here is a sample. So this is a Stabby proc that we have which takes - note we are still working with star. So if I make an invocation ?? (00:07:23:07) to the block like this, what is the output? Mumbling, mumbling, mumbling. It's five. And now you say, I knew that. Right. So basically the short form for the first, second last, last, and the rest of the stuff is in the middle. Pretty helpful thing to know. This works on all. It not, it's just not worked with the Stabby proc, it'll work with Lambda, it'll work with a method, too. But, as with Ruby, and, if I'm supposed to be standing here and I'm supposed to be lecturing you on all this, I'm supposed to know my stuff. Lo and behold, when I was trying these experiments, I learned something new. What do you think is the output of that? That actually works, and I have freaking no idea how. So, well let's put in the slide, and if I have somebody looking explain to me how does that dot notation just work? And it works only on this. It will not work on a method obviously, right. But it works! So, welcome to the weirdness of Ruby. Well. Getting onto really complex stuff. Case statements. How many of you have - you all have used cases, right? Case when and stuff like that. Why do you think this works? And I've tried to make the example as complex as possible. All right. If Optimus Prime doesn't do this who the hell else would, right? So what is the output? It's pretty obvious that we have a multiple of three, because nine is a multiple of three, and yeah, because we can all read in English and Ruby gives us readable code. We know the output here, right? Well it's true. You're absolutely right. Ruby's not that weird. It'll give you the right answers. But my question is: multiple_of is a method, right? It takes one parameter, which I have passed. How was it compared with nine? Where did nine come into the picture? Behind every case, behind every successful case, is a case equality operator. So what actually happens is that that number nine is used with a case equality operator. And that case equality operator is an alias to the proc call, which actually gets us our output. Well. Though this seems pretty straightforward, it has just given me immense power. I can now manipulate any way that I want a case equality operator to work. Simply by over riding the equal to equal to equal to method - the case equality operator. And I am good to have any sort of case comparisons that I want to make. I don't care what happens, but it's my call anymore, right. Speaking of case equality operator, let's go to equality. How many of you all know these symbols? There are operators, an eql question mark, and equal question mark. Let's have some fun. Any takers? Who all think the output is true? Who all think the output is false? What happened to the rest of the people? Don't care. Don't care. That's bad for a conference. You know we just got a huge lecture about participation! Again, who all thinks it's true? Who all think it's false? Why? Oh, come on man, Ruby's gonna be really neat. Of course it's true. Well, what do you think now? Anybody think it's true? All right man. Stand up dude. Please give him a welcome, because he's got it absolutely right. What the hell happened to the rest? Dude, we just saw the slide before about case equality. Are you telling me if you use that in a when statement it's not gonna work? Of course it's gonna work. You're just comparing to one. And... now what? True? How many people think it's true? How many people think it's false? Why? So people called false but thought it was true but didn't want to answer. Well it's false, and I've got you guys so motivated you don't want to answer, right. Damn it. But this is actually equality by value. So the value returned by the object is one, the value returned by the float is a floating point one. It's completely different. Now what? Now it's interesting. Why is it false? Somebody said very confidently, why is it false? Absolutely. Now here's the weirdness. This stuff actually compares the object ID of the two, and a integer and a float would have two different object IDs. It's obvious, right fellas? So. Aiy aiy aiy, true false, what's it guys? There string 'a' and string 'a' are two different ruby objects. If I switch that two a symbol - thank you that's where you go. So with that, let's hit the jackpot. How many of you all know what curry is? It's a lot of fun, a lot of fun. But to make it funnier, I actually decided let's have the slot machine get three pulls. And I wrote code for it on my flight here, so I have no idea whether that's correct or wrong, but like, we know it seems a little weird though. I've tried to compare if all the three pulls are equal and then I'm preparing some recipe with curry, and do you think it would work? It just looks a little bit of weird code, but I shall explain. So curry is a method in the proc class which actually returns a lambda if all the parameters are not fulfilled. So in this particular case, I needed three parameters, X, Y, and Z, and in the first statement, I passed only one. Note, the invocation is in square brackets. It's different. And it returns me a lambda, but other times when all the parameters are actually fulfilled in the second statement, it actually evaluates the proc. Now if you had to write the same code you would have taken different types of input, weighted for the user with (00:14:18:29) ...?? one, two, three, and evaluated it. You don't need to do that. And these things can actually be very helpful. So curry away. So! So you think you can tell protected from private. OK, I am not a - I'm a better programmer than a singer. Right. Private methods. All of us have been taught since school, unfortunately, that private methods are not inherited. Are they inherited? As you can see, foo is a private method. And I ran out of creativity, so I just went to the standard base type foo, blah blah blah here. Is this going to work? All of us take a lot of things for granted. How many of you all knew this already, that private methods are inherited in Ruby? All right, OK, now I'm scared. How many of you all didn't know this? Don't be shy, don't be shy. OK, so this is actually one of the basic principles of where Ruby actually breaks traditional object oriented concepts. All private methods are inherited. What? How many of you all have seen this code before? Forget the Mongoid::Document but include? Wait, come on. Everybody knows it! What is include? Is it a keyword? How many thought it was a keyword? Oh it's like that, require or that import in Java. Include is a private instance method defined in the class module. So while that is sinking in, it raises a basic question. All private methods are inherited. So what are protected methods? So what about protected methods? So what's the difference between private methods and protected methods now? We were told in our school that protected methods are inherited but not publicly accessible, right. Now private methods are inherited but not publicly accessible, right? So what are private metho- protected methods? Contrary to popular belief, in Ruby protected methods actually work with objects and not classes. And you can invoke a protected method on another object within the same lineage. And I say, what the... what? Better explained with an example. Simple example, for the sake of brevity I put the initializer in one line. What is the output, people? Don't be shy. You have bumblebee to help you out. No takers. Come on man, that's like pretty obvious right. You can't call a protected method on an object, right? Simple stuff. However. Now beginners, so-called beginners can tune out. This is fun. I added a method called fights. Same piece of code. What is the output? Take a wild guess, man. Go for it. So either Megatron or Decepticon. Any other deceptive ideas? Guys, very practically, a quick lesson in human psychology. If that didn't work, would I have that slide up there again? It works, man. It works. But why did it work and how did it work? The interesting part is that piece of line, earlier in the previous slide, prime dot nick did not work, but here target dot nick actually works. I have called a protected method on an object. Now that same lineage means that because I'm inside the class Autobot, because I'm calling a method on the prime object, which is in, which is in Autobot class, and since another object called Megatron there is of the same lineage, it's also an Autobot. I can call the protected methods. So why didn't it work earlier? Because everything in Ruby is an object. If you're trying to start prime dot nick and the previous case was outside the scope. So it was effectively in some main class, not the same lineage, so it doesn't work. So Ruby actually works in the traditional way, but has different internal meanings. And if now this was getting a little complicated, how many of you all thought there are keywords in Ruby? Cause that man there is gonna come and shoot you if you think Ruby has keywords. Does that code work? Is it even valid? Should it give me a syntax error? If, how many of you think it will give me an error? Syntax error too? What's wrong with you? Have you gone mad?-kind of errors. Any takers for syntax errors? Probably not. But if not, then I want to ask you know what is the output of this code? Seriously. There it is, seriously. Question is, how many of you all thought this is an error called stack_too_deep. Cause when I call false it calls true, once you call true it will call false. And it goes into a recursive loop and case stack_too_deep. Any takers for stack_too_deep? Higher, higher! And how many think it will actually work? All right. The rest of the people, you all are beginners. But yeah this works. So it does not stack_too_deep. This actually works because true, true's resolution is immediately determined as the boolean value. However if I had changed these two particular statements, the content in the methods to self dot false and self dot true I would probably get stack_too_deep. Not probably, definitely get stack_too_deep. OK. So. If this wasn't complex enough for you, let's go to modules, the mysterious modules. You know what the bull I have with my good friend module, which has power, Megatron is super powerful, and he's a force, he's evil. And I want to put that in my class Hanuman. note the star, because that's true. I want the power of Megatron with Hanuman. Hanuman! Unfortunately this will not go down too well religiously for us, because though it will be Hanuman will be as powerful as Megatron, Hanuman is now evil! So what do I do? Is there a way I can cherry-pick from Megatron, saying, I want the power of Megatron but I don't want to be evil? What do I do? I require. Note, I have not included Megatron, I require the Megatron method- Megatron file, Megatron RB. I define a method called power and I go to the module, tell him to give me that instance method called power, which gives me something called an unbounded method. And then I bind it to me, that is self, and I call it. And that makes my Hanuman religiously acceptable to society. Question? No. So note self, self is the object call. So it's not working on the class call, it's actually working on the instance. So every object, every instance of Hanuman, will actually get the power of Megatron. And with that I end my talk and thank my two assistants here. I have, I'm open for a few questions. Do I have the time, guys? Satish, do I have some time? For questions? Yay! We have a lot of time for questions! All right, you. Thank you. You have a question there. QUESTION: What exactly lead you to title this talk as the Dark Side of Ruby? G.R.: Oooh. Now he killed me, didn't he? So that was a, there's a two-sided answer to that. One was to fool the organizers, to get the CF?? (00:23:05:23) accepted. But more importantly, the dark side of Ruby tries to bring out the weirdness in Ruby, which is not the evil part, but the hidden part. Like the dark side of the moon where we have all these kind of stuff that breaks, the gotchas, the moment that we feel that are going to help but you don't really need to care about it, but it's really, really important that you know these things exist. That's why Dark Side of Ruby. So I still love Ruby - no offense. Any other questions? Yes sir. QUESTION: So have you suffered because of any of these gotchas in you work? G.R.: Absolutely! This is all part of experience. Part (00:23:53:00 ??) is part of experience, part is training, and partly is preparation for my talk, trying to find out these terms, and figuring things out. There's a lot of stuff that I've actually kept out, like you know ?? (00:24:07:03) games. Lots of fun with method missing. I haven't even touched upon blocks and ?? There's lots of funny stuff which happens there. But I have only half an hour. So the question to you guys also is that in case you find some of these funny things which happen in Ruby, and are able to explain it or not able to explain it, send me a Tweet, send me an email, and I will probably investigate and improve my talk at your expense. QUESTION: Yeah. So the other question is, are there some practices, certain things that I follow, so that I don't get, I don't encounter these? G.R.: Well, so one thing, these aren't problems. What I wanted to point out here is that this is not a bad part of Ruby, but these are the things that we take for granted. So knowing about protected and private being different is important. But not mandatory for us to work as Rails programmers. But if you know that, how protected and private actually work, it makes us better programmers. So best practices of Ruby are already there. You know there are things like flip-flops in Ruby which is for lack of a better term, a mind star star star star. But, I do not recommend it. But it's there. There are plenty of other things in Ruby, too. Which work, which should work, which you should use. The bottom line is that Ruby gives us the maximum flexibility to build the way we want to build our code. So with great power comes great responsibility. And sometimes it's irresponsible. So it worked out great. Yeah. QUESTION: So is there a good parts of Ruby, like good parts of Java- G.R.: What? QUESTION: Good parts of Ruby? G.R.: Oh, good parts? Everything! I've been working in Ruby for six years and I still love it. QUESTION: No, there is a famous book called Good Parts of JavaScript, a very thin book that allows a subset of language that is very safe to use, that you can be very productive in. So do you, have you come across something that says, like, there's a subset that you should stick to and use? G.R.: So the best part about Ruby that I like is the closures, which is completely misunderstood, because every time I talk to any person who's getting into Ruby and I show them what a closure is they're like yeah, that's a loop. But it's not. It's like far more better than that. And it's far more - it's more intuitive. It gets into the details and gives us so much more incentive about learning how Ruby internals work, that we tend to actually ignore it in Rails. And I only (00:26:30:29) have a lot of respect for people who have learned Ruby and gone to Rails, because they know the right thing, other than most of us, including me, who got into Rails and then fell in love with Ruby. So it's different. QUESTION: So is Ruby the good parts the next book? G.R.: Could be. But I'll need a lot of community support for that. Yes? QUESTION: Yeah, hi, thanks for the talk. Just (00:26:55:09). I have been checking out Exorcism dot IO. I don't know if you guys have heard of it. So it's actually started by Katrina, who's part of the Ruby Rogues, and I have had a wonderful time running stuff from Ruby, like I have been working Ruby for ?? (00:27:08:20) for years and also gotchas- G.R.: So, Exorcism dot IO. That's great. QUESTION: Like really good Ruby idioms that like so it's basically what happens is you, there are around ten languages if I'm not wrong. You can pick Ruby, you can sub in your solutions. People can look at your code. They can give good reviews. You can help out others with your suggestions. Yeah- G.R.: But to add to that, there is also some interesting - I'm not sure if you all have heard of Winbgall (00:27:33:08). Wingolf was a gem and a simple tool where you can report a problem statement, and using whim, you know execute that in the least number of key presses. Similarly there are a few initiatives for Ruby golf, where you can actually try things like, the beginner ?? they actually said they have things with ?? you know stuff like, write this piece of code without using arrays, or without using the equality operator. And then you start, your mind starts churning, and then you dig deeper into Ruby and find other things. So the best way to find these things is to try Ruby ?? All right we had a question there too. QUESTION: Not really a question, but just a suggestion, actually, to folks who are trying to learn Ruby. I like that he pointed out that some of the things that we've learned in college, classical logic and stuff doesn't really apply. What really helped me understand differences was that treat Ruby as a object-focused language and most of the languages that you probably end up working with, Java, C sharp, they'll be class focused. So concepts like private, protected, just like you mentioned, are all object-level concepts in Ruby. In fact if you wanted to draw parallels again JavaScript is a good parallel because JavaScript is also an object-focused language. So there are a lot of parallels between JavaScript and Ruby, and less between Java and Ruby. QUERANT: Yeah, and- It's like the dot, I'm sorry, that dot thing just amazed me. ??, just having a dot. and I was actually kind of disappointed when it ended. I just wanted more. OK. G.R.: Cool. Thank you. Yes? The Well-Grounded Rubyist. A must read. V.O.: Somebody Tweet about it, please. V.O.: We'll take one last question. QUERANT: How does it help to have protected and private method different from other languages? The way Ruby does it? G.R.: I'm sorry. Did you ask what is different between protected and private- QUERANT: No. How does it help to have a different design implementation, to have it different. G.R.: Oh. Excellent. And I love answering this question. Though sometimes it can be a little long. Why is private and protected different private and protected different in Ruby than in other traditional standard languages? Because Ruby did it right. That's how it's supposed to be. Example. You know, when we talk about object-oriented programming, it's supposed to be about objects. Things that you can see and touch. For example: Inheritance. Right. What is inheritance? In, put it in, no uncertain term, though, it's my ?? Right. My inherited land my from my ancestors. It's private. It's inherited. You can. It, it comes within the family. It can be protected. Can be private. But, if you have your dad's wallet, do you inherit it? You can choose to use it. You can choose not to use it. It's just there. The inheritance of land can be protected because it always stays in the family. Like, for example, the money in the family is protected. But that's always dealing with parents and children. You can't go, your father. Just because you have a father and I have a father I can't go asking your father for money. Right. It's immense, how you determine. And of course public is the same everywhere. So Ruby did it right, because it's, everything's object-centric. Exactly what Aman said just now. Everything's object centric. And, traditionally in object-oriented concepts, it started off right and then it went all across the tangent, where you had this inheritance, and classes and stuff like that. All the standard things that I never talk about: incapsulation, abstraction, polymorphism which seem to be the essence of object-oriented programming but is not. V.O.: So, a follow-up question. I have it. So is there a well-known pattern that makes use of, makes good of private and protected? We understand why- G.R.: Good qu- QUERANT: Is it because it G.R.: Include. Include. Include is an excellent example. There are actually other patterns, too. There are other patterns which allow for protected, protected is used very heavily for all sorts of, the usually standard, why use protected, for example protecting your password generation algorithm. Something like that. But that's the deal with objects. And since objects can be called only from their own lineage you're always safe. Good question. All right. V.O.: Anymore questions? If there's anymore questions, we'll take it offline. G.R.: Sure. Thank you so much V.O.: Thanks Gautam.