Ruby’s Gems

0 0

I'm Peter petrol I don't know I'm supposedly one of the 3 t.o dresses from the ruby on rails community and I was super happy that I was invited here so thanks for the organizers and it's been really great conference so so far end we we've been treated really well and when I was preparing for my beluka talk I figured out I have an espresso machine up my whole room and minibar and despite that I went and gave that dog but there was a very nice conversation we had with Sonic who'll be speaking tomorrow and I'm one of the people who don't really get jokes that well so I actually believed his speaking seriously and I just Kabul some slides and he'll be giving this talk and I just his talk tomorrow unfortunately he's a bit under the weather so so I'd have to soldier from my own slides let's see how it goes I work at the University I work the ruby rails and supper encino amber consultancy also so if you have anything we could help you with do let me know and I'm also apparently i forked sometime in the spring and there is another process with my pit as its parent paid so this might be probably last such conference season so I'm already very thankful for the organizers to provide for people with kids which is this new trend in conference organizing that is like really really good there are notable other conferences that also did that and because of this I I was working on those sites thinking that you know piata will give this thought but eventually like this was universal enough title so this talk will be mostly about what I find most interesting in Ruby and what I like the most and I'm also shamefully using this joke whenever I've speak before lunch I will try to make this quick if there's anything that is very well explained please let me know I'm standing between you and the lunch so i'll try to not you know not to make a big problem about this so whether i could be so much in my opinion Ruby's full of gems there is the language itself has a lot of stuff that people not necessarily know exists but it turns to be useful when it actually gets discovered this is how I discover a lot of things like reimplemented basically half of the song library before I learned about it metaprogramming can in Ruby is very strong as one of the language is known for its meta programming which is also when used properly and when used very scarcely this is a very good thing there are various implementations of Ruby which is also like super super good and those implementations can instrument your applications in a way that that are often quite useful and the last part that I will cover our the protocols in Ruby which are my favorite part which is all of the implicitly assuming object interactions and ties between objects as for us what methods can be called and what the objects should expect by calling other methods so let's go through this like one by one the will be quick or is full of goodies these non library as well the there are wonderful little gems in the library like we have I'm like huge fun and it will keep showing up through those slides this is a quote from Florian give sure who which I which I put in every second of my presentations because it's very very true the innumerable module is the exemplary way of doing things there will be way and do to follow this advice and I will illustrate what I like about Ruby core on a few examples from the innumerable module so for example the prime case of a method that people then to reimplement many many times you have a collection you want to split it into two different collections for example you have numbers from 1 to 10 and you want to split them into primes and composites or you have a to the list and you want to split this all of the tasks into uncompleted and completed there is a innumerable method called partition that will do just that it will run the whatever block you pass it it will consider where the weather the answer is true tea or fall see and then it will split the 30 ones into the first results and the default she wants here so these are the prime and composite numbers apparently one is composite this is a wonderful discussion if you meet a mathematician ask them whether one is prime and why also we we get things like lazy enumerations we can ask ruby for the first ten primes from one to infinity and this will actually complete now because this will be arranged that goes into infinity but it will be evaluated on a lazy basis so this will keep selecting from that range only as long as this requires an input like all of these are enumerators that's why we have to call to a at the end but we end up getting the first ten times which is a good thing to know because it turns out enumerators are quite often hiding in your code if you're doing a lot of generation stuff if you do not necessarily fractals but any kind of things where you generate other things that depend on the previous levels using lazy enumeration might be really convenient it's probably why why I work at the University there is a interesting metal slides before that is i'm not sure i ever saw it used in the wild but it goes through a collection and slices it at the point where this block returns true so if we took the first and numbers again it would slice this into collections to Till's to this and are a that always starts with a primal is the first wasn't primed and it gets its own slice and after this talk do read the documentation for size before because it shows a lot of the things I will cover later in this talk like the protocols that triple equals and so on and will be a numerical chunk is a method that is one of those things that you can't really fathom using it especially after reading the documentation but there are sometimes cases where you would end up reimplement in it chango's recollections runs the block and chunks this collection into pieces that have the same result of that block so this will and it also yields the results so this will be like false all of the parts of the collection subsequent are not prime then through all of the primes then false true and so on it and it works in any kind of response so we can actually partition your collection into five different pieces and those will be yielded as long as the result of the block is the same admirable chunk is one of those metals that is very old and you can see how the Ruby language implementation implementation again i read that documentation there's a ton of like if this block results in a symbol that starts with an underscore the chunk will fail and tell you that these are reserved like this kind of wonderful stuff from probably 15 years ago this is you can grab through our collection if you're coming to ruby from from unix this is like super convenient and and really obvious but you can actually grab through our collection of numbers by passing a number it gives you an array of this with this number and you can actually grab with the range we can go through a collection and grab with a range and it will work why it will work we'll see at the end of the talk but this is some of the things that probably are useful once in a blue moon but when they are ruby is there for you right and you can also like pass ranges to random and it will randomize something from that range you can call sample on a collection it will give you a random element of that collection but you can actually in the recent versions of Rob you can pass a random number generator which is really good for tests because you can see this with any number and as you can see the responses are the same so we can actually check whether your method returns random output but also be sure that it is something that you know so we can because you can see that with random generators you can see that with a couple different one so we know that actually randomizes but you can also have tests that are testing and passing every single time so one of the last examples is something that happens quite often if you've ever worked with Salesforce this might be disturbingly known to you for example you have a collection of tables this is this new nice way of creating an array of of symbols and you have a method that gives you a result for one of those if you want to have a hash that that is kid with the table names and the values are result names you have a lot of things a lot of ways to do it and Ruby Ruby really gives a lot of possibilities how to implement it you can run reduce which is probably what I don't know Haskell people would run like in the middle of the night and it works you can run each with object and I think this block is a bit more readable and it started with this empty hash so you don't have to like with reduce which is the same as inject you have to return the trash here you can just run each which object you can actually use zip which is this wonderful and more able method that lets you zip to collections together so you will have from an array if you zip an array of names with an area of results you will get an ra of two element Aires where the first element will be for an hour to elementary with accountant results from account and so on and then you can pass it to hashes square bracket constructor this probably will make you feel very good about yourselves and your co-workers will probably don't like you even more but since Ruby 2 point wonder is a 2h on our race and I think this actually is the most readable just map the tables into those two elements are raised the table name and the results for and just hash it so Ruby gives you a lot of ways to do the same thing and it's often important to to figure out the one that is the most readable this one is from Sam rubia actually made adjust with this and a few more and asked which is the most readable and summer abuser well actually so yeah this this is one of the gems that you get when you ask people so do it do it exception tagging exception tagging is this thing that I never knew existed and then I can't really leave without it now let's assume that there is a third-party API that leaks tons of different exception process for example something that uses net HTTP and suddenly you have to handle like 10 different exception cases or a library that would throw you know Neal metal missing and all of the other stuff and you really want to handle it in one place you can write a rapper you can create your own API exception for that API rapper rescue anything that comes from this API extend it with your exception and just rear ace because race without any arguments will rewrite the the same thing that was here and also like if you never used method level rescue as you can see there's no begin and it just rescue at the metal level this is really handy and if you ever if you have a lot of begin rescue end blocks i would suggest trying to move them to their own methods because method level rescue is much more readable and you get a method that is like saving you hiding the all of this rescue from you so then you have your domain object you call this API wrapper make that API call and you can rescue whatever that API raised you can actually risk your own class because all of those exceptions are also extended with API exception if you cringe because we're extending objects on runtime it's not such a big deal in Ruby 2.1 anymore so it's it doesn't invalidate the global cash anymore so that's good and this is something I learned from at the grimms exceptional Ruby which I highly recommend reading and just to lighten the mood a bit do you know what this will return if you pass it 1 & 2 any ideas if we call add 1 & 2 come on it's not a trick three really good what will it return if we call it with just one at the first argument and not second element 42 right exactly so if you really want to have fun with your co-workers highly recommend this on the other hand it's actually useful you can yield as a default action for for the one of the arguments it looks strange but it allows you to do things like this this will wrap the first argument if you pass it but also if if you only passes a blog as will wrap whatever the block returns probably you should again talk with your team whether this is acceptable but this is actually sometimes useful again both from FD green and the last part in in this like Ruby proper staff there is a new syntax for creating rationals so you can write this and the parser will actually create rationals on the fly also complex numbers i think they were called with the imaginary part and also this is actually since ruby 2.0 you have the string b method that will return a binary string and also if you call string freeze the Ruby 2.1 compiler we're actually reuse the existing string so you no longer have to do this whole magic where you take your strings assign them to static constants not to recreate them on every call if you actually have bar freeze in your code the compiler will reuse the existing bar string and not create a new one so next part metaprogramming this is one of my two i would say favorite Ruby books I haven't read it I have the a reddit previous edition I'm looking forward to reading this once my daughter is born and I have all of the free time and i highly recommend reading well at least the previous edition i can only assume this one is better mostly because it also shows you where not to do metaprogramming the basic meta programming is metal missing I will spare you this example because I assume you're here because you know how to do metal missing but have you ever considered why when we call class some class names new it actually execute the initialize method but when you return from the initialize method you will get the object even though it could return like foo or 42 and how does it work so we can run and we can look into actually class new source in MRI and we will see that there's some see stuff that if we try to translate it it would look probably something like this so we create a we call the allocate metal this is RV object a log and then we send this initialize call to it this is how you end see you call methods and then we return but we don't return what we got from the initialized call we return the object that we got from allocate so this is one way of writing this if you really want to show that you're on top of Ruby you can actually do this which is you can tap into the object return from allocate and so on so forth if your team that's this call through called review you should probably talk with your team more unless you are all tab funds I mean I'm perfectly fine i use tab in my own projects but you should talk with your team about using this the trick here is initialized is a private method so we need to like send for it especially like we cannot call initialize on the instance and you should always also if you ever send you send please use the underscore underscore sent underscore underscore because sometimes there are objects that redefine sent because it makes sense I send this email right and then trying to use send in the regular meaning it's not the best thing so the thing is this is what I said was it's not really truly called two-rbi bialik it's not really the call to allocate we can see that if we have our own class we create the class level allocate we just print out and call super and initialize as well we can see that if we do foo allocate then it prints allocate and it actually allocates the object so what it does so what allocate does by default is you can allocate the object without calling it initialize method if you want to get an object but not necessarily for some reason actually raise does this but there are actually legitimate uses for it as well and if you call phone you it actually doesn't print allocate so if somebody tells you that this is equivalent like me know like these are not equivalent because I'll be opt a lock is not really calling this method if you redefine it the funny thing is when I was running this code I I was playing along and you know trying to do the stuff redefine class new then create an instance run it and unsurprisingly this actually works like we call for new it uses cross new because phu nu is not redefine so it prints out the symbol new and then in france the initialize which prints out the arguments and then prints out the block I then decided to paste it into our be because I wanted to see what happens so when you run this in Ruby you get three lines of output when you run this an IRB things get interesting like up until here it actually makes sense because now classes return the symbol of the first medal of the last that is defined and then you paste an empty line and IRB suddenly create an object then you paste the line class foo and I are be happily creates for your objects then you write def initialize arcs block and I hope is like super happy for you and then it goes on and on and on like every single line and then when you call this this is the amount of objects IRB actually spins up just to communicate with you so please if you are doing those things probably you should in the first place but if you are don't do them an IRB just play with you know regular Ruby script you can we run it with the rerun gem and it's super fine copy constructor this is one of the things that I learned back from the gloomy dark C++ days and I never thought that Ruby being a very nice language would have anything like this but it actually has whenever you do something like this first this should call the initialize this shouldn't do anything visible because it's just like we reassign we assign another variables the same object but this actually underneath calls the initialized copy method and if you want to have a object that you can tap and you want to for example make a deep copy of its all dependencies like you have an RA and you want to copy it over to another object and also copy all of the elements in theory you should just initialize copy in the past I was implementing the dupe method just by doing martial law commercial lamp so please please please whenever somebody looks like they know what they're doing no like don't assume that people have any clue what they're doing we all learn all the time the Rose wonderful tweet a couple of days ago saying developers please tweet your google searches so that new comers can see that you know it doesn't get any better the interesting another interesting part is temp file is one of my favorites libraries in the standard library because not only creates a temp files but it also divides them by the time you finish so even if you have two tests that fail you don't have to clean up the temp files after them and you can see it here we require the tan Phi library we require we graph which is a way of creating references to objects wrapping objects in another objects which are weak references in a way that will allow those objects inside to be garbage collected I won't go into details how it's done you can if you go to actually ruby 1.9 simplement ation of we graph you can see that it's implemented in ruby itself which blew my mind that you can actually implement something like this in in robe itself that is not one hundred percent true but it's more true than for Ruby 2.1 and if you round as you can see that the week ref we crave wraps up that object and the only metal it adds its weak ref alive which we can ask whether the object still exists and you can see that the garbage collector run actually made the temp file go away but the temp file itself when it went out of scope when it was garbage collected it actually also deleted the path that is no longer it no longer exists the path because the time five no longer exists and the question is how does it do it how can we make objects that clean up after themselves without having the structures or something like this and it turns out that we can actually do this quite easy we can use object space defined finalizer and it takes as the first argument that takes the object and as the second it takes something that it can call to prague on which is either a proc or a method and whenever this object will get garbage collected this will get run if we do this we can see that we are initializing objects with this ID then we are running garbage collector this finalizar is being called and then we initialize another object and its finalizar is executed when the script ends so not only when we run explicitly garbage collection but also at the end of the scripts all of the final answers are being run and this is why temp files clean up after themselves if you ever do this which is like seems like even a cleaner way just pass this lambda on the define final final answer call you might get surprised that this doesn't really well doesn't really go as planned like around the GC but this finalizer like this one for the first object it's not round here it's actually run at the end do you have any idea why what what's different about this puts finalising ID exactly exactly so this scope has the reference to this object which means so this self is visible inside of this lambda which means this lambda keeps a reference to this self so it's not garbage collected that that's why you should always create a class method for this kind of stuff or anything order that doesn't hold implicitly a reference to South so that's something that I also learn the hard way the part about meta programming that I really like is all the hooks that let you do like cons missing which is like method missing but for Constance autoload please please could you not ever use it matts is promising to take it out of Ruby with at least since 1.9 and I really believe Ruby core will deliver on that promise it looks like super cool I remember when I learned about autoload I switch all of my projects use also load everywhere and I started running with multi-threaded applications and then I switch them all back to not using alcohol because as you can probably imagine when one thread out loads the other sees the given features not loaded yet class inverted is called when a sub class inherits us so we can actually know when another class inherits from our class and then track this the this also goes for modules so if you include a module into another module or class that module included will be called so we can know that we are being included and do some very bad things to the class that we are being included in to append features is what actually adds our modules instance methods to that other class or module so you can really find it you can do some additional work there if you want to and it's the same with module extent and extent objects race does it vary a lot of this especially with the recently introduced concern in class methods as you can see I'm not a big fan of the concern pattern and I don't think I don't mind it but I also don't think that saving those five key strokes with self dot are that much worth to introduce this whole pattern of having a separate module with class methods and also if you have a class which you extend with class methods and also extend with instance methods then maybe those are actually two different use cases that should be handled by two different object types and the last part is you can actually track when methods are being added also as well regular methods as singleton methods and you won't believe what happens when you call like method removed method singleton method removes and so on so all of those calls you can actually track inside of Ruby you can act on it you can these are also there are sometimes those really really dark gloomy days when you need to figure out what went wrong and this come up if if those come up then you're really in a tight spot but they also can save you a lot of debugging especially with those things that include a lot of things around if you have a method added hook that just prints the method name there's always underscore underscore methods underscore that has the method name and then print the parameter that was passed and you can see that it's calling method added with the parameter being the symbol of this metal the funny part is if you do this with a single method added it will print this and this is one of those things where r a ruby registers this callback and then notifies itself there's a new single method that is called single method added so this first two lines are from this callback being called on this code back being defined ruby is like very diligent when it wants to which is not always please please please don't use metaprogramming younger the prime example for me is the rescued from it lets you on a class level rescue all of that exceptions of a given type from all of the method calls which i can somewhat understand when these are controllers and you really want to handle like database errors in one single place but there are cases were you know it looks like intercourse come from if you never used in the cow which you probably like if you did please speak to me like i would love to meet the integral user it's one of those esoteric languages that shows you how not to do languages and come from is this idea opposite to go to so go to makes if you encounter go to it says you jump into an unconditional usually to another part of the program come from it's the other way around if you come to this part of the program some other part can say come from this place and you will jump there so rescue form is the come from of rails in my opinion and this is what we probably end up experiencing as the result especially if you like doink retry or raising your own exceptions from rescue from and you have no idea what's going on because the rescue from is usually like five files removed implementations the the third part the the language has many implementations there are many platforms which runs on and there are many engine engines like an RI j ruby ruby news maglev and so on and so forth and i will only talk very briefly about the MRI we already referred this in GC start which tells the implementation that to begin the garbage collection unconditionally and there's also GC stop so you can do these things where you stop the garbage collector do a lot of work that creates a lot of objects and you really don't want the garbage collector team to interrupt it because for example you're making a response to your user and then you run GC start unicorn is known to do this which is called out-of-band garbage collection runs which basically means when unicorn is providing the response the HTTP response to your server it stops the garbage collector so it's never like suddenly the response takes 15 seconds longer because Ruby is cleaning up after itself and it also works in other examples like an at my university work I have some pieces of code that allocate a lot of objects and it's actually much more efficient to clean them up and one go afterwards object space in general do read the documentation it's not the same all ruby implementation so if you're Noble and no no I Ronnie here if your noble goal is to create applications that run the same on all review implementations be very very careful and use object space but it's a home of ID to ref and weak map which are if you have object ID the object space can give you the object that this ID belongs to weak map is what is now the implementation of we graph that the thing that lets you reference objects but still garbage collect them there is a counter objects method that returns a hash with the number of given object so if if your application suddenly creates tons of strings you can actually see where it does it and how many strings just by learning count objects if you think that it creates a hash with the statistics so if you think like it's a bit fishy because this method actually creates a hash so does it increment the hash talent in itself how does it work you can actually pass it an existing hash including an empty hash and it will populate that hash with the data so it won't create a new hash at that point so this is like really really well thought out each object which we seen at the beginning we iterate over all of the objects you can actually pass it a class name and it will only yield the given given objects give classes objects for you and define finalizar we already knew and please watch our Patterson stocks including his lightest from our combo it's not up yet but it was a really really good example how he sped up rails quite far just by using the methods available in an object space and seeing like which parts allocate a lot of unnecessary objects we craft which I mentioned briefly a couple of times it's this a formal objects that might not be there later you basically pass some objects to regress constructor and it will hold to that object but it will let it to be garbage collected and the contemporary Ruby versions it's implemented using wit map which is implemented in C but don't look at the source of we graph from before 2.0 to see how you can actually implement it in an Ruby whitcraft was Ruby like pure Ruby back then the only thing it actually cheated a bit was it off loaded the little piece of work to object space but it's actually quite nice and when I tweeted because I I always treated week we crave has this like my favorite startled library but at the same time nobody would use it in any same project and then Constantine was like first obviously Constantine but Constantine was I actually use it in my sermon which is a project that you should really check out if you haven't already but he actually has a good use for weaker have back then he actually uses weak map directly sao paulo calls the last and my favorite part about ruby is the protocols which are ruby is a dynamic language so in general you are not supposed to be too much tied to the object types or classes itself more to the methods that those object response to so protocols are the basis of ruby object interoperability in my opinion they are the cornerstone of duck typing because in general when you write ruby or should be more interested whether you get an object that behaves like you would want it to rather than whether it's an object of a given class it might be worthwhile to make your objects conformance to some of the protocols that will be thus and let's see let's see what the example protocol might be type conversion is probably the most known one you can call explicit metals like to i 2 s 2 a and they will switch they will turn a given object into that number if they are implemented properly and you probably should implement at least two s on your objects but this is also like super liberal if you have a string that begins with a space and has 12 monkeys in it you can call to eye on it and it will give you 12 you know without batting an eye on the other hand there are those methods to end to esther to airy and so on with the three-letter acronyms i think to hash is the only one that breaks this convention which are used implicitly inside of ruby to convert objects all the way that is much more strict so you can call to end on a float but you cannot call to end on a string because these are fundamentally different types and if you want to make objects that should behave like ruby core types you probably should look into implementing those methods in a same way and then there's the last part are all of those uppercase or title case methods that are implemented on colonel so they look like they're this integer bracket or string bracket which are the best validate or enforce input types because they will actually accept a string and turn it into integer as long as it's actually makes sense so a string that contains only digits will get turned into integer a string that contains 12 monkeys will raise an exception so kind of depends on what you want to do with your objects you should use some of these and do read of the grimms again a confident Ruby it's a very good book and it's a good book that very well explains those things fun wit binaries did you know that first we can call toast we can pass a parameter to string and it will turn an integer into a string with the given base so 35 and base 2 is 1000 11 you can call to eye with a base and it will interpret that string as an integer in the given base but you can also calls for brackets on a number and it will tell you whether the bit at that position is a 0 or a 1 so 35 is 1000 11 and going from the right side this is bit 0 this is bit 1 so 35 square brackets 1 is 1 and this is the third beats on bit number two obviously computers so this is 0 you might think that this is like super unnecessary very good reaction but if you happen to work with sets of integers which two large extent my PhD was about you don't really want to well you can treat them as sets of integers but in a set the numbers never repeat so you can actually instead of having a set of integers you can have a huge integer that has only the given bits set so if you create something like this and I will try to go through this really quickly but the Bob for starters you can create a set of integers in n my PhD it was a block so I call this module at B and then define this square brackets method that will contain one and two it will give you the number six that happens to be to have the representation 110 so it has going from the right side the zero is not in this set but the one and two are if you have a set with 0 1 and 5 it will be 35 because the 0 is there the one is there the two is not 3 is not for it's not and the five is there and you can actually index those sets with those numbers and if you interpret the results properly you can see whether this given number is in this set because it makes a bit more sense than calling this on a literal and the way I implemented it this way because if you haven't read about module function do read about this if your modules have like South not something methods do consider whether they should have said something or whether they should have things that look like instance method but are actually prepared with module function this is like super useful I won't get into details but do they look into this and if you want to create a set of sets of integers you can create a set of integers like those magic integers with the bed set one of the 14 own protocols is what equal or as I ve likes to say equal a double equals equal and hash do so equal is for identity whether two objects are the same double equals are usually for value equality so if you have two objects with first name and last name if they have the first the same first name and last name they might not necessarily be the same people but you have if you have two addresses that have the same street name city name and country then they probably refer to the same place actually so this is like the simplest thing if you want to see whether something is should have value identities or sort of like identity semantics or value semantics equal is called for hash key equality whether a given element is in a hash and hash is this shortcut that is called before equal is actually called so if you can very quickly check whether two objects should be the same key of a hash the way it actually happens is that the hash methods is first called on them because it's assumed that it will be much faster than actually equal and only if those the results of those hash calls are equal only then the equal checks are performed otherwise if these are different these two are different then those objects are considered not equal and the equal is not even cold how they learned about this there was a bug in Ravi Ruby 186 were big nose which is this Ruby's version of storing very large integers that are larger than what can be natively stored in your system more or less the hash would not hatch on the phone way so if you had a very large number which was a big num and you have the same number that was another big name they will actually have different hashes which means if you put them in a set you would suddenly have a set with this number twice like three months of my PhD down the crop so very fun things I learned this you know going through the source please don't shy from using range range is this wonderful type that lets you specify well arranged obviously dates can be used for a range this is my pet peeves that people don't use it if we have a contract that has a name in days and we have Baruch overcome Andrew becomes Portugal and let's say we also have a conflict this is an example where we will use the HTML method as a vessel for the innumerable protocol then we can do something like this we have each conf and meritorious to each please read up why this makes a lot of sense those sites who are actually already up but will be linked at the end there is a wonderful post from the Arkin c company in poland that explains why this line is super important so if we have this conflict then we can actually call each conference iterate that's not like super exciting but if we call another protocol if we actually do shouldn't be there sorry if we actually make 2's Matt up then we can do something like this which is we can say that for each element take the puts medals from the colonel and apply to it the elements of those which are in turn turns 22 s so this this happens if we have a finished predicate that says that comfort conference is finished if it's aunt is before today then we can use the partition on our conflict so our confess is our own class is not an RA but we can still thanks to including kandemir able we can still use partition on it and see like which conferences are done and which ones are not another very well-known protocol is the spaceship operator you define a method like this and then it basically should return minus 1 if we are before in the sorting order or smaller than the other other object one when larger and zero if we're the same so basically what if the conference begins if we begin before the other conference then we should be sorted first in its later then after and if at the same day like jruby convent you come then the end date should be compared so this gives us sorting but what happens if we confer with an on conf like what will happen this will blow up because the other object does not have dates and it's not really that good if your objects blow up and some someone tries to compare them so one question is what happens if you comfort compared with the nomicon and the other is why the question mark methods not always return predicates like not not always return boolean's and the reason for why I mentioned both of those is that you should implement the spaceship actually like this so you should return nil if the other object is not your class because then all of the comparable methods will know that this is a comparison that cannot be made rather than this blowing up in your code and second you can change on zero calls because this spaceship operator for those dates will return either 10 or minus 1 and if it's nonzero then you can go further and check further if you include comparable you get the less than less than equal and so on and also the between ok I don't have enough time to go through call too much so I vary with a bit of foresight I didn't put an examples but call it a protocol that you probably know and you should use probably more often which basically means you can replace if you have objects that responds to call you can replace those objects with lambdas in your test or default values to proc lets you create a prog from a method this let's first read this for a bit class object various methods pretzel method and they'd snap pretzel asset it took me like 10 minutes to figure out how to actually make this run but never do this but is what it does it actually calls this method on this object with arguments from this array subsequently which is why we love Gary born Harlan should all follow him my favorite and last protocol is triple equals this is the thing that we've seen something like this before already how does case know what to do when it has all of these things and it actually all supports this so it actually uses like it seems like it checks the quality but it also actually can run a reg ex against it I input and it actually can check the class it can see that a number is inside of a range it runs Prague's Anderson else class with which should also be used more often so the reason why it runs like this is it doesn't check whether this is equal to this it actually checks whether this it's triple equal to this and it actually like really really works and by default the triple equals is uploaded to double equals which means like full is double equals well bar is double equals bar so it runs but for reg accepts regular expressions it's re assets to match so for this it actually checks whether this match is that for modules it checks whether this is a kind of this for angels it offloads too between so it changed whether this is between this range and for proxy just to call which means whether it calls this prog with this input really do consider giving your objects triple equals because then you will be able to use it in here and also for example in the grab this is why grabbing with a range of our collection works because it checks whether the objects from the collections are inside of the range protocols do use them they allow for proper object interoperability a lot of Ruby core staff uses two paths on internally which means you can use pet names you can use files but you can also use strings doubles can be common classes if your repositories response to fetch then you can mock them with you know hashes there are a lot of many many other protocols and do it up on course I didn't have the time to cover it here but do read up on this so to wrap it up please do dive into Ruby core and dogs there are if only for all the wonderful morsels of you know magic numbers in their toilet object space see where your code is creating tons of objects may be unnecessarily read up on Ruby's protocols read exceptional Ruby and confident Ruby form of the read metaprogramming Ruby to like I will soon Potter is my second like work with meta programming Ruby puter as the two most important books that i read about Ruby so please read these 99 bottles of opie will be a wonderful book with from Katrina and Sandy mats so do sign up for it it's might be showing up sometime soon but ask katrina at me do it on a browsers post on at sign point there are really good things about pathname but also about using protocols in Ruby follow Ruby's on library Twitter account follow the Ruby strings to their account and if you have nine dollars a month that you can spend on something sane then spend it on Ruby tapas which is I think the best screencast series that is currently maintained five minutes screencast twice a week actually screencaps that you can watch and not safe or later and never watch again like you do with all of the screencasts thank you so much the sites are here piatra will give the other tag so i had to soldier through those slides myself but thank you so much and enjoy your lunch is anyone's brain not fired enough to have a question God someone's grab a question one at the front here little one tyonne on one of the first slides you showed this exception wrapper and i was wondering because in the first line it says class something equals if this is oh yeah that it's in from today until this too much but this is so this is basically in this case it was module but actually thanks for this question it wasn't scripted it's this is how you can create new modules and this is how we can create new classes without the syntax of class foo less than bar ends so if your classes has if it will end up having an empty body this is one line of creating a module or a class I'm not sure whether you can extend objects with classes i would have to check this is one of the things that I keep checking every second month and forgetting the day after so yeah this probably doesn't make sense because you can't inherit a module can inherit yeah it should be class no sorry yeah good point at the end the class keyword at the beginning works and yeah there shouldn't be a class keyword okay thank you there's nothing three things to fix in the slides thank you so much as a questionnaire here on the left let's show something like we are sponsored hi great speech I enjoyed it so in the beginning on one of the first slides you mentioned reading a numeral innumerable Darby now the gym did you we're thinking like docs on it because i think it's not really a ruby file but like implemented in see you mean the week ref or another the innumerable only on my blog the quote yes yes the pill ok so i would have to check is really florian everything he says you should alright so okay hey thanks okay that's it thanks it's not in cnj Ruby it's not an senior vineyards like haha what does that even mean to be in see there's another question this behind I was wondering about the difference between initial scorpion you do methods look how do I know which one should I over right and what is the difference initialize an initialize copy yes yes ok as well as the difference to initialize coffee on the jig methods so this will be called when you call dope which is supposed to give you another object as a duplicate of that first object without any shirt stays in theory so if you have an object that holds on to an array that has an RA it's inside then if you create a duplicate of that object then in theory that other objects should not have that era should not have any references to the first objects are a switch which you implement either by initialize copy or if you do it like I did for years you just redefine object dope to marshal self to a string and then run Marshall it which gives you the same effect unless the object is not marshal in the first place so basically if you have a huge tree an object that holds a huge tree and you want to create a copy of that tree that doesn't share any notes for examples than you would it would redefine initialize copy and you would do all the copying deep copy of the members of that object in there it's actually yes one more question awesome your water hunter nearly started going to lunch hello how do you deal with when you're redefining triple equals and throwing it into case statements how do you deal with like the principle of least surprised or however that is called like with teams or even with yourself two months later it's usually the co workers who are faster but at kind of depends so you should be you should be like super worried with like all of what you heard here like first triple check it but also here I think yeah but I think the way the Corps does it it's actually sensible like I can like all of those cases obviously you probably wouldn't write a case statement that would assume that it gets different kinds of objects because that's like super rare but like all of those cases actually makes sense and I can see that there might be a case where it makes sense for you as well for example you know whether whether conference is included in some set of conferences to bring up the example but yes like every time you do matter programming or every time you use one of those protocols make sure that you're using and not abusing them but I think that might be valid cases where triple equals should be redefined and I really like how elegant this looks I guess documenting is around Amy's there's probably no hard and fast rule yes it never is no excellent thank you very much to all morn thank you sir so it's not lunchtime your lunch is sponsored by mail jet so if it's good you can thank them if it's rubbish you can gain of words it's a buffet it's downstairs here so just go and just help yourself to whatever you want if you have any dietary requirements please find one of the guys in the mood Portugal tops and they will dig out the white food for you I'm going to going to put some clothes on I'll see you back here at two forty-five thanks