- Brian Ford (Shirai) (blog twitter github)
- James Edward Gray (blog twitter github)
- Josh Susser (twitter github blog)
- Charles Max Wood (twitter github Teach Me To Code)
- Levels or Ruby
- Assignment to something that could be a local variable or a setter method
- Having more than one way to do things
- map vs collect
- and vs &&
- alias method chain
- copy on alias
- when you alias a method, then alias its aliases for consistency
- in some cases ruby is white space sensitive
- ruby’s complex grammar
- How much documentation do we need if we can open the source of our projects?
- Generally takes an architecture change to get better.
- the Ruby Application Archive (RAA)
- standup meetings post (Josh)
- officeplayground.com (Josh)
- www.thinkgeek.com/geektoys (Josh)
- Rails 3.0 (James)
- Snow Leopard (James)
- Actors Blog Post (Brian)
- Mirrors Post (Brian)
- Netflix for iPad (Chuck)
- Skype (Chuck)
CHUCK: Hey everybody and welcome back to another Ruby Rogues podcast. This week on our panel, we have four awesome Ruby developers. First, our guest Rogue, we have Brian Ford. Brian, why don’t you go ahead and introduce yourself.
BRIAN: Hey everybody, this is Brian. Let’s see… I work on Rubinius for Engine Yard. That’s probably the best way to tell you who I am. I am working on that project almost since Evan announced it back in December 2006.
CHUCK: That’s awesome. I know a lot of people who use Rubinius. That’s terrific. We also have James Edward Gray.
JAMES: Yup. I’m back and I’m going to try editing this podcast, since that’s been the popular request. So you guys can give me a thumbs up or a thumbs down on how it goes.
CHUCK: Yeah, and if somebody wants to sponsor this podcast, then maybe we can just hire somebody to do that. But yeah, I’m lazy, so I don’t. [Chuckles] And we also have Josh Susser.
JOSH: Hey everybody. Good morning. [inaudible] recording this podcast, so I hope we are all alert and chatty. Anyway, I’m from San Francisco. And the thing that’s occupying my attention a lot these days is [inaudible] Ruby conference that is just coming up in a couple of weeks now, so it’s driving me crazy – but in a good way.
CHUCK: That’s exciting stuff. And I’m Charles Max Wood. I’m the host of the Teach Me To Code, and The Rails Coach Podcast and I’m doing a bunch of other stuff. You can find my stuff at teachmetocode.com. And right now, I’m in Boulder, so I might sound a little bit different, but that because I’m sitting in a hotel room talking on my laptop. Anyway, let’s get started. Josh, you picked the topic this week, so why don’t you go ahead and introduce it?
JOSH: Okay, so the topic this week is What’s Wrong with Ruby.
CHUCK: Josh, can we get a definition of Ruby?
JOSH: [Chuckles] Ruby is a silicate crystalline gem stone. [Chuckles] Okay.
CHUCK: That was about far too many syllables for my tired mind.
JAMES: I was sure he was going to make me define “wrong”.
JOSH: [Chuckles] No, I´ll do that.
CHUCK: The rest of it all depends on what your definition of the word “is” is.
JOSH: [Chuckles] Oh, you went there. You really went there. So what’s wrong with Ruby… [chuckles] now you see what starting the recording earlier in the day has done to us. [Chuckles] We don’t have any pre-show to get all these out of our system first.
Okay, so what’s wrong with Ruby. Ruby isn’t perfect . No, programming language is, but I assume from this podcast, it’s definitely our favorite language that we’re using. And there’s things wrong with it, there are things that could be better, things that drive us crazy every now and then. And I think one of the things that experienced Rubyists learn is how to deal with those things, and not let them make you crazy. So, that’s where I was coming from when I thought of the topic.
JAMES: So Brian had kind of an interesting pre-question when we asked him to join us for this episode. He started quizzing us on what exactly Ruby means. So Brian, do you wanna talk a little about that?
BRIAN: Sure. So it’s a great question, “What is wrong with Ruby?” I think that we see a lot of people write blog posts and talk about a variety of different things that I associate with Ruby. And being a little bit of a math head, I really like definitions. So of course, I was curious what exactly do we mean by Ruby. And I look at Ruby as a fairly complex thing and the very core sort of language which has syntax and the semantics; how you make a class, how you make a method, that sort of thing. But I deal with a lot of stuff around that core every day, working on Rubinius. I work on RubySpec a great deal, so that’s sort of defining how the language works. But also, I write it on the Ruby code in Rubinius, my code compilers are all on Ruby, for instance.
And I’m still working on that. I’m contrasting what I hear from people about their experiences engineering Ruby applications, and Rails applications. And then there’s many things around Ruby, like the testing either Unit Test or Rspec or Cucumber, and there’s fairly avid engineering community that looks at things like patterns. And so I’m really interesting in the question, and I actually have things that I could say or in my opinion is wrong with Ruby, if we can define wrong, at all these different levels. So it’s a fascinating topic.
JAMES: So you are thinking kind of the levels being language, implementation, sounded like maybe community or maybe just “culture” would be a better word, and then that ecosystem in general.
BRIAN: Absolutely. That’s a really good way to summarize it.
JAMES: All right, so let’s start picking on some things. Josh had a list generated. Didn’t you, Josh?
JOSH: So I actually started going through a list of… putting a list of what I thought was problems with Ruby or things that were wrong, things that I didn’t like. And I realize that a lot of them had to do with ambiguity. So, my favorite awful quirk in the Ruby language, in the syntax, or the processing of the syntax — I’m not even sure — is that the assignment of a value to something that looks like it could be a local variable, or a setter method. And that’s ambiguous to the programmer, although not to the compiler.
JAMES: So I will try to sum up how Ruby does that, and then Brian can correct me on everything I get wrong, since he knows much better than me. But I believe what Josh is talking about is like if you say var=… the way Ruby determines… or no, that wouldn’t be the case because that would always be a local variable, wouldn’t it? Yeah, var= would always be a local variable.
JOSH: No, that’s what you would think. [Chuckles]
JAMES: Is there any case where it’s not? I can’t think of one.
BRIAN: Well, if you’re within the context of a model, and you have say, “ActorAccessor” set up or ActorWriter I think it is, I don’t remember.
JAMES: But in that particular case, you would have to modify it with “self.var=” I believe the actual case is, say you have some method and then space var. So that’s an actual ambiguity, the second the var… if there’s been a local variable assigned in the current scope, then it’s the local variable. If there hasn’t, it’s the method call to the word var, I believe is the case.
BRIAN: Yeah, it’s pretty complicated, James. I think you have two cases there. There is the one case where you’re setting and identifier = something, and that’s always going to look a local variable to Ruby. So if I say, “name=Josh” and I have an adder setter on my class name, Ruby is going to interpret name= as a local variable assignment, and you have to give it an explicit receiver in order to disambiguate that for Ruby. It’s a decision that could have been made the other way; it could have always like looked up a method first and maybe if that failed, okay, I guess you wanna set a local variable. But it’s really something that trips people up.
I assisted with the beginning programming for women class where we were covering some Ruby stuff, and the first non-trivial piece of Ruby that they wrote, most of the save filter to up case the name, and everybody hit this variable problem. So that’s one of the things that I spent a whole day debugging, and I didn’t realize what was happening; I couldn’t understand what my initialize method was not setting these attributes. I have made some complex setters. It’s a very ambiguous part of Ruby. It’s a big trap.
And there’s another one that’s kind of similar to it. I think James, you were mentioning that and it’s basically the ambiguity between an actual variable reference, or a method call that in Ruby is called a vcall, I think that stands for “variable call”, because if I just say name= and instead of literal string like “Josh,” if I say name =foo and foo is an identifier, foo could be a local variable or it could be a method call with no receiver, nothing before the dot and no arguments. And that case is ambiguous. And Ruby actually goes to a little more trouble to try to figure it out. It will actually say, “Is there a local variable? If not, send the method call to try to find out [inaudible] hierarchy.”
So those two cases are a little bit different. They are both ambiguous, they easily trip people up and I would agree with Josh, one of my least favorite parts of Ruby.
JOSH: The crazy thing about what you just mentioned is that, at least the second case where you doing something=foo, that you can copy and paste out of one method and put it in another method in the same class. I think it will always consistently the same, as long as you don’t have the foo variable in one of the other methods. But the other case, where you are assigning to an identifier – and that identifier can either be a local variable or a setter method — that will behave differently on the rest of the context of the method. And the way that Ruby resolves that ambiguity of assignment is not based on whether you’ve done an assignment to a local variable in the method, but whether you’ve referred to that local variable in the method.
JAMES: That is a good point, but I think you are actually confusing it with the second case. In the first case, when you have var=, it is always an assignment to a local variable, I believe.
JOSH: No. No, no if you have referred to the method before, then it will treat it as a setter method. I think. I mean, the fact that it is so confusing to people who have been doing Ruby for many years, is why I hate this. [Chuckles]
JAMES: [Chuckles] That’s a good point. If we are working this hard to define it. So I’ve definitely been bit by this in the past, where I was assigning and then I forgot to put the “self” in there, so you end up assigning to a local variable, that just gets thrown away, and then you keep trying to figure out why you were losing data somewhere. I do wanna say in our little chat window here, Brian showing us how to get Rubinius to decompile the stuff for you to show how easy it is in [inaudible] expressions, which is one of the awesome features of Rubinius. It’s why I think Rubinius is the most transparent of all the virtual machines; you can feed it some code and pass the right command line switches, and it will just spit out basically a representation of how it sees that code. And because of that, you can see how Ruby resolves ambiguities like this. So I think it’s very helpful.
JOSH: Yeah, definitely agree with that. So okay, enough about this little word. What I would say is that, if you are doing an assignment, a setter… assignment to a setter method within your code, if there’s any question about what you are doing, you should prefix it with… you should be explicit and say self.name=
JAMES: Yeah, I think the “self.” is that rule of thumb if you are using a setter method. If you want a local variable, use “name.” If you want a setter, then put a “self.” in front of it.
BRIAN: So I was going to say that this very interesting ambiguity in Ruby grammar, this particular case with the setter is not really ambiguous to the grammar; the grammar just sees the local variable assignment. However, the ambiguity that we see as programmers in the code introduces some of the other things that I think are very interesting about Ruby, and potentially something you can say is wrong with Ruby.
I just wanna sort of tie that in, that a lot of times, how we are engineering our code — if we are making a complex setter, a setter is really something inside the class, we have access to the instance variable directly, that’s in our scope and we can change its value directly. It’s only when we start overriding the simple concept of setting an attribute inside of our class, that we get into this case we are calling a setter inside the class, and have this weird thing where we didn’t put a receiver, because no one writes “self.” — that’s implicit, right? If you don’t have a receiver for a method call, then it’s going to be sent to self.
So, I think that that sort of identifies something which is just not the language that’s the problem, but whether or not we ask ourselves, “Why did I created this complex idea of wrapping a simple idea of setting an instance variable that I can do directly in my class; and instead, I’ve added a bunch of logic around that, so now I’m required to call a setter inside my class. And then I run into the ambiguity that Ruby sends a local variable assignment and now I have to add “self.” to tell it exactly what I mean.” So I think that’s… I mean I just want to like to tie that in; that maybe it’s not Ruby’s fault; maybe we are writing that code that’s tripping us up in this situation.
JOSH: I don’t think this is a Ruby thing. I remember this was a fairly significant topic of the debate when I was working in Smalltalk, 20 years ago, that do accessing an instance variable directly or do you wrap it up in getters and setters, and talk to it that way. I think that that is a cleaner… that leaves a cleaner code working through accessor methods. Even when you are within your own class, it makes for more more malleable code, it’s easier to refactor. If you decide, “Oh, the name is no longer just an instance variable. It’s something that I am composing out of some other…” the first name and the last name string, for instance. Then, you have much more flexibility and you don’t have to run around then hit you code all over the place if you change that.
Sometimes that’s a little YAGNI, meaning “You Ain’t Going to Need It,” and you are getting ahead of yourself, and you are putting in flexibility that you are never going to take advantage of. I think a lot times, it is useful to do that. And then there are things like if you are working in Active Record, you have to talk to those attributes through accessor methods, because they are not really instance variables.
CHUCK: Right. And you wanna get all the goodness there with like the dirty variables and stuff.
JOSH: There’s just starting the instance variable though, that’s not how active record works. But the next thing is that, if you have something that’s an instance variable and you turn it into an attribute, you don’t have to run around and find all those places where you talk to the instance variable; you just change the implementation of the method by replacing it with an attribute.
JAMES: I think that’s sometimes, something we forget, like we kind of get into the habit of just doing ATTR reader, and saying or writer or whatever and we have that, but then it’s good to remember that sometimes when you need to, you can rip that out, and put in the full method and allow yourself to do something, like when you return sends, because you always wanna put sends in your database, you can switch it back to $ and sends, which humans prefer to read or something like that. So I do think it’s usually a handy level of abstraction. Although it it’s not going to be set externally or messed with externally, then I don’t see anything wrong with accessing the instance variable directly.
JOSH: I agree with that. So here’s something that I want people to respond to, and that’s that Ruby has this very, “there are many ways to do things right,” philosophy. It’s fairly Perl-ish in that respect. Python, has a “there’s one right way to do things,” approach; Ruby is very much, “all things to all people.” So you can do block says do end, or you can put curly braces around them. And there’s && versus AND. And so there’s a lot of these “pick your own way of doing it,” which is great up to a point, but sometimes, there’s differences in how these things operate. So “map” and “collect” are synonyms for the same method, but && and AND actually operate differently. Is that something that’s bad about the language, or is it something that’s great about the language?
CHUCK: It’s interesting. I have a quite a few friends who I talk to that are Python developers, and so yeah, they go way into the Zen of Python and you know, there’s only one right way to do any given thing. And so they taut that as a virtue. But at the same time, I mean, I really like the flexibility that I get out of Ruby. I mean, can you imagine writing a block on one line, writing it out “.map do |variable| ; something ; end.” I mean, the curly braces in that instance is very, very convenient.
You know, unfortunately, I think with the AND and the &&, or whatever, it a little bit different because they actually do different things, and so you kind of have to take in to a case by case basis, and make sure that what you are using is what you want. But I think in most cases, it’s a good thing because it really just provides you flexibility, because it’s just an alias to something else.
JAMES: I came from Perl, definitely so I guess I side with that community. And I learned using those constructs; so for example, everybody does seem to be bothered with the && versus AND, and I really like it because the difference basically, the primary difference is && has a lower precedence than an = or sorry… I should make that higher precedence than the =. And AND, has the lower precedence or binds more loosely. So if you have like var=whatever AND… or maybe we should use OR in this case, abort blah, blah, blah. Basically, you can say something like “assign this variable OR if we can’t let’s just abort the script right now,” which is very useful in like scripting and stuff. Whereas if you use the OR, on the equal side, it tries to do the first thing, and if it can’t you can’t it ORs the second thing, and that’s what ends up getting assigned, because it’s the difference in the equal sign.
So, I did kind of learn using those tricks, so they are very comfortable to me, but I can definitely understand where they make people uncomfortable; because if you change, you can’t just like do a search and replace through your code and replace AND with &&; you may literally change the meaning of the code – which is definitely problematic. And people argue which ones to use, and if conditionals and stuff like that should use the symbols are the words, which I tend to use the words, just because I think they look better, and I’m generally using an equal sign in a conditional, at least not a single not equal. But a lot of people disagree with me on that. I think I’m in the minority. Anyways, I don’t mind the choice, and I always prefer to have multiple ways to express myself, but I do understand why some people have that complaint.
JOSH: What about aliases for things like map versus collect?
JAMES: Well, map is just right and then collect is just wrong.
BRIAN: Yeah, I love the fact that Ruby has aliases, actually. One of my most favorite features I have never been particularly confused by code using those different methods, and I found that it gives people great bit of freedom to write code that makes a little more sense to them. I think that’s the same thing with AND and &&, the code visually looks different, and I only ever use && if I am really explicitly wanting that higher precedence for something like assignment. And the AND is more like an expression in my mind, and so I find that the code flows more readily as I’m reading through; && is more visually jarring, and so I pay more attention. And especially if I see &&= something, I have to think more deeply about that code; this can become an initialize, and if it’s not, then I wanna change that behavior and that sort of thing. So I find aliases and the the block and [inaudible], they are used in different ways to actually structure code and not just the architectural structuring, but actually lexically structuring code, where different symbols get next to each other. And I find that really, really helpful in writing more explicit code.
JOSH: I have a question about the aliasing of method names. And so we have map and collect, and so I go in and I override the implementation of collect… or I put a novel implementation of collect in my… so I have a class, I include the enumerable module, and then I override collect. So you wrote your code to call map in my object. What happens to my collect method?
BRIAN: That’s a good question.
JAMES: Yeah, in that case, I believe your new override would not be used because my understanding of Ruby’s aliasing is that it’s actually a copy basically, at the time of alias.
JOSH: Right, so you are actually putting a new entry in the method table?
BRIAN: You know, I’m actually looking at that right now. I’m always surprised by that. Yeah, let’s find out, shall we? You guys can talk about the next topic and I´ll come back and tell you what I´ll find.
JAMES: I do wanna argue in favor of the aliasing. I think I can give an example, where it’s very helpful. For example, I’m a FIND guy and I use FIND, and I believe that’s the correct one. If you use DETECT, you’re just wrong. I just want you to know that. However, but if you are in active record, right? It needs FIND for its main thing, maybe less so now, where we tend to use the other methods. But in all of active record, FIND was a very important method. And we still use it for like ID lookups, right? And the problem is the way active record does it’s associations, it returns that association object in the middle, when you call .com ends or whatever, it’s actually a association object, and you can call class methods through it, so you .com ends .find, where if you do that, you are going to get active record FIND.
But what if I really wanted to load the comments and iterate through them then using enumerable find? Well, you can actually do that using .com and .detect, because there’s the, alias there because active record appropriate find, but I still have access to that other method, that other way to get to Ruby. And of course, you could do that in other ways; you could alias it yourself at load time before active record was loaded or something, but I’m just saying that, having those choices means that even if active record stomps on to me, what is an important method, I can still get to it.
CHUCK: It costs you two more keystrokes though. My goodness.
BRIAN: Yeah, I’m probably going to be slower right, because the longer identifier. Yeah, it actually does make a copy of the method, which gets kind of complicated, because you can undef… you can make an alias and undef the other method, so that Ruby can’t look up in the class priority and find that method but you’ll still have access to it. And then obviously, we know how alias method chain… how that sort of thing can sort of overtime, devolve into a real mess, right?
So one of the things that I think are interesting about aliases is identifying which methods are aliased. I think Ruby needs better tools for that. And also, where we keep consistency. If we wanna make something… it’s almost like we are creating this duct typing on module sort of thing, where I have this concept of comparable or enumerable, and then I wanna override in a way and say, “Well, it’s kind of like an enumerable, because it responds to find, and that’s kind of doing something that we call find in here.” You know what I mean? And then we start layering those concepts, and I think that that complexity then mainly gets blamed on alias, where it’s a question of, “Have we taken a concept that’s been established in Ruby, like find on enumerable and decided we wanted to layer a different concept on top of that and is that where the complexity comes from?”
JAMES: That’s a good point. The alias copying thing is actually a good thing, I think, because that’s actually what makes things like alias method chain possible, in that you can copy the method somewhere else, and then write a new version of that method that refers to the copy. So, you can still get the old behavior that modify it in the kind of wrap around filter kind of way, sort of. So I would say that I’m pretty pro to Ruby’s aliasing feature, and don’t necessarily consider it a minus, but I can definitely see why people ask things like, “Well, which one do I use, linked or size?” The answer is, “It doesn’t matter.”
JOSH: Unless you are in active record. [Chuckles] so if I’m aliasing “collect” in my class, then I wanna make sure I’m also aliasing map. I mean, I’m not aliasing; I mean, I’m overriding collect, then I also wanna override maps, so that my API to my class is consistent.
JAMES: Yeah, I think that’s the good rule of thumb. And you can just write the one implementation and then use alias method to copy it over, right?
JOSH: [Chuckles] There you go. So James, I remember when you looked at my list, you said, “I hate this list.” So, what were you thinking about?
JAMES: That’s true. I did. When Josh brought up this topic, he made a list of items that we should talk about – we’ve talked about two of those now — and I looked at the list, and I immediately got mad. And I thought that was interesting, because Dave Thomas has these great examples he’ll show in his talks sometimes, where like Ruby becomes particularly picky about syntax, and he has a great one with regular expressions. And he’ll show it as just like a/b/c kind of thing and say, “What does Ruby consider this? Is this division or a regular expression?” Actually, its more interesting if you take three letters, m/n/o because of O being a regex modifier, meaning compile once.
CHUCK: Oh, interesting.
JAMES: So he’ll show these very different examples, and he’ll like put a space in there, and all of a sudden, Ruby treats it totally differently; and he’ll put another space in there and Ruby treats it differently again, turning it from like regex into division. Some of them are syntax errors, where Ruby just throws and refuse to interpret it at all. It’s very interesting, because Dave’s point is that, we always say we have whitespace-sensitive languages, but there are scenarios where Ruby is whitespace-sensitive. You know, and it will change the meaning of your program or whatever.
But Dave says — and I’ve always felt this way — that Ruby does this, to try to be more helpful to us; to try to talk more like we do, and less like a computer does; to try to be more friendly to our way of expressing things. Usually, when we divide two things, we’ll put spaces around it or whatever. So Ruby will use that rule to say, they are probably dividing here not using a regular expression or whatever. And I think that’s interesting. So I’ve always liked that Ruby’s grammar is complicated and horrible, because it’s got edge cases. It’s a lot like English, right? English is complicated and horrible, you know? And Ruby’s grammar is kind of the same way. But I bet Brian has a very different opinion on that.
BRIAN: Actually, I love Ruby. And find that the things that you are mentioning here, with the trailing slash, oh yeah, that’s I think a thing that a lot of people don’t even learn about regular expressions early on. They have this modifier flags, they can follow that trailing… closing character And then Ruby has these other complex, I think they are rather complex ways to introduce things like a literal regular expression or literal coded array of strings, that sort of thing. And Josh even proposed a great one that you can use %S and then [inaudible] ends, and then basically get an array of symbols out of that.
I’ve dug around in the parser a whole bunch… extracted MRI’s Matz Ruby Implementations Parser into thing that we call “Melbourne” in Rubinius, and I’ve been working with the 1.9 grammar a ton, recently. And it is complex; it’s a very complex grammar. It’s got a lot of state that… the part that’s breaking up the string of characters into words in the language, it’s got a lot of statement that goes between that, and between the parser itself, the part that’s figuring out when you say, foo and then an identifier and then a curly brace, that you are attaching a block to that identifier and not doing a hash literal, these sort of things that we typically don’t think about.
I think the reason for that is — James, exactly what you said — is Ruby tries to be a more humane language, and more in the realm of people talking about things. And we are fantastically good at disambiguating things. All around us, there’s tons of stimuli constantly, words and facial expressions from people, and body language, and phrases that they are saying, that we are constantly figuring out the right meaning for those things. And I find that a lot of Ruby code that I read, I have far less trouble understanding it than other languages.
First of all, it’s because I spend a lot of time in it, but also I think I’m very sensitive to how much effort my brain is kind of trying to put into decoding symbols and stuff. I mean, for instance, PHP because of the different symbols that are used in the code, I spend a lot more time tracking each individual identifier; trying to figure out, “That one dollar sign, okay, identifier, I need to know what that means versus $$ identifier,” and that sort of things. I’m a huge fan of Ruby’s more complex grammar. I think that sums it up.
JAMES: So I realize I didn’t actually answer Josh’s question, and talk about the things I’m not a fan of in Ruby. I think if I had to pick my two things, I would first attack our documentation.
JAMES: We’re bad about that, and I’ve personally spent energy trying to make it better. Although I have learned something messing with Ruby’s documentation, so I should probably mention that. But our API documentation is usually what’s atrocious; that we tend just not to do that and people end up just looking at the code, because it’s easier to read the code, than figure it out from the terrible API documentation. But we do have other kinds of documentation, that I think are just fantastic; like in our blogosphere and stuff like are so strong. If you read things like Avdi’s blog and stuff, you can get, a lot of times, really in-depth with the concepts of Ruby, and stuff like that. And so I find that side very good, but our API documentation very bad.
And I’m becoming less convinced of the import of API documentation or at least at certain levels of leaning. So I think really, documentation in general is due for a breakthrough that we’re going to find a better way to do it at some point. But I would say Ruby is generally bad about that.
CHUCK: Can I stop you real quick, James? I have a couple of questions about that. First off, people are writing the documentation, so I’m wondering if the poor documentation — or poor level of documentation — is that fault of the language? Is it the fault of the tools that they are using to write the documentation? Or is it the fault of the people? Is it a kind of a combination of the three? Is there something I’m missing?
JAMES: I think it’s a really good question. I would love to know where it comes from, because other communities do this better than we do. Like I mean if you look in the Java community, it’s a standard practice to have good and complete documentation in the Java community — and that’s not true in our community. And if I would take a guess — this is me totally guessing — but in Ruby’s early days, there were language barrier problems, because you had the Japan side and the English side. And i think that lead to poor documentation in the beginning, and then that we kind of took it as a lead by example from there. So I think because we started off the wrong foot in the documentation, and then we just kind of stayed on the wrong foot. But I’m totally guessing.
CHUCK: So we’ll blame it on Dave Thomas then.
JOSH: [Chuckles] well, you can blame rdoc on Dave Thomas. I think that there may be something to that, James, but I think that you can’t really compare Java and Ruby; they are apples and oranges, because when someone ships you a Java library, it’s a bunch of compiled class files. When you grab a Ruby gem, you can always just open it up and look at the source code for it, and see how it works.
CHUCK: So you are making the case that Java has the documentation because it’s by necessity, you need because you can’t look at the code itself.
JOSH: Yeah, yeah. And then in a lot of cases with Ruby, you don’t actually need documentation. It’s actually really easy to just look at the code and see how it works.
CHUCK: That’s true. I’ve seen people document methods that are basically just like one assignment or something, and you are sitting there going, “So the documentation is longer than the method.” [Chuckles] And it’s something so simple, that it’s more expressive in code than it ever will be in English.
JAMES: I think that you guys are bringing up a good point. And for us, that doesn’t matter. Like if I’m working on a project, and I wanna see how some Rails plugin works, then I do a gem unpack, dump it in a directory and go read the source, and that’s true. I don’t have a problem doing that, and it’s very easy. However, I think it’s important to realize that activities like that are extremely hostile to new programmers.
JOSH: I agree with you completely. I’m just saying that for experienced programmers, and a lot of the early adaptors for Ruby, they were early adaptors, they were doing that because they were cutting edge kind of people, so they were up to this reading the source code. And maybe there was some language barrier that was involved in how that arose. But the nature of Ruby has been that it’s possible to, I mean, the community has made a huge amount of progress and grown and people have been using Ruby libraries pretty well for years, even with what we might consider to be an inadequate documentation, just because they can open up the Ruby source files and look at things.
CHUCK: Yeah, we could hold this for an entire episode, so I’m going to give it back to James, so that he can go on on whatever else he was going to say.
JAMES: So the other complaint I have about Ruby in the past, has definitely been the speed. And I definitely wanna qualify that, because I’m not a big person that thinks that Ruby needs to be as fast as C; I don’t have any illusions like that. I often believe, most of the time, that in speed, it’s actually an architecture change that gets you the boost that matters; switching to an algorithm that does it more efficiently or switching to a multi-processing model, that allows you to do more work at once. I think you’ll always get better, bang for your buck out of something like that, than actually doing… hoping that Ruby’s inject method is fast enough.
But at the same time, I felt like older versions of Ruby were unnecessarily slow. That when I did an inject, it took more time than it needed to, based on the level of difficulty and that stuff. But I will say that between the new VMs and stuff, Ruby 1.9, Rubinius, and JRuby, I feel that pain a lot less. So we’ve come forward I think quite a bit, and I don’t really view it as a major minus. But I definitely would like to definitely would like to see us to continually improve in that area as much as we can, recognizing that Ruby is a very difficult language to optimize — I’m assuming. Right, Brian?
BRIAN: It can be a difficult language to optimize, but the challenge has been sort of essentially that architecture of MRI before 1.9. So we’ve known about bytecode virtual machines for a long time, and we know that they are a great deal more efficient and faster than something that’s just interpreting the abstract syntax tree of the grammar.
So in some respect James, I think your point is spot on. Ruby has lacked in the sophistication of the technology that we are pairing with the sophistication of the language; our garbage collector story has not been the best, or our virtual machine story has not been the best, and our concurrency story has not the best, you know? These are all things that are being improved. Ruby 1.9 is making huge strides forward in terms of speed, and there’s a lot of attention to the garbage collector now.
Rubinius, from the start, was the idea of thing thing, this is a quote from Evan or a summary of what Evan often says is that, “If you can get Ruby technology to where Smalltalk was a decade ago or 15 years ago, we would be light-years ahead.” So, you know, the JVM is a very complex project and a complex language surrounding it, and i think corporate issues with Oracle and stuff like that, that make me very uncomfortable. But it’s also a platform that I’ve seen a tremendous amount of attention in terms of technology. So yeah, JRuby is definitely in concurrence to garbage collection, and just in time compiler generate a machine code is taking Ruby forward.
Rubinius, the whole goal of Rubinius is basically to make all those things directly available to Ruby. So, I think it has been a problem with Ruby; it’s something that we are addressing. I think it’s beyond passed the time that we address it, but I don’t think that it’s going to be one of the things that detract from Ruby in the future.
JOSH: Can we have 2 minutes just to address a little of the ecosystem stuff?
BRIAN: I guess.
JOSH: So, one of the things that I used to hear a lot about Ruby was that, “Oh it’s a great little language, but there’s really no library support for doing system programming.”
CHUCK: [Laughs] I sat down with Wayne E. Seguin yesterday, and he was showing off his SM framework.
JAMES: It’s a great framework.
CHUCK: And you know, we were just chatting for a few minutes and he’s like, “I got to show you something cool.” And he showed it off to me. And I used to be a sys admin, so I mean, five minutes in, I’m sitting there going, “Oh my gosh dude, where was this ten years ago when I was system admining?” Because it would have saved a ton of time and trouble. You could have actually written shell scripts that made sense, stuff like that.
JOSH: So not just talking about shell scripting, but that’s an important part of it. I’m talking about things like interfacing to low level system services, network programming, dealing with process management — the kind of things that you typically program in shell script or hardcore math programming, what have you. There’s a lot of things that Python guys say, “Oh, this is great about Python.” And then one of the big reasons that people go with JRuby is because there’s all these JVM libraries that you can do pretty amazing stuff with. And if I’m being fair about this, I got to say Ruby is actually relatively weak in that area.
JAMES: That’s interesting. So I do a little bit of system programming, and I find Ruby does pretty good on a POSIX environment, where fork process and them in to something else and stuff like that. And I really like that, and I use those features a lot. I guess when I wanna mess with process tables and stuff like that, I tend to just go the Unix way anyway, read from the proper device to get the information that I want or stuff like that. But I think I can understand what you are saying about. I’ve often felt like I’ve had to dance around the way to kill the exact process I wanted to kill because I didn’t start it or whatever. I have felt that sometimes, so I guess I can see where those libraries would come in.
JOSH: James, I remember listening to a podcast that you did a while back about how do you do process monitoring in Ruby, and just how ridiculously complicated it was, that it took you a very long time to describe all the hoops that you had to jump through to have a sentinel process around watching the other processes. And that seems like that’s a problem that got solved it a while ago in just regular system programming.
JAMES: Yeah, that’s a really good point.
BRIAN: It seems like it’s a very complex problem that is not really solved. I mean, if you look at the complexity of something like Unicorn, I think that does zero downtime deploys and stuff like that. There’s a lot of stuff that’s required to do that, so I’m not surprised that’s hard in Ruby. I will just point out that one of the things about a language’s libraries and stuff, if a language isn’t up to the task of executing some library code fast enough, people tend to drop down to another language. C has been the go to language for Ruby.
And way before rubygems.org and way before ruby gems was actually a big deal or something called Ruby application archive, which is still out there, and there’s probably something like 45,000 I think different libraries on there. A good portion of those are bindings to C library. I think Ruby has a ton of libraries available to it. The question I think is whether or not they reduced the complexity of what you are trying to do enough or whether or not they throw just this big chunk of C in your… and so if you don’t know C and the library doesn’t function, can you get past it?
I think Ruby is not particularly poor on library. There’s all kinds of crazy stuff out there. And if people really wanna do more numeric processing, it’s very easy to hook something up [inaudible] to Ruby. It’s really easy to do that. Probably easier to do it than it is with Python, because we have a better interface [inaudible] for instance. So, I think it’s fairly strong. I think that people wanna see more libraries. We need to like convince people that it’s something they can actually accomplish; write a library in Ruby and it will perform well enough.
JAMES: I agree with Brian. I’m old enough to remember the RAA and have used it a lot. And there’s some gems on there people still don’t use enough. A few of them I believe have even been brought forward to the 1.9 era. One of my personal favorites is “narray,” so if you need to do some very fast math, narray basically lets you borrow C’s numbers. And so you can do wicked fast math, a bunch a whole bunch of numbers at once. So that’s a cool library.
Another one I love is rbtree. That one may even be on GitHub now. Narray might be too. But rbtree is a binary tree, which can be like a hash but with really great lookup times, if you know how you are going to structure them so they will stay in an ordered way and you can order through them, but the ordering doesn’t necessarily have to be in such an order like it is with Ruby 1.9’s hash. So rbtree is another great one I love.
But yeah, I think we do have some tools. I have heard the complaints about the science and math libraries being pretty weak from time to time. I think that kind of represents a little bit of difference in the Ruby mindset though. A lot of times, we’ll just shell out and pipe it to some command line tool, whereas Java programmers would prefer to have the whole thing happen in the JVM and just get all that. But Ruby is not afraid to package up some data and throw it down the pipe, I think is kind of the difference.
CHUCK: Nice. So we can disambiguate an alias or map data or pipe it on to doing some picks now.
JAMES: That’s right.
CHUCK: That was awful. I’m sorry.
JOSH: [Chuckles] Okay, I’m satisfied.
CHUCK: [Chuckles] Okay, well with that, I think we are going to have to move on to our picks if we are going to stay on track with time. Since you are satisfied, we’ll let you go ahead and do the first pick or picks.
JOSH: Okay. Cool. So, my first pick is a blog post; and it’s about stand up meetings, so I think that a lot of rubyists are prone to agile development and we use extreme programming practices and one of those practices is a daily stand up meeting. And yet, there’s a lot of us who don’t have any kind of training in how this works; people think doing a morning stand up was just standing up and talking about whatever. And sometimes, these meetings can devolve into meetings, rather than what a stand up is really meant to be.
So I saw an update recently of one of the canonical descriptions of standup meetings. It’s by Jason Yips, and he’s a Thought worker. He wrote this a while back, but he just updated it for [inaudible] material and better descriptions. I´ll put a link in the show notes, but it’s on Martin Fowler’s website. It’s a very long… it’s a surprising blog post, because stand ups are just these quick little things, but there’s a lot of material in this post and the thing that I like about it is that it talks about the different ways that you can do things; it’s not “this is a one size fits all process,” it’s “Oh, you have a small team. Here’s how you do it.” “Oh, you have all the stakeholders present, here’s what you wanna do.” “Oh, you don’t have all the stakeholders. Here’s how to deal with that.” So it’s a really great read if you are doing morning stand ups and you don’t feel like you are getting the most out of them, this is definitely something worth reading.
And then my other pick is office toys. So I just ordered something from officeplayground.com and it’s a water filled bouncy ball full of flashing LED lights and glitter.
JAMES: Oh my god, that’s awesome.
JOSH: Yeah, it’s great. [Chuckles]
CHUCK: I think my kids would like that.
JOSH: It’s great. So I looked around and I found officeplayground.com and they are the only place that had these things. A friend of mine gave me one of these and I thought it was great, I needed to buy more. So office playground is good for like little things. And then the other site that I really like is, thinkgeek.com and their geek toy section. And they have just really incredible stuff like push pins shaped like ninja stars that you can embed in your cork board. So they are of course the place that came up with the child-sized eviscerated Tauntaun sleeping bag.
JAMES: It will be also awesome if you’re a parent, check out their kids section. I buy my kids like tons of stuff off of there.
JOSH: Yeah. I think you pretty much can never enough fun distracting things in your office.
CHUCK: I have a feeling I’m going to wind up buying things off of Think Geek for my kids, and my wife is going to look at them and, “What?! What is this?”
JOSH: [Chuckles] Okay. So that’s it for me today.
CHUCK: All right, go ahead James. What are your picks?
JAMES: So, I think I’m going to make an unusual pick, and probably not popular. Let’s see if I can get hate mail for this one. But since Rails…
CHUCK: Nooooo! Oh, sorry.
JAMES: Since Rails 3.1 was released last night, I thought I would go ahead and make a pick for Rails 3.0, not 3.1. And while I’m at it, why don’t I go ahead and throw in a pick for Snow Leopard. A long time ago, I used to be definitely the bleeding edge guy who always updated the second something was released. I mean, Apple announced a new operating system, I ordered it that second and installed it. And while it was always cool to play with the new shiny, you always run into things that like break immediately, and you have to wait on people to get the updates out and stuff like that. And then eventually, you get back to where you get a great working system and stuff.
So I’m actually – in a herculean effort — been resisting the Lion, because I have two pieces of software that aren’t yet compatible with it, but in both cases, they are working on it and should be out soon. And upgrade to Rails 3.1, I was looking at it last night and, “Yeah, I’m going to have to change all the asset stuff in this one app and stuff. And it’s just working just fine, and the asset stuff doesn’t really buy me anything I haven’t really figured out how to handle.”
So anyway, I kind of resisted upgrading an app that I’m currently working on to Rails 3.1 I’m not saying don’t upgrade — of course, I still love playing with new tech and all that — I’m just saying you don’t have to upgrade the day something comes out. But if you choose to wait a little bit, then it’s a more pleasant experience, and that you can slide up when you are the stuff works there and things like that. So I’m recommending retry, although I realize it’s horrible hard to not being the very first person to use a piece of technology.
JOSH: That is awesome, James. So I worked at Apple a while ago, and the QA team that I worked with had some letter head, some email letter head that they would use that said, “Apple Computer: where quality is job 1.1.1..”
JAMES: [Chuckles] That’s awesome.
CHUCK: [Chuckles] Oh man. So James, the anti-fan boy.
JAMES: It’s my new strategy. But you know what, everybody got Lion, and some people were like complaining on Twitter and I’m like, “You know, still working for me fine, and Apple is not going to cancel support for Snow Leopard in the next 30 days or something. I’ve got little time.”
CHUCK: It’s funny because about a week before they released Lion, I had Snow Leopard crash on me like three times. And then the week after they released Lion, it crashed on me another two times. I’m like, “Screw this. They can’t be any worse than Lion.” And I’ve upgraded and haven’t had any problems.
JAMES: Oh, that’s good.
CHUCK: Anyway, Brian.
JOSH: I got to say, I’m really excited about the upcoming Rails 3.1 release.
JAMES: It’s out, Josh. Haven’t you seen?
BRIAN: That happened yesterday.
JOSH: No, the 3.1.1
CHUCK: [Chuckles] All right. Go ahead, Brian.
BRIAN: I have a couple of things. One is people ought to learn about a concurrency mechanism called Actors. And I think it’s fantastic. It’s old, it’s been around for a long time, some great research have been done on it. And there is a guy who got a terrific blog called, It’s Actors All The Way Down, where he covers a lot of the simple patterns in using Actors. Rubinius has had an Actor implementation from MenTaLguY and Tony Arcieri since I think 2007. So I think within the first year, but it hasn’t gotten any attention, that I think that it deserves in the Ruby community. Another guy has written a thing called … for doing background processing that also use Actors.
In Rubinius, we’ve removed the gil in 2.0 and really excited to have full Ruby concurrency, and that can be a wonderful thing, or a huge kind of worm, so I hope people are going to take the necessary good full thread and locking route. I think there’s better things for us to use. I guess we’ll have the link in the whatever people can access… is a blog though from a guy who has written an entire language around the concept Actor. It’s going to broaden your mind a little bit.
The other thing that I think is really fascinating, is that Ruby is an object-oriented language, and we sometimes think everything about being an object-oriented language means everything is sending messages to objects. And I wanna introduce the idea that there’s actually some stuff in Ruby, reflection methods, like respond to and instance methods and things like this, that can be used in code to make things more complicated than they need to be, actually and actually destroy some of the object oriented-ness of code. I can’t tell you how it frustrates me to see code that says, “If respond to, call this method.” I think it’s a terrible perversion of the idea of sending messages to objects and letting them figure it out.
CHUCK: All right.
JAMES: Brian, kind of along your last one. It’s always bothered me that caller in Ruby returns an array of strings, and then I have to parse it out to find the file and the line and all that. I’ve always thought it should return an array of objects that I can call line on or file on or whatever.
BRIAN: I absolutely agree. In Rubinius, our back traces is actually an array of objects, and we provide an MRI compatible array of strings that you can instead of using caller, you can use the VM to sort it directly get back this array of location objects and you can find out a lot of information about. And so I absolutely agree. I would loved to see that aspect of Ruby objectified properly.
CHUCK: All right, I guess it’s my turn. I’ve been trying to what my picks would be and [chuckles] I’m kind of drawing a blank. I was on the road for most of the day yesterday and got into Boulder last night.
JAMES: So your picks is Boulder, Colorado?
CHUCK: Sure. I’ve seen about six blocks of it, other than what I saw driving in. I guess my couple of picks, one thing that’s been really nice on the way out here is having my iPad, and having the Netflix app on it. It just helps me relax when I could just kind of hang out, lay on the hotel bed, prop the iPad up and just watch a show. And so, I guess those are my picks are the iPad and the Netflix for the iPad. Just the streaming content, there’s a ton of it — it’s awesome. So you just hook in to the hotel Wi-Fi and watch.
And one other pick that I usually use on trips like this is Skype, and not just for recording episodes like this, but it’s nice to do the video chats my kids and my wife, to see them and my kids gets excited and say things like, “Daddy, you are on the computer,” and you know, they are amazed that they can see me on the computer. So, those are my picks. And you know they make these conference trips a whole lot easier, so we’ll go ahead and wrap this up. I just wanna thank our panelists again for coming on to the show. Once again, our panelists are Brian Ford.
BRIAN: Thanks everybody, it was a pleasure to be here. And I really appreciate the invite.
CHUCK: You are most welcome. We have James Edward Gray.
JAMES: Thanks for coming Brian, and thanks for everything you do on Rubinius for us.
CHUCK: Yeah, absolutely. And Josh Susser.
JOSH: Good time as always. Although I got to say, I really miss having David on the show.
CHUCK: [Chuckles] Yeah, I don’t know where he is today.
JAMES: We’ll track him down.
CHUCK: Yeah, and I’m Charles Max Wood. A few things that you may wanna know, the show notes are at rubyrogues.com. You can also find us in iTunes, and if you look us up and you like the show, then leave us a review and let us know what you think. You can also follow any of us on Twitter. We’ll put links up in the show notes. And if you have any feedbacks on the show, then you can tweet to @rubyrogues or you can tweet me, I’m @cmaxw, and we do take that into account. And then again if you wanna just reach us through any other means, most of that information is up on the show notes. So, thanks for listening, and we’ll see you next week.
JAMES: Also as a reminder, don’t forget that the Ruby Rogues is reading Exceptional Ruby by Avdi Grimm, this month. We are going to discuss it on our early September episode. I think it’s September 7th or 8th, something like that. So, if you wanna follow along, get the book, read along with us. You can send in questions through us if you like. We’ll grill Avdi on your behalf, and you can learn about this awesome book, that’s out in the Ruby community right now. So join us for the book club in September.