05:02 - Incremental Performance Improvements
06:50 - VM Optimizations
08:51 - Keyword Arguments
18:13 - %i
21:13 - Unbound methods from a module can be bound to any object
25:30 - Prepend
35:00 - Stack Sizes
36:47 - Refinements
41:25 - Lazy Enumerables
49:38 - Lack of updated/refurbished standard libraries
52:46 - Garbage Collector
56:46 - Improving your window into the inner workings of Ruby
58:33 - to_h
01:00:06 - Installing Ruby 2
01:00:55 - Can a language keep evolving and growing?
The Rails View by John Athayde and Bruce Williams: Read along with us! We will be discussing the book with John and Bruce and the episode will air on Wednesday, May 8th, 2013.
Behind the Scenes with the Ruby Rogues
DAVID: <Sigh> Lord. More programming crap.
[Hosting and bandwidth was provided by The Blue Box Group, check them out at BlueBox.net.]
[This podcast is sponsored by New Relic. To track and optimize your application performance, go to RubyRogues.com/NewRelic.]
CHUCK: Hey everybody and welcome to Version 2.0 of the Ruby Rogues podcast. This week on our panel, we have David Brady.
DAVID: I am fully backwards compatible.
CHUCK: We have Katrina Owen.
KATRINA: Hello from Denver.
CHUCK: Avdi Grimm.
AVDI: Hi from Pennsylvania.
CHUCK: James Edward Gray.
JAMES: Henceforth, I want to be known as Rogues 7 of 9.
CHUCK: Josh Susser.
JOSH: My version number can't be expressed as a rational number.
CHUCK: And I’m Charles Max Wood from DevChat.tv. This week, we’re going to be talking about Ruby Version 2.0.
JOSH: It’s about time.
CHUCK: Yeah. When did they release it? A couple of weeks ago?
JAMES: Yeah. It came out February 25th on Ruby’s birthday, I believe.
JOSH: And I think the first mention that Matz made of Ruby 2 was 11 years ago. [Laughter]
JAMES: That was awhile.
CHUCK: They should have followed Reg’s example and just gone to 10.0. [Laughter]
JOSH: I think they just should have confused everyone and got right to Ruby 3.
DAVID: Ruby 3000.
JOSH: So, what is this Ruby 2 thing?
CHUCK: It comes after Ruby 1.
JOSH: Okay. [Chuckles]
JAMES: It’s the next major release of Ruby 2.
JOSH: If Ruby 1.8 was good enough for Mom and Grandma, it’s good enough for me.
DAVID: So, I have a question just to fill out right now because we’re running into this with a client. Is Ruby 2.0 patch level zero ready for production?
CHUCK: That was fast.
DAVID: Because they're skittish about it. The standard skittish response is, “Well, we never install patch level zero.” And I'm replying that, “No, no, no. 1.92 and 1.93 and 1.91 were their release candidates.” I mean, 1.93 was the RC for Ruby 2.0. So, Ruby 2.0, ready for patch level zero, ready for production.
JAMES: We have two questions here, I think. One is WTF Ruby’s version in system which I have made before I [inaudible].
JAMES: And number two is, is Ruby 2 a significant enough re-architecting that we’re going to see a lot of version no-bugs. I think that one’s pretty interesting. Let’s try that one first. But I say no, I don’t think you will. Ruby 2.0 is not a drastically incompatible. In fact, it’s almost fully compatible with 1.9. There are some minor changes that made it not. But it’s super compatible. It’s mostly a refining of the VM. So, we’re talking incremental improvements everywhere and stuff. So generally, the rule is 1.9 stuff works and works better. So, I don’t really think you're going to see a ton of 1.0 issues.
JOSH: James, I won't contradict you there but that said, I've seen a couple of tweets and blog posts about people discovering at least minor issues in Ruby 2 that have big problems for them.
JAMES: So, we’re updating right now at work, all of our systems. And we have a large infrastructure made pieces and stuff like that. But the upgrade isn't perfectly seamless. We have seen some minor stuff. But, I mean, this is minor stuff. Like I think the two main things you're going to run into upgrading, one the default encoding switch from US-ASCII to UTF-8. So, sometimes, depending on how you use regular expressions and stuff like that, there can be a scenario where you have an encoding issue now that you didn’t have before. It’s generally very easy to fix. I mean, it’s not usually a problem. And yehey for UTF-8 for being the default anyway. And the other one is in strings and such, things like chars, bytes, code points, stuff change such that they no longer return enumerators. They return OAS that might cause you a slight problem depending on how you are using them. But those are probably the two largest incompatibilities.
CHUCK: So, you were talking about incremental improvements. And to me, an improvement, it really depends on what you care about. So, are these improvements to like the API so that it’s easier to use or are these improvements in performance? I mean, what kind of improvements are we talking about here?
KATRINA: They're actually performance, I would say. The two things that I notice the most were -- or not notice because I haven't used it extensively. But the garbage collection is significantly improved. And that’s actually pretty exciting. I think we should probably talk about it. Another thing is the requires, the way that things get required is also greatly improved, I believe.
JAMES: There's one more message performance improvement and that’s that method dispatch has been heavily optimized.
AVDI: Do you know any of the details of the optimizations?
JAMES: In the method dispatch or the requires for the garbage collection?
AVDI: Method dispatch.
JAMES: I don’t know. I know that it’s mentioned -- I watched Peter Cooper’s Ruby 2.0 Walkthrough videos. It was a kick starter project that I backed and he’s fully doing them out to us. So, it’s not out in public yet but it will be. So, just keep an eye on Ruby weekly until it pops. But he mentioned that basically, there were something like 11 cases or something that method dispatch had to work through when it was working out of how to call a method or whatever. And that’s been trimmed down just so basically, it has less scenarios to work through and it works faster.
JOSH: I saw Koichi give a talk on Ruby 2 at Ruby Conf last year and he talked about a lot of the VM changes and optimizations. Here’s a link for that on YouTube in the show notes there. And he talked about some of the optimizations in the VM. I think they're doing more with inline method caches and byte code level optimizations. He walked through a lot of the very particular cases and code paths. And showed, “You know, we’re taking this from 700 instructions, and now, we can do it in 85,” that kind of thing. So, if you're really curious about those optimizations, that’s a good watch.
JAMES: Generally, across the board, I think you're going to see some speed up. Most people are noticing Rails launch time has improved because again, more optimizations to the whole requirements set, requiring stuff like Katrina said. And the method dispatch is going to affect the entire system. So yeah, it should be significantly faster and noticeable faster.
CHUCK: Nice. I want to kind of go back to, you were talking about Peter’s video on Ruby 2. I really like to get my hands on it. His Ruby 1.9 video was really, really helpful in understanding what goes on and what’s going on with the new version. So, I just can't recommend that highly enough. I'm excited he’s doing another one for Ruby 2.
JAMES: Yeah. It’s really good and my complaint for the 1.9 one is it was this like massive 3-hour slog. So, you really had to do it for it. But 2.0 one, he broke into chunks. So, there's like a video just on keyword arguments, for example, and it’s like six minutes or something. So, you can take it in chunks and look at what's interesting to you and stuff. So yeah, the 2.0 is even better than 1.9, in my opinion.
DAVID: I'm really excited about these keyword arguments.
JOSH: Me too. It seems like there's a couple categories of things in Ruby 2. There's things that are like keyword arguments that change how the language itself is because that’s an actual change to how the language works. And there's a couple of those. There's sort of implementation efficiency things, like method dispatch and garbage collection. And then, there's like API level changes that are adding nice features and functionality. But those are things that probably could have been done on 1.9 but they just decided not to for whatever reason.
CHUCK: So, can I ask a question about the keyword arguments because it looks like they're optional. You don’t need to use keyword arguments. It’s just kind of a convenience thing that sort of does the hash notation behavior stuff [inaudible], get the options and reference it by key. Is that more or less what it is?
JAMES: Yes. It is actually backed by a hash but it puts it into local variables. Peter has some really good examples of it in his videos. Basically, it just takes some super common cases in Ruby like how we would make that last argument options and then use the kind of syntactic sugar that Ruby has that treats the last parameter as hash-like as long as it looks like it. But then, you’d have to do things like write if you wanted defaults or whatever. You’d have to merge those defaults into the hash because if you set it in the hash in the def line, then it would just get overwritten by what got passed in. Whereas this, you can set a default per item and then if that item is passed, it gets its value. If not, it gets its default. So, it basically just really shortens it up and really cleans up very common method usage in Ruby, much like you see it all throughout Rails with the various methods that take lots of different keywords on all arguments.
KATRINA: I've seen some discussions about using options in method arguments where just ones out of the argument is that you're adding complexity like nothing else, like you're increasing the entity of the method even though it might not look like it. And that this can create a lot more path through your code. You guys think about that at all?
JAMES: Yeah, absolutely. I mean, I think that it’s a really good point. Even Sandi had talked about that when we had her on. Like, what was her rule? You can't have more than four arguments and throwing it all in a hash doesn’t make it any better.
DAVID: Yeah. No cheating, she said.
JAMES: Yeah, no cheating. Right. But you are trading like kinesis of position or something for like kinesis of name which I think we tend to prefer. I think it can clear things up. But I think you're right that it leads to -- the tendency is, “Oh, I can throw one more key in that hash.” And keyword arguments probably helps with that in a lot of cases and that to throw one more key in that hash means you got to go up there and put one more keyword argument on that method unless there is this little piece syntax. But if you have to go out and put that other keyword argument on there, then it’s like the same as if you put another argument on there. So, you'll feel that pain more.
DAVID: I'm kind of excited by then because I fell in love with named arguments when I was playing with Smalltalk. And there’s a kind of a cultural idioms in Smalltalk that you use the named arguments to turn the method call into, or the method send rather, into something that reads semantically, reads well. And right now, the examples that I'm seeing of keyword arguments are kind of arbitrary. It’s just like, look, we’re not really hiding the fact that this is backed by a hash and they can come in any order and whatnot. But I think if we see some Smalltalk people get in here and start to establish a culture of your keyword arguments need to semantically scan so that you can have point.distance to and then the to is to: some other point. That’s a lot more readable and a lot more -- and it actually reads out like, point.distance to other point instead of distance_to or whatever.
CHUCK: That’s the approach that objective C has taken. And the interesting thing, the difference, I guess, between that and what we got here with the keyword arguments is that those keywords that define different pieces or the different arguments that you're passing in, are actually part of the signature. So if that key is different, then it’s a different method call. And in Ruby with the keyword arguments, it doesn’t appear to be the case.
DAVID: It’s not.
CHUCK: But at the same time, I really do like that thinking of, and this is what David is saying is that, it is part of the entire description of what the message is. So, it’s not just go to some point, point: blah…blah…blah…, but it’s actually go to distance and with distance@angle and then you can do things that way.
JOSH: The thing that is a little confusing when you get into that kind of keyword selector, I guess, on a message is, what is the equivalence between selectors? Because it seems like -- okay, so this is going to get a little tricky object-oriented detail stuff. In Smalltalk, you have this two selectors like you're saying. And if they have different keywords, they're actually different method selectors, they're different messages. So, if you have a super class that implements ‘do with’ and then a subclass that implements ‘do with with’. Those are completely different methods. One doesn’t chatter the other. But with the keywords, you can, I believe, in Ruby, you can rearrange the order of the keywords.
JAMES: Yes, that’s true.
JOSH: Yeah. So, and in some cases, the keyword arguments can be optional.
JAMES: Yes, also true.
JOSH: Right. James, how does that affect equivalence between method selectors? Does it discriminate based on the set of keywords or is it only on the main method name?
JAMES: Only on the name. Just like Ruby always has been.
JOSH: Okay. So, that’s a bit of a difference. But I think that helps keep things much more tractable and sane.
DAVID: I like keyword selectors. But at the same time, it would have made it a very different language.
CHUCK: So, my other question is you have this wrap on Ruby 2.0.0 in detail that James shared with us and we’ll have a link to it on the show notes. It says wrap and then has ‘before and after’, can you just pass just regular string in there without saying ‘before and after’ and will it work? Or do you actually have to name the arguments?
KATRINA: The way that they're defined there, they're given defaults so that if you don’t pass them in, the default from the arguments look fully used.
CHUCK: Okay. But if you pass it three arguments, will it treat the second argument as before and the third argument as after?
KATRINA: You actually have to specify the keyword.
JAMES: Yeah. If you don’t pass ‘before and after’, then they don’t go. They have to be named.
DAVID: For the listeners that are not looking at this webpage, we’re talking about positional arguments and we’ve got some keywords that are called before and after. And those are actually the names of the keywords. If you're wrapping a string, token that is supposed to come ‘before and after’ it -- when we say ‘before and after’, that’s what we’re talking about. We’re actually reading the word off the page. We’re not actually talking about position in the order of the arguments.
CHUCK: And the question basically was can you substitute? Because they're put in a specific order and so I was asking if positionality and indexing by keyword were interchangeable and they're not.
DAVID: I like it if you specify it as a named keyword that you have to call it with a named keyword. I like that. I like that.
JOSH: Yeah, yeah. I think that’s crucial. Keywords are keywords. [Crosstalk]
CHUCK: Go ahead, real quick.
JOSH: I was using the big word, man. I'm saying swapping kinesis of name for position just gets you in trouble.
CHUCK: Yeah. I want to move on to some of these other features. We’ve been talking about this one for a while and I want to get through a few more before we end the show. What are some of the other features of Ruby 2 that you guys like.
JOSH: I really like %i.
JAMES: Yeah, that’s a great one.
JOSH: This is -- I get to two of my own horn a little bit here. This is my feature. I think I made a tweet saying how much I wanted this feature and within a few hours, Aaron Patterson had a patch for it.
CHUCK: Then I'm going to give Aaron the credit.
DAVID: That’s cool.
JOSH: Hey, he gets the credit for doing it but I'm the idea guy.
CHUCK: Oh, there you go.
JOSH: And I’ll explain the mysterious choice of the letter ‘I’. For people listening along, the %i is like %w for making an array of strings but it makes an array of symbols which is something that you want to do all the time when you're like setting up a before filtering your controller and you want to give it a list of symbols. And it has the lower case and capital versions for playing and interpolated. Basically, this is how symbol array literals worked in Smalltalk and I say, “Hey, I want this in Ruby 2.” So now, we have it in Ruby 2.
CHUCK: So, I have to ask, do you know how they pick these letters? Like %w for strings and %q for…
AVDI: I do.
JAMES: I do.
JAMES: So, let’s see. Josh, me, Avdi, anybody else have guesses on %i?
AVDI: Josh, this is your features. So…
JOSH: Yeah, I know what it is. I picked it.
JAMES: Yeah, he gets to explain.
JOSH: So, we can't do %s for symbol because that was already taken as %s in Ruby basically defines a single symbol with funny curly brace quoting. So, the other way that you create a symbol from a string in Ruby is you call the intern method on it which means that…
JAMES: Wait. It’s interesting to say that, Josh. That is true but I never see that in code. Everybody uses interns alias 2_sym. That’s the one I see.
JOSH: I know.
AVDI: That’s more recent.
CHUCK: When it’s done being in intern, is it going to get a real job?
AVDI: When I started writing Ruby, it was all .intern. If you want to turn a string into a symbol, it was all .intern.
JOSH: So, intern is how, 2_sym is what. So, you say, “Oh, I want this to be a symbol.” Intern is how you get it. But anyway, the %i comes from ‘I’ for intern. I only had a moment to come up with…
AVDI: And that has nothing to do with low paid entry level workers.
AVDI: I believe it is short for internalize which we won't even -- that’s too long a discussion for this.
JAMES: Yeah, it’s a mess too.
AVDI: Goes back to Lisp, at least.
CHUCK: Are there any other features that you guys are excited about?
AVDI: I got a favorite feature.
AVDI: Unbound methods from a module can be bound to any object.
JAMES: Yeah. That’s awesome.
KATRINA: So, before this, Avdi, just correct me if I'm wrong. Before this, you had to bind to like top level, the top object, the top level object. And then, you could bind it to anything whereas now, you can bind to a module.
AVDI: So Ruby has this concept of method objects where if you call .method and give the name of the method on some object, you can get a method object. You can also call on a module or a class, you can call .instancemethod and get back an object which is an unbound method. And that unbound method can then be bound to another object by calling .bind. And then from that, you get a method object which you can then call .call on. And this is all stuff that really is only useful when you're doing sort of infrastructure work. You're creating interesting new infrastructure for other people to build on. It’s not something that you're going to haul out when you're just writing application code. But up until now, if you had like a Module Foo and you said .instancemethod on it for one of its methods and then you tried to bind that method to a class bar or an object of class bar and call it, Ruby would object. Ruby was very, very strict about the type of the object it’s being rebound to has got to be the same. And there’s this horrible, horrible kluge that I've seen to get around it where you would actually briefly define a method on basic object, capture a reference to it, and then remove that temporary method once you’ve captured the reference to the method object. And since everything inherits from basic object that effectively gives you a method object, an unbound method which can be bound to anything. But now, they relax that for modules so you can take an unbound method reference for many modules and then rebind it to anything.
JOSH: So, why is that cool? I mean, what kind…
DAVID: What do you use that for?
AVDI: So, I've been playing with this a little bit. And I already had some, I’d already run into this limitation and some of the stuff that I've been playing with. Now, I mean, it depends on your definite of practical. I like abusing Ruby. I like kind of pushing it to its limits. I did an article series recently. One was in practicing Ruby and then the sequel was on my own blog about implementing prototype-based inheritance in Ruby. And I ran up pretty hard against this limitation as I was looking at different ways of implementing this. And so, one thing that I kind of just played with a little bit in preparation for this episode was re-implementing some of my code for that article using these rebindable methods from a module. And it works and it’s actually a bit more full featured than the technique that I've gone for. Something else I've played with a little bit this morning was like a DCI kind of thing where I had the ability to give an object a role and then take it away again. Whereas typically, the implementations of that you see examples of you're doing like object.extend which extends in the object with a module but then, you can't take that away again. It’s going to be extended with the module until the end of time which may mean you wind up with some other code that has dependencies on that extended behavior which really shouldn’t. And so, you can do some fun stuff where you can almost sort of kind of simulate the ability to mix in modules and then un-mix them again.
JOSH: Alright. So, you're talking about fairly low level language hacking and maybe framework construction. But this isn't the sort of feature that you would recommend people using their application code?
AVDI: No, definitely not application code stuff. But it’s certainly, it may clean up some framework implementation.
JOSH: I can see that.
AVDI: And there’s some nice ways that it plays along with the Prepend feature. But somebody else can talk about Prepend.
JAMES: Let’s do it. Who wants to talk about Prepend?
JOSH: I’ll try and explain Prepend. [Chuckles]
JAMES: Go for it.
JOSH: I think that’s half the battle, right?
JOSH: It serves the definition. Okay, so we all know how inheritance works in Ruby. You have sort of straight line, single inheritance. And then, we have modules that you can mix in, giving you effectively module#prepend inheritance. But the way that happens is that everything gets linearized into a straight path from your class all the way up to, I guess, basic object is how it is in Ruby 2. And given that it’s Ruby, you can always reopen a class and monkey patch it and add stuff into it. But if there's a class that you want to basically you don’t want to add -- let’s see, you have a class and it has a method, we’ll call it Foo. And you want to change what it does with Foo by adding some functionality to it. Prepend lets you add a new module worth of behavior just like you're mixing it in. You're including that module but it does it sort of in a pretend invisible sub-class. So, it’s putting the methods in the object in front of the methods in the class. So, if you have a Foo method in this module and in the class and in its super class, and you do prepend of your extension module, and then you send Foo to an instance of that class, it will hit the method in the prepended module before it hit the method in the class itself.
JOSH: And this lets you do the kind of thing that you are using alias method chain for years ago. But it’s a lot cleaner and this is Yehuda-approved.
JOSH: A fair amount of confidence but it won't do ridiculous things and break stuff.
DAVID: So, the advantage here is if you have 15 classes that all use a module and you want to inject something between those classes and that module, prepend will let you do that.
AVDI: Well, it will actually let you put stuff in front of the classes on methods. So like, one example I’d give is if you -- let’s say I write a macro called memoize and you give it the name of a method. And it will magically turn that method into memoized method for a given set of argument of inputs. It will save off the results somewhere in the hash or something. So, if it finds a match for the arguments, it will give you the memoized result instead of calculating it again. And so, you define your method, your expensive method inside your class and then you say memoize and pull in method name to turn that method into a memoized method. Previously, you would have had to either do an alias method chain in order to do that where you alias it to an old method name and then, write a new method that calls that old method name. Or you’d have had to do some crazy stuff where you capture an unbound method, kind of some of the stuff I was talking about before. You capture an unbound method, delete the method, then overwrite it. But you include reference to the captured old method in the new method that you meta-program in. This lets you meta-program and do that meta-program in a cleaner way where you create a new module for that memoized version to go into. And then you just prepend the module to the class. And the old method is still there and your new method just gets hit first in the lookup before the class its own method. And then, that method that gets hit first can call super to get at the original behavior which is probably the cleanest way we’ve come across yet to do that kind of macro method rewriting. DAVID: It’s almost aspect oriented.
AVDI: It’s getting towards some of the languages, some of the OO languages where methods could choose how to delegate to other implementations where you could say, you could choose to forward to like a higher level method or to forward to a lower level method to a more specific method, or version of this method.
JOSH: But I like this because it doesn’t really break the way that people think about objects and messages.
JAMES: If you consider the lookup line, the lookup path, the method to be a straight line, the only thing that’s changed, you always had a way to stick something behind the point on the line. Now, you can choose if you want to stick it behind the point on the line or in front of the point on the line. Nothing really changed. It just gave you a greater flexibility.
JOSH: So, the experiment that I would like to do that I haven't been able to play with yet is if you have like a couple -- if you have an inheritance hierarchy. And so, like you have A at the top and then the subclass is B and then the subclass is C. And then, you go up to B and you prepend something on to class B, does that get inserted between B and C?
JOSH: But does that get inserted between them?
DAVID: That’s what I mentioned by this would let you basically inject a flight fleet of module that had 15 subclasses, this would let you inject at one place that will automatically intercept that call chain. Yeah.
JOSH: Okay, that’s cool.
CHUCK: And the nice thing that I see about it is that you don’t then have to understand the full chain all the way up. You just have to know which one you want to put it in front of instead of trying to figure out what's in front of it and then put it in after that.
JOSH: So, the thing that I would call out as a potential red flag with prepend is I would worry about people sort of going whole hog or going hog wild on this where -- with Rack. I'm going to use an analogy here with Rack where one of the problems people run into with Rack is that every time you're inserting a new Rack middleware in your web application, you're inserting -- because of the way Rack works, each piece of middleware calls the call method -- sends the call message to the next piece of middleware. And the whole execution state, the whole stack frame of the previous piece of middleware is around while you're calling the next piece of middleware. And if you have enough pieces of middleware, you can have a really deep call stack which is not really good for all sorts of reasons. And with the Module#prepend, if you're always doing this and then calling super, that’s the equivalent thing where you keep stacking on methods and getting your call stack deeper and deeper. In general, that’s not a big problem. But some of the issues that people have working with stuff, like Rails, we have an incredibly deep call stack, is it becomes hard to understand what's going on your code. It’s slow, it uses a lot of memory, uses a lot of stack space. And if people just use a really generic mechanism like prepend to compose behavior this way, that can lead you down the path that can get you into [inaudible] of this incredibly deep call stack and I'm exhausting system resources in a particular way. And that oftentimes, when you're doing stuff like that, it’s better to shift around your -- basically, the architecture of how you're composing that stuff so that you're doing it in a way that’s a little more friendly to how the language works. And maybe a little more object oriented. So, you surface the composition attributes of your code into a place where you can work on and reason on and in the language. So, people are talking about changing Rack so that it’s not this really deep call stack to a more iterative model where you're, “Okay, we use data structures within the language. We have objects and messages that work around.” So, each piece of middleware has some state in an instance, you call the next one and you get stuff back and you have your state and your instance that’s not stuck on the stack.
CHUCK: When you got started Josh, I was thinking that you're going to say that prepend is the new stuff and that include is for champs. But yeah, you make a good point. I like where you went with that. And the Rack example really illustrates well, I think, where you would go with that.
JOSH: Yeah. I don’t think there's any problem with using prepend. It sounds like a cool feature. It’s just when people get into, “I'm just going to use all these new hotness for everything.” You better be careful where you wind up there.
AVDI: Speaking of exploding stack sizes, one other little thing that I like is that we can tweak both the VM stack size and particularly fiber stack sizes now.
AVDI: It’s something that hopefully you won't need. But it’s something that without it, I don’t really feel like it’s an industrial strength language.
DAVID: So Ruby can finally have a non-hacky work around solution to the Ackermann function in the language shootout.
AVDI: I don’t know that one.
DAVID: It’s a language shootout. And one of the black eyes for Ruby is computing the Ackermann function which is a non-trivially, non-optimizable recourse or function. The stack size is like exponential. And Ruby blows up somewhere around 30,000. And you need, in order to compute it, you need a stack size for the shootout, you need a stack size of like half a million. And there's just nothing you could do. Somebody rewrote it in Ruby to be stack-less. That was like they were cheating. They completely reworked around the problem. So, that’s awesome.
AVDI: Now, you can adjust stuff like that in REE, Ruby Enterprise Edition for Rails. But even there, I don’t think that you could adjust fibers. As a matter of fact, I don’t know if REE was up to the level that had fibers. And fibers have really small stack sizes by default. So in some cases, it actually makes sense to be able to adjust your fiber stack size in order to make them useful.
CHUCK: I do want to ask, wasn’t this one of the features that some of the alternate VM implementers were worried about, the prepend? Or was that a different feature with like refinements or something?
KATRINA: I think that was refinements.
JAMES: That was refinements.
JOSH: Refinements was definitely the feature that I saw most analyzed in terms of impact. So, let’s talk about refinements.
JAMES: I think we should brush over them because they're not very exciting. But the short, short version is they were extremely watered down to the point where I even doubt their usefulness. Can we say that?
CHUCK: Well, unwatered down, were they useful?
JAMES: You know, they solved the problem I didn’t have, really. I think it’s the end story.
JAMES: For me.
JOSH: Yeah. The thing about refinements is I think they do solve a particular class of problems. And the intention with refinements was to create a safe way to monkey patch objects. And the goal was, I have some code here and I'm using some code over there. And I want it to be different. I want to monkey patch it but I don’t want my monkey patch of that code to interfere with other code that’s using that in a different way. And a great example of that is if you're writing some RSpec tests or specs, however you want to call it. And you want to like patch in the behavior for like your spec DSL somewhere. You can patch that in and that will only be visible within the spec runner. And it won't interfere with the basic operation of the code elsewhere. I think that’s a cool feature to think about having but the cost of it just seemed way, way, way high. And it had a big effect on performance. But I think more importantly, it has an effect on how you think of code in that there's no difference between your view of how an object behaves and someone else’s view of how an object behaves. And personally, I think that breaks the model for thinking about objects. You and I did a talk about that. If I have an object and I send a message to it, it should behave the same way as anybody else having an object and sending a message to it. So, I think that’s a philosophical difference about whether you should be doing this kind of things to classes in this very restricted way. But that aside, I think James is right. It’s been so limited in how it operates into actual release of Ruby 2 that I don’t think it’s sort of a fair test of refinements anyway. It sounds like they're never going away. I know it’s a “experimental feature”. But from listening to Matz talk about it, I think they're going to be sticking around in one way or the other.
DAVID: I, for one, hope the [crosstalk].
JAMES: I guess they’d keep hoping they’ll find the right implementation. Honestly, I think there's so much cooler things in Ruby and that we can do and stuff. I'm for dropping them on the floor and cutting all the losses. But I don’t think…
KATRINA: I don’t have to understand them.
JAMES: I know, right?
DAVID: I think that’s what needs to happen, right? The first shoe has been dropped which is, “Here they are and they're going to be a headache.” The other shoe that we’re waiting for is, “Oh my gosh, you guys. Here is the killer implementation for it.” And also, everyone’s going to be on board with them.
JAMES: See, I think Josh has about the best case scenario which is the RSpec DSL. Something like refinements doesn’t even make sense in Rails, like there’s no reason for Rails not just to modify the entire world and stuff like that. And if it used refinements, it would basically want to apply them everywhere so there’s really no point.
JAMES: So, I think Josh has the best case but even RSpec is moving away from that, right? Now with expect, you call expect, pass the object in and then the DSL springs off from that. So, even RSpec’s going away from that. I really think it’s -- to me, it’s a solution in search of a problem, I guess.
CHUCK: Yeah. If it does turn out to actually make our lives easier in one way or another, I’m looking forward to learning what that is but I agree with you guys at this point.
JOSH: Okay. So, I think we’ve touched on refinements enough.
DAVID: Let’s move on.
CHUCK: So now, I’m kind of curious because we were talking about features that we were excited about and then we talked about a feature we weren’t. Are there any other things in Ruby 2 that you guys are just kind of going, “Why do we have that in there?”
JOSH: Okay. I have one and that’s lazy enumerables.
JAMES: No! Not lazy enumerables.
JOSH: Okay. So, there’s two things about lazy enumerables. First, I’ll say what they are and then we can harsh on them. Actually, James, you say… [Crosstalk]
JAMES: You say what they are and then I’ll tell you why you’re wrong.
DAVID: James, you now get to feel how I feel when he was trashing my precious refinements.
JOSH: Okay. So, lazy enumerables are basically, you can get an enumerator for an array or an enumerable class, you can get an enumerator. And you can pass that thing around and then people can chain other enumerators onto that. And lazy basically turns that from an iteration API into a streaming API. So, if you have an array of ten things and you have a bunch of these blocks that you’ve put together as enumerators, instead of having to run through all ten things in the array with the first block and then taking that collection that you’ve created and then run it through the next block the same way creating another array of ten things et cetera, you can take that first value, run it through the first block, the second block, the third block, all these enumeration blocks. And you can do that with each of the values in the array. And then, collect all those values into a single array at the end. So, you’ve avoided allocating all of this intermediate state that you don’t really need if you sort of unroll the loops and do them the other way.
AVDI: I think it’s a fair description. I just want to say that enumerators were already lazy.
JAMES: Yes, that’s true.
AVDI: You could easily construct an infinite, some method that would just keep yielding new values. And then you could say, construct an enumerator for it and then say .take3 and it would give you three values without actually trying to iterate to the end. All this does is makes chaining more workable.
JOSH: Okay. So, the one red flag I have about this -- okay. Well, there’s two things. One is practical and that’s that now that they have an implementation of this lazy enumerables, they found that the performance win for it is actually negligible or negative. So, it’s not actually…
JAMES: Okay. That’s not totally accurate, though. You’re right that if you take some existing code and you drop .lazy on it, you’re probably going to take a speed hit because it adds, obviously, it adds some overhead in order to turn that into lazy. But there are definitely scenarios where you can see speed-ups if you have the advantage, like the one you gave earlier. If you have to build three intermediate arrays of 10,000 items each or you just stream them through one pipeline, which one’s going to be faster?
JOSH: Absolutely. I can see that there’s situations where you’ll get significant performance benefits there. The downside of it is that, we’re working in Ruby which is an object-oriented language. It has side effects, sort of, by definition. It’s not a functional language that’s stateless, that has no side effects. The trick with lazy infinite lists that you see in functional languages, I think, is really great because of the alternate way to do something like iteration. So, I love lazy enumeration that way. In Ruby, because we have side effects, I don’t know how likely it is. But I know that it is possible that you could get yourself in some serious trouble where because you’re taking some objects and running them through the chain of the enumeration blocks before -- and some of those things have gotten to the very end of the chain before other things in that collection made it through the first one. You’ve now reordered your operations and in a theoretical perspective, reordering operations in a language of side effects can get you in serious trouble because you can have things happening out of order and you can introduce some pretty pernicious bugs that way. In practice, that may not be an issue at all. So, it’s a definite concern for me but it may not be a practical concern in anyone’s code.
AVDI: It’s definitely a reason to always try to do functional style or do imperative style, don’t mix them up so much.
JAMES: Yeah. I think it’s an excellent argument for that. My only thought is that the way we typically use iterators, especially something like map where it’s going to pass the value in. And all you have to do is provide the part that completes the difference and it’s going to gather that into an array and stuff. I believe we tend to use that functionally anyway, most of the time. But I can see Josh’s concern.
JOSH: Yeah. I’ve been trying to construct likely scenarios for people building enumeration blocks that would have this issue and there aren’t many. So, I think practically, it may not be a big problem.
CHUCK: What I want to ask is, on the performance thing again, it seemed like you guys have a pretty good idea of -- in these instances, there’s definitely a performance win and in these instances, there may not be. Do you kind of have a rule of thumb for that as far as like the size of the array or enumerable that you’re iterating over? Or the types of operations that you’re doing that will definitely give you the performance boost?
AVDI: I think the wonderful thing is what this does let you do, is it lets you pretty easily swap in pipelining behavior where there was previously process the whole collection, then pass it to the next method, process the whole collection, whatever the name for that is. If you start the chain out, if you just chain the start of the chain to be lazy, my understanding is then everything following that is going to be lazy, is going to be a pipeline. The great thing is you can profile it. You can profile it as it is and you can change the head of the chain to be lazy and then profile that.
JAMES: And I think Avdi just gave you your test case right there. If it’s one of those things where you would find yourself saying, “Ah, I should unroll this loop and I can speed it up.” Bam! .lazy.
AVDI: And that’s the fundamental change here is that you don’t have to rewrite to try that out. You don’t have to rewrite all your code to find out if…
CHUCK: Yeah. Just mark whatever…Go.
JOSH: So I had a chat with Charlie Nutter about lazy enumeration in Ruby 2. And we had a nice little chat about how it works and performance and all that. I don’t want to put words in his mouth but my take away was that the number of scenarios where you will find an actual performance advantage are vanishingly small. It’s going to be very hard to find a situation where you will actually get a win from lazy enumeration.
AVDI: I suspect that may also depend on domain. I mean, that might be very true for a lot of web applications, it might not be true for some scientific calculations or something like that.
CHUCK: Yeah. But as you said, it’s pretty simple to just wrap a profiler around it, put lazy on it, take it off and just see how they compare.
AVDI: I have something that I think is missing from Ruby 2.0.
JAMES: What’s that?
AVDI: Any significant updating or rewriting or just refurbishment of the libraries. Like, one of the items that’s…
JAMES: Are you talking about the standard libraries?
AVDI: The standard libraries. Like one of the items that is in one of these lists of new features I’m looking at, is that the CGI standard library now has a profile for HTML 5 which, okay, but why is the CGI standard library still a thing?
AVDI: Because the Internet…
DAVID: Is that thing still around?
AVDI: Mind you, the CGI library isn’t even really what it sounds like because it’s mainly used for building.
AVDI: It’s mainly used as an HTML tag builder. It’s not so much as a way to access like the standard CGI variables.
JAMES: No. Avdi, everybody does require CGI, CGI::escapehtml.
JAMES: That’s what it gets used for.
AVDI: Which totally makes sense. It’s very easy to explain that to newbies, that you require the CGI module to escape HTML. That’s, if I could select one focus for the next version of Ruby, it would be, okay, let’s stabilize the language feature set for a while and just go through it and update and call the standard library and just make it more consistent.
CHUCK: So, you want them to do garbage collection on the standard libraries?
JOSH: Yeah. One of the things that had been discussed in a lot of depth for Ruby 2 was trying to gemify a lot of standard lib.
JAMES: So, there is progress there. Can I explain it?
JOSH: Yeah, please do.
JAMES: Ruby 2 includes a new version of Ruby gems that does lay the groundwork for moving the standard library to gems. So, even though it hasn’t been done yet, some infrastructure is moving that way. We’re on that path, basically.
AVDI: That’s right.
JOSH: I did notice another change to Ruby gems which is that it can interoperate with Bundler.
JAMES: Yeah. I heard something about that but I don’t know the details.
JOSH: I don’t know a lot of the details either. This Ruby 2.0.0 in detail page that you linked us to has a little discussion of it. Basically, you can do like gem install but you can pass it a pointer to your gem file. And then, it will use the information in the gem file about versions to load a version of the gem that’s compatible with your gem file definition.
JAMES: That’s cool. So, we’re not done with cool new features. Can we hit just a couple more before we call it a day?
JAMES: Katrina actually…
AVDI: And then, I have one philosophical question I want to ask after that.
JAMES: Okay. Katrina actually hit my favorite feature early on in the show but we rode right over it. Katrina, do you want to tell us about the new garbage collector?
KATRINA: Yes, I do. You’re going to have to correct me if I get the details wrong because I’m not very strong on Linux fundamentals. But in Unix like operating systems, there’s something called copy-on-write which means that when you fork a process, if both of the processes are just reading data, shared data, then they can keep that data as shared. They don’t have to make their own copy. And they only make their own copy of the data when they mutate this. This is really important in the old garbage collection which is the mark and sweep style. So, every object, every Ruby value which can be anything from strings and arrays to just nodes in the syntax tree of your program are these C objects which have both the value and some metadata. And whether or not something was flagged to not be garbage collected was in the metadata of this object. And this means that the object itself was changed. This means like when you’re going through to decide if it’s going to be garbage collected or not, every single object that is still living in your program, the metadata gets marked to say that it’s still alive which means that every single process has to copy it, has to have a copy of this. And in the new garbage collection, there is sort of a mirroring structure that mirrors the heap with all of the objects in it that just has a bitmap of zeros and ones to decide whether or not that thing is going to be garbage collected which means that you can now share objects like all of your whole program structure, and any variables, or any constants, things that don’t change can be shared across processes which means that you use a lot less memory as you’re running. Did I get that right, James?
JAMES: You nailed it. Yeah, that’s exactly right. So in Unix, whenever you would fork a process and everybody is thinking, “Oh, it’s forked. I can stop listening.” But actually, it affects everybody because you use a web server and your web server probably forks. So, whenever you fork a process, you’ve got this great benefit of copy-on-write of Unix just made a new entry in the process table and you were done almost instantly. And then second the Ruby garbage collector ran, you lost that entire benefit because it walked through and touched every single object in the system. So, that whole benefit was gone. Now, with the bitmap garbage collector, the notes are kept in a separate place away from the object. So now you fork, you get copy-on-write and the data isn’t copied, and when the garbage collector runs, only that map changes, so only it needs to be updated and all those objects are never copied over until you write them.
KATRINA: And those maps are really tiny.
JAMES: They’re just bits, right?
CHUCK: If you want to get a little bit more into processes, forking, copy-on-write, and stuff like that, we did an episode about it when we did our Book Club on working with Unix processes with Jessie Storimer. And we’ll put a link to that in the show notes too.
JAMES: There’s also an excellent blog article from Pat Shaughnessy where he digs in and says why the garbage collector in 2.0 is so exciting. And it really is my favorite feature in 2.0, the garbage collector.
CHUCK: So, it gives us copy-on-write and stuff but there’s always been this kind of performance thing with garbage collection and how the memory grows as you let a Ruby process run long. Are any of those issues solved?
JAMES: Yeah. This actually leads to another thing I think is absolutely awesome trend in Ruby 2.0 that I just hope catches on like wildfire and keeps going. They’ve really done a lot lately about improving your window into the inner workings of Ruby. So like, to give some examples of that, in Ruby 2.0, we have this trace point which is like set_trace_func if you know that one, on steroids and object-oriented which is really cool. You can turn it on and off in places, you can have multiple traces going, getting different data, really neat stuff. And then, object space has been enhanced to give you things like reachable objects so that you can determine, given this object, what objects can be reached from there which is very helpful in finding memory leaks. There’s a blog post I’ll throw in the show notes and it’s only in Japanese. But you can read the Ruby, and the code is for basically finding memory leaks in Ruby just using this method. And if you combine that with things that were brought in with Ruby 1.9 like the garbage collector profiler and objects base has a mem_size of in Ruby 1.9, you can start to build really detailed images of what’s going on inside Ruby to help you track down these problems. DTrace support’s been expanded. So yeah, I really feel like they’re trying to give you a window into that world.
DAVID: I’m really excited by the Ruby VM instruction sequence module which gives you the compiler- decompiler for everything.
CHUCK: Yeah. We’re running out of time guys, are there any…
DAVID: Okay. I guess, I’m the only one excited about that.
JOSH: Does anyone want to mention to_h?
JAMES: Yeah, that’s another great feature.
CHUCK: I missed that one.
JAMES: Do it, Josh.
JOSH: Okay. So, to_h is kind of like to_s. It’s a standard conversion method. And what it does is it converts the object in question into a hash and this is now part of OpenStruct so you can pass a hash…
DAVID: It’s also a nil class, the N for object, yeah.
JOSH: Yeah. It’s in a lot of places but there’s now like this standard way of converting an object into a hash representation of it.
DAVID: I want to give just a fair shot of it as well. Andre Bernards, on the Parley mailing list mentioned this one. I asked for some Ruby 2.0 tips and tricks a couple days ago. And he was the only one that replied with a Ruby 2.0 specific one. Another Parleyer whose name I cannot pronounce, Faisol Injorat wrote back with a gem clean up but that was another feature as well. Definitely shout outs to the Parleyers for coming in with some really good tips. The to_h was in there which was very cool.
JOSH: Sounds like, have we hit it all?
JAMES: We’ve definitely hit the highlights.
DAVID: If we can cover it all in an hour, there needs to be more.
AVDI: Do we have time?
JOSH: So, before Avdi gets to his philosophy, how should people install Ruby 2? Is there a good blog post about how to get it set up, is it just RVM?
CHUCK: I’m pretty sure RVM and rbenv will allow you to install them. As with anything else, I mean, you can always just go and download the source, and run ./configure with whatever options are important to you and then make and make install. That will put it together.
AVDI: At least with RVM, it was stupidly easy.
KATRINA: With Ruby build, it was really straightforward as well.
CHUCK: I don’t know about Windows, is the only one I’m not sure on. If anyone has information about that, I would really appreciate that. Just put a comment in the show notes and you can do that by going to RubyRogues.com. Alright, so philosophy.
AVDI: Alright. So, here’s a philosophical question to maybe end on. Every language as it grows and matures, especially every time a language has a major revision, there’s always going to be a set of people that say, “We’d finally jumped the shark this time.” And I guess the question is, can a language just keep evolving and keep growing or does it eventually get too big? Does it just have too much stuff? Is there a point, do you think Ruby will be done, as far as you’re concerned, do you think Ruby will be done at some point soon? And any further language experimentation ought to be in a new language, or do you think it can successfully evolve indefinitely? I’m thinking particularly of a lot of people have said that Java is now just too big a language with all the generics and other things that have been added over the years. Of course, people have been saying that about C++ pretty much since C++ first started existing. So, what do you think?
DAVID: I think Ruby’s going to continue to grow. I think we’re already seeing people who want the ecosystem. Ruby obviously has, maybe not obviously. I assert that Ruby has the fastest growing, fastest moving ecosystem of any language ever in any community. And the people who are pushing fast evolve/change/grow, they’re not willing to sit around and wait for Ruby. They’re the ones jumping off and going, “I’m going to go do Closure. I’m going to go do Erlang. I’m going to go do this other thing.” And then we turn around a year later and Ruby 2.0 is starting because these people come back to Ruby because they love it. And they bring these ideas back from these other crazy languages. Things like refinements and things like ennumerable lazy, pretty clearly have -- like enumerable lazy pretty clearly is coming. That’s insanity being back contaminated from these people that have jumped off into Haskell and Lisp and those languages. And in 2009, I think it was, Guido froze Python for two years to let the reference implementations catch up. And I remember just being shocked and horrified by this. But it really touches back on the philosophies of the two different communities. Python’s just one right way to do it and I think Python is a very mature language that most problems that it’s going to face in the next five to ten years, they’ve kind of figured out one good way to solve that. And with Ruby, Ruby’s constantly questioning itself and saying, “Well, is there a complete reinvention of what we could do?” I’m a little excited about it. I’m a lot excited about it. I’m a little trepidatious of it because like Josh pointed out, we’re dragging in some very non-OO things into what used to be a language that touted itself as more OO than Python. And I think Ruby can still make that claim but there’s certainly a lot of dead birds on the doormat. There’s certainly a lot of contamination, a lot of stuff that’s been dragged in from FP and from concurrent programming and that sort of thing that are being brought back in Ruby. I genuinely think Ruby 3 is going to be a completely different beast. But I also think it will still have a GIL. So, this is my thought.
CHUCK: The thing that I see with a lot of this is that most of the changes that we talked about, they don’t deeply change the way that I’m going to write Ruby. And so, like 2.0.0, did it jump the shark? Well no, because it doesn’t make a huge difference for 99% of what I’m doing. Eventually, will it change to the point where we don’t, where it doesn’t have what I need? Or changes the way that I do things in a way that I don’t prefer? Well, possibly. But for right now, I don’t think Ruby 2.0.0 is it. I think some of the other things that we’ve talked about with like the size of the standard library and some of these things that may become more standard like the keyword arguments that some people will like and some people will not. And these other ideas that we’re bringing into the language may eventually change the way that people use it for good or for ill. But for right now, I really don’t see that this is going to hurt the Ruby community in any meaningful way at all.
JOSH: I think there is a potential there. I think that as David was saying, the more functional features that we get in a language, the more opportunity there is for people to create what you call a multi-paradigm code.
JOSH: And that’s when things get confusing. I think that a language that has multiple design centers has no design center. It gets very confusing how to structure things.
DAVID: It will be very interesting to see what the community does in response because like send can access any method public or private. And monkey patching can modify anything at anytime. And we, as a community, we developed a torch and pitchfork brigade that basically we said, “If you’re a library, don’t you dare monkey patch something that’s going to come out of that library into everybody else unless you were specifically advertising that that’s what you provide as a service.” But if you’re just doing your own manipulations, don’t monkey patch globally. And like when I talked to Python people, they’re still terrified of monkey patching because, “Oh, you can change anything at anytime.” No, no, no. It doesn’t happen. It’s like a Wiki.” Yes, you can delete all of Wikipedia. But it doesn’t happen because the community will respond. And I do think we are going to see some multi-language program or multi-centric programs come out. And I think they’re going to have some unique challenges. And eventually, some people are going to step up and say, “Just stop doing that.” Either write FP Ruby or write OO Ruby, but don’t try to do them both. And yeah, who knows? The FP Ruby stuff might die out and it might be, you know what? Talk to a remote service written in Closure or something. I don’t know. I guess what I’m saying is that I think the community will respond with, “Don’t do that,” when we discover some problems. But I think there might be some cool things that we find along the way.
CHUCK: Yeah. And there are definitely some things like blocks and procs and some of these other things that, to my thinking anyway, are more FP than OO that are powerful things when we couple them with the OO. So, it’s really interesting some of these things that are being brought in and just where they could be taken. So, it could wind up being a major win or it could be like Dave said, “Don’t do that, do it this way.”
JAMES: I’m not sure about that one. I think Ruby’s always been a very multi-paradigm language with the scripting and all the crazy tricks it grabs from Perl, like Flip-Flop operators and stuff like that, up to really solid OO. But the iterators really did come out of the functional community. I feel like it’s always been kind of multi-paradigm and we’re seeing it import new things from different places and stuff. But I’m sure there is a breaking point to that but I don’t feel like we’re there. That said, I wouldn’t lose any sleep if refinements are removed in a later version.
CHUCK: [Chuckles] Alright. Well, let’s go ahead and get into the picks unless Katrina, or did Avdi say something about this? I don’t remember.
AVDI: I just wanted to hear from you, folks.
CHUCK: Alright. Well, you’ve heard from us folks. Katrina, did you have anything to add before we get to picks?
KATRINA: I guess, kind of. I really liked Gary Bernhardt’s talk on Boundaries where he talked about his FauxO model where he kind of combines, I guess, it’s the imperative shell functional core that he’s been talking about where he’s able to combine two different approaches but with a very clean sort of separation. I really like that.
JAMES: Yeah, that’s a good point. I mean, lots of people are really understanding the valuable as like immutable objects. And I think that’s happening because of the big interest in up and coming functional languages.
CHUCK: Yeah. It will be really interesting to see what happens. Alright, let’s do the picks. James, what are your picks?
JAMES: Alright, I’ve got a few but I’ll run through them pretty quick here. First is a great blog post from Mislav. And he did it out of something, a discussion on Parley. But it’s called Git merge vs. rebase. So, if you’re one of those people who doesn’t know when should I merge, when should I rebase? Or you’ve read all the arguments out there and every time you read one, you think, “Okay, but that’s still kind of weird.” This is the most practical and the best description I’ve ever seen of what merge is, what it’s good for, when you want to do it. What rebase is, what it’s good for, and when you want to do it? So, a really good reading there. And then, a buddy of mine Paul Huckle got me hooked on this YouTube channel, ‘Smarter Every Day’ I think it’s called. Yeah, ‘Smarter Every Day’. And it’s these awesome science videos that just have all kinds of great stuff in them. You just have to go check it out. But to give two examples of ones that are amazing. There’s like the honey rope coil effect, which is how when you drip out honey, it will coil around itself. And they explain all the physics in that and it’s totally awesome. Another one that’s great is the Prince Rupert drop which is like this piece of glass that’s so hard at the tip, you can’t break it. But you can just barely tap the tip and the entire thing will shatter. And they explain to you how that happens and why, all the way down to what happens when a baby takes its first breath and literally biological changes in the heart at that point. Super cool YouTube channel for science geeks. Those are my picks.
CHUCK: Awesome. Katrina, what are your picks?
KATRINA: I have three today and none of them are programming-related, I’m afraid. I’ve been thinking a lot about thinking lately and how I really like to become a better thinker. And I came across a book called ‘The 5 Elements of Effective Thinking’ by two Mathematics professors. And it’s a small book, and I read through it. And then, immediately turned back to the first page and started reading it again. So, it gives you some very practical strategies that you can use to improve your thinking. Another thing is there’s a blogger that I’ve been reading for a few years. His name is Venkatesh Rao and I’m probably mispronouncing that. He writes a blog at RibbonFarm.com. He’s an Aerospace Engineer, I believe. But he is this deep thinker about everything, like he thinks about so many interesting topics and then thinks about them deeply and synthesizes these amazing blog posts where he sort of shares his journey. And it’s always varied, it’s deep, it reaches across. He’s able to really go into the nuances and the depths of things and I just really appreciate that. So, that’s the second one, RibbonFarm.com. And the third thing has nothing to do with thinking, UTILIKILTS.com. I wish I were a guy so that I could wear utilikilts without it just being a skirt because they’re awesome. So anyway, those are my picks.
JOSH: Yeah. I think that UTILIKILTS is based in Portland. So, anybody who goes to Rails Conf this year can go check it out and pick up a kilt.
CHUCK: Alright. Josh, what are your picks?
JOSH: My first pick is something that I’ve been using for a while and it’s so awesome that I just don’t even think about it, until I had to update it recently. And I realized I hadn’t updated it in a few years. This is, people use Adblockers to control nasty content in their browser. And I was having a phishing site show up on a site that I use and it has ads or something which is causing me grief. So, I got rid of it really easily. There’s this ‘Poor Man’s Adblocker’ that’s basically an /etc/hosts file replacement. You basically dump in thousands of host names into your /etc/hosts file that map all of those hosts to the IP address as 0.0.0.0. And so, you just never get a route to any of these places. You’re completely protected from any requests to those hosts and it works great. You end up seeing a lot of either those little broken image icons in your browser. But I can deal with that. So, that’s at SomeoneWhoCares.org/hosts/zero and it’s a really nice project. I’ve been using it for years and it works great. It’s pretty awesome. Although a little warning if you’re using Hulu. Hulu gets really upset when it can’t connect to the various ad servers. So, there’s some situations where you have to disable this to be able to use things. But in general, it’s just awesome and works well. So, that’s one thing. And then, everybody knows that I’m a huge fan of ‘Avatar, the Last Airbender’. And I’ve made other picks related to that. So, I now have a pick about the next comic book in the series of Avatar stories, that’s called ‘The Search’. And it’s about Zuko’s mom and what happened to her. The first issue of that is out now. So, people should read that. It’s awesome. Then my last pick is, speaking of being known well for my picks, I’ve picked a couple of these cool Twitter accounts that are just fun things to follow on Twitter. This is one that Avdi even picked for me the day after I discovered it. This is @PicardTips. It’s basically Captain Picard of the Enterprise D, Star Trek Next Generation, taking lessons from the shows and recasting them as tips, like pro-tips for either Managers or whatever else you’re doing. And I find them just terribly amusing and also, often really insightful. Things like ‘Picard Management Tip: Tolerate Failure, Not Incompetence, Learn the Difference’.
JOSH: Or things like ‘Hire Aliens, It’s No Big Deal’.
JOSH: Anyway, I’m enjoying that a lot. So, I recommend following that one. And that’s my picks.
CHUCK: Those are your Picard tips this week. Alright. Avdi, what are your picks?
AVDI: I’ve been kind of out of the tech orbit this past week. My wife and teenage daughter attended The Art of the Belly Dance Conference in Ocean City, Maryland. And my wife brought the children along because she didn’t want the baby to wean in her absence. And she brought me along to watch the children while she was attending the conference. So, I found myself with three children, including a babe in arms, young children at Ocean City, Maryland in sub-freezing weather for three days. And that was an interesting challenge. But I discovered the Old Pro chain of mini golf places in Ocean City. And they actually have these giant elaborate indoor mini golf setups. And so, I introduced the little ones to mini golf which they were highly entertained by. The four year old actually got into the game aspect of it and getting the ball into the hole, although he used some fairly unorthodox methods of doing so. The two year old mostly just liked clambering over the scenery. But yeah, if you’re ever stuck in Ocean City or some place like that in freezing weather and nothing to do with children to entertain, I highly recommend checking out the indoor mini golf places if it has any. So, I guess that’s kind of a pick.
AVDI: Anyway, when I got back, something I had ordered arrived and this is somewhat technical. I am anticipating another trip this coming week and I wanted to be able to do some Ruby Tapas recordings while I was away. And I didn’t want to use the built-in mic on my laptop for that because that would sound horrible. So, I ordered a bunch of travel recording gear. And particularly, I ordered a new microphone which is the Samson Go Mic. And I’m already really impressed with it. First of all, it’s adorable. It’s this tiny little folding thing. I showed it to teenage daughter and she basically said, “Aaaaa.”
AVDI: And it sounds really good. And it actually has a leg up on my current Blue Snowball and that it has a built-in monitor port. You can plug a pair of headphones into its monitor port. And as I discovered, not only is it just a direct monitor of the analog monitor of the input, it also functions as a sound card, a sound output when you plug it into the USB on the computer. So, it can actually take the software output, like say, somebody on Skype or something, combine it with the direct monitor of your voice and you can hear both together. So, really nice little microphone that packs up tiny. And can be gotten on Amazon for like $40.
AVDI: Yeah, it’s USB if I didn’t make that clear.
CHUCK: Alright. David, what are your picks?
DAVID: Oh my, gosh! It’s been a couple of weeks. So, I’m going to try and go through these really, really quickly. And it did not help that James and Katrina both triggered other picks for me. The first one is ‘Towns’, the game. If you like Minecraft and you like SimCity, there’s a good chance that you would like this hybrid of the two. It’s basically Mines of Moria, or Rogue, or Diablo. Only you manage the town above the Hellmouth and you open up a mine and that exposes the town to monsters. And if you’ve built a tavern, heroes will show up and they will then go down into the dungeon and clear it out for you. One thing I will tell you about ‘Towns’ is, do not attempt to even open the tutorials that come with the game. They absolutely stink. So, the companion pick to this is, go to YouTube and look for SplatterCat Gaming or just go to YouTube and look for Towns’ Tutorial or Towns Game. Don’t look for Towns Let’s Play. A lot of people are doing those. But if you look for Towns Tutorial, you’ll find a guy named SplatterCat Gaming who will get you up and running in your first month as a Town quite well. And you’ll be ready to handle the monsters that the heroes come dragging up to the surface on accident, all the time, basically. My second pick is James, you mentioned the ‘Get Smarter Every Day’. I have a Twitter account for people to follow. It’s called @SciencePorn. And it’s totally safe for work. But what it is, it’s a Twitter account that just posts just bizarre and amazing science facts, absolutely gorgeous Earth/Science pictures like volcanoes, Northern Lights. Their most recent picture is a picture of sunrise right after a new moon or right before a new moon at the North Pole. And the moon is like a thousand times bigger than the sun because of the forced perspective. It’s just amazing. So, follow @SciencePorn on Twitter. They’re absolutely amazing. And then the last one is, Katrina picked Venkatesh Rao. And Venkat is just amazing. He runs a newsletter called ‘Be Slightly Evil’. And I just can’t recommend it highly enough. It all started with, I think he’s turned it into a book. I think Katrina has linked it in the show notes, ‘The Gervais Principle’ which is based on interoffice socio-dynamics, based on the TV show, ‘The Office’.
CHUCK: [Laughs] No!
DAVID: It’s a very serious article and it will blow your mind. If you do nothing else, just read the second installation which is Power Talk, Baby Talk, Gamer Talk, and Loser Talk or Posture Talk which is how the three types of people in an organization which are socio paths, clueless people, and losers interact with each other. And it will be very -- it’s funny and then it’s really uncomfortable when he starts describing the way people talk to you or the way you talk to other people when suddenly you realize, “Holy crap! I’m clueless.” Or, “Holy crap! I’m a loser.” Or, “Cool! I’m a sociopath.” That didn’t happen to me but I strive. ‘Be Slightly Evil’ is a very pragmatic newsletter that helps you strive to become a sociopath for the greater good. His point is that to be maximally effective, you can’t just go around mincing and prancing and lying to people. Sometimes, you have to say what you mean and take what you want. And sometimes, that’s a little bit sociopathic. So, it’s a fantastic newsletter.
JOSH: This sounds like a modern version of Machiavelli’s ‘The Prince’.
DAVID: He mentions multiple times that he idolizes Machiavelli. And he has refrained from writing a review or his own take on Machiavelli because he says, “I’m different enough from Machiavelli and I also respect him enough that I don’t dare touch that classic.” But yes, he certainly has given Machiavelli a nod.
JOSH: By the way, just as a tangential pick here. ‘The Prince’ is an amazing read. It’s very short. And it’s actually a book on how to provide good governance.
CHUCK: Alright. I’ll go ahead and do my picks. I don’t really have anything that I’ve run across this week that I really want to talk about. So, I’m just going to talk about some of the stuff that I have going on that I want to share. The first one is that I’ve had a ton of people asking me when an IOS podcast is coming. And I have an answer for you, next week. We’re going to record the first episode, a week from yesterday, which means that it will probably come out a week from yesterday when this one comes out. So, we’re going to be putting that one up. And I have to give credit to Josh for the name of the show. It’s going to be the iPhreaks Show. And you can get it at iPhreaksShow.com.
JAMES: That’s awesome.
CHUCK: The other one that I wanted to bring up and I don’t have the landing page up for it yet but it should be by the time this episode goes up. I’m doing a Rails Power Up. I’m doing the Rails Ramp Up course right now for beginners. Rails Power Up is going to be, you can sign up for just the ones you want or you can sign up for the whole mess of webinars. But basically, it’s going to be training on specific advanced things in Rails. So, I’m looking at doing engines, Facebook apps, doing an in-depth on the asset pipeline and things like that, that I know people struggle with, even though they understand kind of the basics of the MVC and some of the other pieces of Rails. If you want to learn about what’s there and what I’m going to be talking about, then go to RailsPowerUp.com. I guess we’ll wrap up the show. It’s been nice having all of the Rogues on for an episode.
JAMES: Yeah, for the first time!
AVDI: Really cool!
CHUCK: So next week, I’m not sure what we’re talking about. I don’t think we have anyone on the schedule yet. But that will be our 100th Episode. So, stay tuned.
JAMES: 1-0-0. DAVID: Clip show! Clip show!
CHUCK: Yeah, we’ll see. Well, let’s wrap the show up. We’ll catch you all next week.
JOSH: Okay. Goodbye.