 I'm very bad with software So yeah, I'm Greg and today I will be running about Ruby. I will be complaining about all the features that I don't like There's plenty of them, but I chose just 10 because there is no time for more and I'm not a hater. I use Ruby for six years and I like this language but like every single language it has its problems and It has big problems like for example, it has this thing called nil and no language should have the thing called nil But Ruby has it and it's huge problem and I could talk about it for hours But I will focus today on more simple and smaller issues That in my opinion Ruby shouldn't have but they are they are there and they are actually called features So I want to have this presentation a bit interactive So I will be writing some code and I want to ask you what this code will will return. Okay, so let's start with something basic What this code will return What better? What yeah, this code, do you know what it will return anyone? No No, one divided by two will return one. Come on. Come on. It returns zero It's so obvious. Okay. I hope this one will be easier Even beer. Oh wait, maybe Okay Now better so Yeah, so square root from four what we will return Yes, okay now tricky one Square root from minus one what will it return? Oh Yes, of course error Okay, now I do some magic I'm requiring Math library for Ruby It's there. And now what will return this code? No It returns rational, which is one of two Now what will require this code? Yes, and What will require this code what will it return? Yes, it's I so the math and library adds Plenty of possibilities for Ruby, but it also changes the default behavior that you expect So normally when you divide integers you expect it to return zero and of course if you require math and yourself Then you know what will happen But now imagine that in your gem file you have a gem that depends on another gem that depends on another gem that requires math and and then suddenly all your operations or your integer divisions stop working and It's not just problem that I imagined I checked on github and they are at least like ten different issues with different gems that people complain Oh, I added your gem and now all my tests are failing and the usual response is like oh, it's no problem not mine So yeah, so there is this there is this gem called Ruby units that allows you to convert various units like miles to kilometers etc and it requires math and because of the precision and Because of that people who want to use these gem usually have problems later with integer division So the solution for that is to do something like this So now it works like expected, but no one no one thinks about it because no one thinks that oh Maybe some gem will require this obscure library. Okay now another thing Okay cloning objects, so this is thing that I That I that is really annoying Because we have two different methods in Ruby that are that are called very similarly one is called clone and one is called doop and Now let's do Okay, so I've required this this code I've got just class user and I've got module admin and now I have you equals user Of course. Oh, no, it's not a user. Huh? That's interesting Yes, okay user.new So now It is a user. Is it an admin? It's not an admin. Now I do user.extend admin Now I've got the same user, but it is also an admin So I just this one single object is an admin and Now I do Freeze It doesn't have it Freeze Okay, yeah, so I frozen this object so I can't modify it So this object is an admin and it's frozen. I can't modify it I can't add any more modules to this object and now I do user.clone You see equals user.clone now you see Is a User of course. It's an user. Now the question is is it an admin if I clone the object Is it still an admin or not? Who thinks it is an admin? Nobody two people who thinks it's not an admin anymore Nobody. Oh one person. Okay. The rest is still thinking. Okay, so if I clone the object It is still an admin and if I clone the object It is Is frozen? It is still frozen, but now I've got another object which is duplication of user and This object obviously is a user, but it's not. Oh, sorry, it's UD. Yeah So it's not an admin it is a user and is it frozen No, it's not frozen So the difference between these two methods is not obvious if you think about this words like duplicate and clone You think of them as synonyms, but in Ruby they have very different very different consequences So this is something that I do not like Because it's not explicit whatever I use if I use duplicate or free or clone The name of this method doesn't tell me that the object will actually change that we it will not be an admin anymore Next one. Okay, so in Ruby we've got instance variables that are Prefixed with single at character and class variables that are prefixed with two at At characters now Okay, so I've got class a and I do something like instance Sorry, okay Correct. I think so. Okay. What what will return this code? Which number? three anyone Agrees disagrees it returns one So and now if I do a dot new that instance variable get it returns three Which means that instance variable for the class and for the instance of this class is different thing Now let's do a dot class variable get Okay, what will this return two or four? I Know it returns for so the class variable for the class and for its instance It's the same thing, but instance variable for the class and its instances is different thing now Now we've got class B which inherits from class a and now we do the same Let's say that we call B dot class variable get what will it return will it return? No, this returns this returns five now what this will return It returns five because we wrote another class that inherits from a and it uses the class variable Which is shared among the whole three of of classes and now if we do P dot instance Okay, this everyone knows what it will return Yes, it returns six and This one It returns Neil So once again, if you have single at character, it's only in the same class It's not shared among any any other classes and you have the if you have double at character It's class variable. It's short everywhere the con the conclusion is don't use it because you will have a lot of surprises Now aliases So we've got these two methods to add alias in ruby one is called alias and the other is called alias method and they are basically They seem the same So one looks like this alias method then we say the new name and then after the comma Old name and alias. We do not have to do We do not have to use the comma the difference is that alias is a keyword in ruby and alias method is just a normal method Which you can override So now Let's check how they both work Let me just switch Okay, so that you see better. So we've got two classes one is vehicle and one is a car and now car inherits from vehicle When you ask for type of a car it takes the the method from from its parent and that adds a car and Then when you ask for a size it does the same the difference is that For for size I've got alias method and for type. I've got only alias So now let's say I've got new car and I ask for its type So it says vehicle is car Now I did an alias So alias should behave exactly this way the same way So you expect that car new dot kind will also return that vehicle is a car, but it's not and If you do this with alias method So if we ask about the size it says that size is big and if you ask about dimension It says the same so alias method will call the method from the child Which I do here In the size but if you do an alias It will not call the method from there from the child It will call the method from the parent once again just like in previous case You've got two methods that are called almost exactly the same, but their behavior is different in certain cases I don't like it because it's not explicit. I don't know that alias is only attached to the parent and that alias method also works on the child next one is Logical operators Okay, so I guess most of you know that in Ruby we've got two types of logical operators one its end-end With like the end with ampersand for example, and the other is just the word end and Obviously, you know that their behavior despite the fact that we use the same name to describe them is is different So we've got Sorry So test one This method anyone knows what it will return return Seven and the other one The other one it will return 42. Yes, so the difference is that ampersand The double ampersand behaves like this X X equals this While the other one behaves this way So the problem here is that once again we've got something that looks very similar that you would expect it To behave the same way, but it's different and now you can you can check it also In this case like if I run test 3 I'm running around. I'm raising a runtime error Because the behavior is like this and if I do test 4 it will not raise an error Because the behavior is like this so the ruby style guide that is Used by the community says that you shouldn't use this or and and at all that you should just ignore them For me, it's not really I don't use them as logical operators. I use them for control flow But many many people do not know the difference. So whenever I see the code that uses both of these Constructions, I always think if the programmer is aware of its of its effects or not That's why I prefer to keep using one of them and just use parentheses whenever whenever it's needed Next one is for loop Has anyone here ever used for loop in ruby ever a Few people okay. I use it once It's here This is the one. This is the one that I'm using it The reason why I'm not using for loop is because it has some unexpected behavior Okay, so you've got test for loop So if I run test iterator What it will do I Not new It will raise an error because the J variable is not is not available It is it is defined here inside this block and its scope is limited to to this block But the for loop doesn't care So I do test for And it returns me a number. So the thing is that Even though it looks like the same begging and block the difference is that it doesn't have a new lexical scope so it's it's the same scope and it introduces a lot of confusion and The only case that I see people using their for loop is when people come from JavaScript or Java or another languages in Ruby It's not really very common because of because of this problem. Now. Oh, this is my favorite. So you've got this Methods protection, right? You've got three levels of Of methods availability. There is public method protected method and private method And in all of the languages that I knew before all object-oriented languages The semantics of private protected and public is exactly the same except for Ruby So now we'll check how how behave private methods Okay works So I've got class called private parent. I've got this class and I've got a new object So, okay, I've got this object and it has a few methods. So the first method is Check a check a obviously will return The variable a that I defined here and I've got public attribute accessor for this method So of course it returns one now Since the attribute accessor for the variable B is private as You can expect it will tell it will return an error And now it's the same with With setters, right? If I say Set a What it what it should do, of course, it should it should set this variable, right? It should set a and now if I do check a it will return the new value and And if I do the same with B What I expect is an error, right? Because B is private method and I can't call it with the with the self Prefix so I can't call self dot B because it's private Except that I can because it's an exception that totally doesn't make sense when you think about it at first but then you realize that if my Accessor is private and if I am not able to use self if I write something like this instead of defining the Instead of assigning the number four to my variable B. I will just create a local variable So because of that Ruby has this one only one exception Only for access for writers for assigning the variable. You can use self dot private method and now if you have private child this object in languages like Java or C++ wouldn't have access to any Private methods, so it will have access to set B Because in that languages child has only access to public and protected methods of its of its parent But in Ruby this semantics is different now. We've got protected methods Which I would behave also entirely different than in other languages So if I have protected parent Anyhow if I have protected new Let's say one and I have protected child So I've got these two variables protected child inherits from protected parent. Now I can call something like protected child compare arc with protected parent and it works even though This method arc here is protected and I'm calling it on the other object which normally wouldn't work because Because it's a protected method, right? The difference is that In ruby you can call protected methods on any other object that is in the same tree That is inheriting or its object of the same class Why I don't like this feature is because it's confusing If you ever written any code in any other object oriented language So whenever someone uses protected in the code I'm wondering if they really mean Mean it to be protected if they know what's the difference between protected and private Or if they don't know either and they just copy this code from stack overflow Okay, the last one I've got is block syntax So we've got two syntaxes for block and it's either curly braces or it's do end And you would expect that they are exactly the same, but of course they're not So you've got this block syntax Okay, so we've got two methods here Uh One uses curly braces and the other one uses do end And they're exactly the same except that one uses curly braces the other uses the other uses do end So it's curly braces It's this method any idea what this will return So this will return an error That's because ruby thinks that when you're using block, uh, the curly braces you're doing something like this So for you when you read this code, it seems obvious that no, this is not what I mean But curly braces behave this way and if you have exactly the same code But instead you use do end This works So now why this is confusing because Because this method these curly braces it can still work Like if the method val 2 will return something different than zero So if we do curly braces 2 It will return minus 4 you might think that it doesn't make sense but Imagine that you see this code like this. So it's method val 2 that accepts some block And this method what it returns for me. It's a symbol of minus So if you do something like this, obviously it will reduce with minus So we 1 minus 2 is minus 1 minus 3 is minus 4 And then if you try to to use this val 2 variable, but with curly braces It will raise an error So, uh, I think this is all what I've got. Let me check Oh no, there is one more. There is one more that I really really hate Uh, so this is the syntax of Of the methods with exclamation mark in the end. So obviously when you've got string like str and you do sub As we replace with z It will return us The changed Changed object, but it will not Modify the string itself to show it to you better. Let's do it like this So it returns me modified string, but the string itself is the same It's different when we do it with sub The string was changed, but now if I call this str sub same, it returns me nil Why because there was no letter s there was nothing to replace in that first string So it returns nil So for me, this is extremely confusing because I don't know that it will return me nil like why why would it it should return me the modified value, right? And this modified value is basically the same as the original value The reason why it behaves this way is so that I can do something like if string sub Then zero else one So I can do something like this So I I understand the concept. I understand why it's done this way But this is something that once again is very confusing and when I see the code like this I'm always curious. I'm always very suspicious if this is something that That the developer intended to use or if they don't know that it has these confusing consequences Okay, I think that's all for me today Despite all these all these stuff. Where is the camera? I still love ruby. I still I'm not a hater. It's just Obviously, it could be better like like any other language. Thanks everyone Any questions? Yes, like most of it I see just like once or twice Some of them Like so for loop I I I don't see but the class variables that people use I see all the time And I always I always change this code and people get annoyed because they They use it on purpose But then they don't realize that it has some further consequences And this math and that I shown in the beginning I didn't see it until I checked it actually on github and it seems that Plenty of people had problem with that Just don't use it Well, but this is this gem that uses it is the best gem that provides the conversions between units, right? Oh, yeah, but it's not actually it's not a gem. It's the core library Yeah, so it's element of core library that monkey patches the core library Okay, anyone else No, cool