tag:blogger.com,1999:blog-11788780.post8112946283044490906..comments2023-12-29T13:22:33.104-08:00Comments on JJinuxLand: Ruby: nil is a Billion Dollar Mistakejjinuxhttp://www.blogger.com/profile/03270879497119114175noreply@blogger.comBlogger38125tag:blogger.com,1999:blog-11788780.post-75752752274990360482013-11-21T21:00:58.381-08:002013-11-21T21:00:58.381-08:00If you don't like it, override Hash#[](key) to...If you don't like it, override Hash#[](key) to raise an error if the key doesn't exist, and even have the error message helpfully tell you what keys you can use. Yay Ruby ;)Chad Woolleyhttps://www.blogger.com/profile/04298952972087713297noreply@blogger.comtag:blogger.com,1999:blog-11788780.post-34789949807441428492011-07-16T07:49:43.656-07:002011-07-16T07:49:43.656-07:00Eiffel 6.4 has removed this problem. They say tha...Eiffel 6.4 has removed this problem. They say that Eiffel is "void-safe". In "Masterminds of Programming" Bertrand Meyer said, "I think it is a major achievement because it removes the major potential runtime problem that still exists with object-oriented development. This is the kind of thing that we want to do to increase the reliability of software developers." [p. 438]jjinuxhttps://www.blogger.com/profile/03270879497119114175noreply@blogger.comtag:blogger.com,1999:blog-11788780.post-90092938878325785672011-05-05T12:27:17.756-07:002011-05-05T12:27:17.756-07:00> No, I was talking about whether NULL should e...> No, I was talking about whether NULL should even exist. There are some heavyweights in the database world who do not believe in the entire concept of NULL.<br /><br />I wasn't aware of that. I don't have a problem with NULL in databases. I just wish "NOT NULL" was the default.<br /><br />> It didn't really seem that it was a problem with gems that you were addressing. It seemed more that you wanted to be protected from your own (mis)use of the behavior.<br /><br />I'm talking about everyone's code, not my own.<br /><br />> I'm simply saying that you don't like the fact that we use Hash#[] instead of Hash#fetch, where appropriate. Because if we did, this argument would be moot.<br /><br />I strongly suspect that it is fairly common for developers to use Hash#[] when they should use Hash#fetch instead. I'm only an intermediate level Ruby programmer. However, I've read "Ruby for Rails" and "Agile Web Development with Rails" cover-to-cover, and neither book made use of Hash#fetch as far as I could tell.<br /><br />> In other words, if a piece of code should raise an exception when a nonexistent hash value is accessed, then the programmer should simply use #fetch. If he doesn't, he's created a bug. Does that mean the language should be changed? Especially when most of the time the existing behavior is correct? <br /><br />Remember that I'm only arguing about default behaviors. I think Hash#[] should be strict by default. I think that making use of an uninitialized instance variable should raise an exception by default, etc.jjinuxhttps://www.blogger.com/profile/03270879497119114175noreply@blogger.comtag:blogger.com,1999:blog-11788780.post-10009365291283079322011-05-03T15:43:39.696-07:002011-05-03T15:43:39.696-07:00> In the cases of databases, I wish the default...> In the cases of databases, I wish the default was NOT NULL. <br /><br />No, I was talking about whether NULL should even exist. There are some heavyweights in the database world who do not believe in the entire concept of NULL.<br /><br />> That means that even if I always remember to use .fetch(), it doesn't rescue me from gems that don't.<br /><br />It didn't really seem that it was a problem with gems that you were addressing. It seemed more that you wanted to be protected from your own (mis)use of the behavior.<br /><br />In any event, the gems I use are so 1) well-written, 2) well-tested, and 3) widely-used that I don't think I've ever had a problem with their use of this behavior. Certainly not enough to require a change in a fundamental Ruby class.<br /><br />I didn't make myself clear about "the Ruby community." I'm not saying you don't like the community or that you shouldn't belong to it. I'm simply saying that you don't like the fact that we use Hash#[] instead of Hash#fetch, where appropriate. Because if we did, this argument would be moot.<br /><br />In other words, if a piece of code should raise an exception when a nonexistent hash value is accessed, then the programmer should simply use #fetch. If he doesn't, he's created a bug. Does that mean the language should be changed? Especially when most of the time the existing behavior is correct?Mark Wildenhttps://www.blogger.com/profile/07153901140004937121noreply@blogger.comtag:blogger.com,1999:blog-11788780.post-70123115775278769602011-05-03T13:20:17.252-07:002011-05-03T13:20:17.252-07:00> There has long been a huge debate in the data...> There has long been a huge debate in the database world about NULL. Most people like having it; some don't. But this is a different discussion. This is about whether or not Ruby hashes should throw an exception instead of returning nil.<br /><br />In the cases of databases, I wish the default was NOT NULL. However, it doesn't usually burn me as badly because I usually remember to add NOT NULL if that's the behavior I want. Note also that NOT NULL is determined once at table creation time, not at query time.<br /><br />> I like the current behavior, and it seems that the majority do as well. You don't, but you can obtain the behavior you want with #fetch.<br /><br />I think Martin made a good point on this topic. The problem is that [] is the default operator for getting something out of a hash, and it returns nil. Many gem creators use [] without thinking of the ramifications. That means that even if I always remember to use .fetch(), it doesn't rescue me from gems that don't.<br /><br />> So what's the problem? Are you saying that we should not like the current behavior?<br /><br />I'm just trying to explain my opinion on the subject and provide some interesting commentary in comparing the situation to other languages.<br /><br />I do think it would be cool to create a gem that monkey patches Hash and Object to make things strict by default. Unfortunately, I suspect that this would break other things like Rails that may be expecting less strict behavior.<br /><br />Remember when Rails 3 made it so that templates escaped HTML by default? I feel the same way about nil--it'd be nice if things were a little bit stricter by default.<br /><br />> Is your post about Ruby<br /><br />It's about Ruby's use of nil.<br /><br />> or about the Ruby community?<br /><br />I actually really like Ruby's community. Programmers in the Ruby web world seems to work together much better than the Python web world. I love the fact that Merb merged back into Ruby. I love Ruby Toolbox. I love the fact that I can go to a Ruby on Rails company and understand the code within hours rather than days.jjinuxhttps://www.blogger.com/profile/03270879497119114175noreply@blogger.comtag:blogger.com,1999:blog-11788780.post-60053255146548287372011-05-03T13:02:50.760-07:002011-05-03T13:02:50.760-07:00There has long been a huge debate in the database ...There has long been a huge debate in the database world about NULL. Most people like having it; some don't. But this is a different discussion. This is about whether or not Ruby hashes should throw an exception instead of returning nil.<br /><br />I like the current behavior, and it seems that the majority do as well. You don't, but you can obtain the behavior you want with #fetch.<br /><br />So what's the problem? Are you saying that we should <i>not</i> like the current behavior? Is your post about Ruby or about the Ruby community?Mark Wildenhttps://www.blogger.com/profile/07153901140004937121noreply@blogger.comtag:blogger.com,1999:blog-11788780.post-31985198777424043092011-05-03T12:51:46.176-07:002011-05-03T12:51:46.176-07:00Rush is a new programming language coming out of M...Rush is a new programming language coming out of Mozilla that is similar to C++:<br /><br />http://en.wikipedia.org/wiki/Rust_(programming_language)<br /><br />I found this line interesting, "The system is designed to be memory safe, and does not permit null pointers or dangling pointers. Data values can only be initialized through a fixed set of forms, all of which require their inputs to be already initialized."jjinuxhttps://www.blogger.com/profile/03270879497119114175noreply@blogger.comtag:blogger.com,1999:blog-11788780.post-58695027197945537752011-05-03T10:40:57.563-07:002011-05-03T10:40:57.563-07:00Maybe I can explain it this way. The problem with...Maybe I can explain it this way. The problem with nil is that it often pops up at times when you don't expect it. This leads to bugs. In C, they're called NULL pointer dereferences and they lead to core dumps.<br /><br />This problem even happens in Java, which has an extremely pedantic compiler. Any good Java programmer can tell you of a time where a null got to a place in the code where he didn't expect it.<br /><br />If you think of the number of bugs this problem has permitted in all the languages that support NULL, you'll see why Tony Hoare called it a billion dollar mistake. Tony Hoare isn't some random blogger spouting off useless opinions like me ;) He's a famous computer scientist.<br /><br />These days, languages like Haskell and Scala have new approaches that can get rid of this whole class of bugs. For instance, Haskell's "maybe" monad prevents nulls from getting anywhere where they aren't expected, and the compiler can catch you if you don't write code that can handle the null. Most of the time, null isn't allowed, and you don't have to write any special code to handle it.<br /><br />Python and Ruby don't have a compiler to apply such checks. However, Python will rely on exceptions for certain "exceptional situations" whereas Ruby falls back to using nil. I really like Ruby, but I think this is one time where I prefer Python's behavior.<br /><br />Of course, that's just my opinion, and you're free to disagree.jjinuxhttps://www.blogger.com/profile/03270879497119114175noreply@blogger.comtag:blogger.com,1999:blog-11788780.post-90207233259194622882011-05-03T10:23:10.685-07:002011-05-03T10:23:10.685-07:00> The problem you are describing is imaginary a...> The problem you are describing is imaginary and not backed by real world scenarios.<br /><br />I've spent the last 1.5 years as the lead engineer at a startup using Ruby on Rails. We built fandor.com. During that 1.5 years, I often encountered exceptions that looked like "NoMethodError: undefined method `foo' for nil:NilClass". It always leaves me wondering, how did that nil get there? That's certainly a "real world scenario" as far as I'm concerned because it happened to me in the real world ;)<br /><br />The problem is that I have a nil somewhere where I didn't expect it. I would have preferred Ruby to raise an exception at the source of the problem (maybe when I looked up something in a hash) rather than later (when I try to use the thing I looked up).<br /><br />> I came to Ruby from .NET and it has always been a pain to handle non existing keys.<br />I waste 3 lines of code to check for existence of the keys.<br /><br />Sorry, I don't know how .NET handles this. I do know how Python handles it, and it doesn't require 3 lines of code. I just write d["foo"]. If "foo" doesn't exist, I'll get an exception. If I want Ruby's behavior, I write d.get("foo"). The default is to be strict. That's all I'm arguing for--I want the default to be strict.<br /><br />> 99% of the time I DID need NIL instead of exception.<br /><br />I think we simply disagree on the "99%". Most of the time, I want the system to be strict. Once in a while, I want it to be lenient; in those cases, I'd prefer to explicitly tell it I want it to be lenient.<br /><br />> In Ruby the 1% can be handled using fetch method.<br /><br />I'm just disagreeing with the default. I think that it's particularly the case with instance variables. If I write @a, and @a isn't set yet, it's very likely a bug, and I want Ruby to raise an exception. <br /><br />If I write "self.a" in Python when "self.a" hasn't be set, I get an AttributeError. That's really helpful for finding bugs at their source instead of allowing them to fester.<br /><br />Thanks for the comment.jjinuxhttps://www.blogger.com/profile/03270879497119114175noreply@blogger.comtag:blogger.com,1999:blog-11788780.post-49275223428497223822011-05-03T10:08:57.070-07:002011-05-03T10:08:57.070-07:00Dmytrii Nagirniak wrote:
The problem you are desc...Dmytrii Nagirniak wrote:<br /><br />The problem you are describing is imaginary and not backed by real world scenarios.<br /><br />I came to Ruby from .NET and it has always been a pain to handle non existing keys.<br />I waste 3 lines of code to check for existence of the keys.<br /><br />99% of the time I DID need NIL instead of exception.<br />In Ruby the 1% can be handled using fetch method.jjinuxhttps://www.blogger.com/profile/03270879497119114175noreply@blogger.comtag:blogger.com,1999:blog-11788780.post-76491023627241542812011-05-03T09:44:18.311-07:002011-05-03T09:44:18.311-07:00> As for kicking anyone out from community, wel...> As for kicking anyone out from community, well, no one said that.<br /><br />I was referring to the comment "Maybe Ruby just isn't the right language for you?"<br /><br />> All Mark meant is that why torture yourself if it's so against the hair growth.<br /><br />I'm a language guy. I code in a lot of languages. If one language has a better technique for a particular problem, I think it's useful to point it out. Personally, I think the way Scala (using Option) and Haskell (using Maybe) approach the problem is fascinating.<br /><br />> There should a reason why you decided to make this post (and port it on Ruby Reflector).<br /><br />I write about both Ruby and Python on this blog. Most of my readers are Python programmers. I don't even know what Ruby Reflector is, and I didn't know this blog post was on it.<br /><br />> Did you really expect that everyone would agree with you and say "oh, right, how did we live all these years"?<br /><br />No, I suspected that there would be push back, but I felt like I had to make my point anyway. I'm not actually trying to pick a fight. Notice that the very first sentence in the post was "The fact is, I really like Ruby."<br /><br />I'm trying to pick a feature and write intelligently about how different languages handle it. However, it seems that many people aren't really addressing what I really said.<br /><br />I said that the guy who invented the concept of null said it was a bad idea. I thought that that was a pretty interesting thing.<br /><br />I'm saying that Scala and Haskell have better approaches. I thought that those two things would be useful insights.<br /><br />> When you post insights like this, you have to expect some argument and smirks, while 99.99% of the world will simply ignore.<br /><br />Unfortunately, that's true. However, some of the comments were really helpful. For instance, Sean Huber showed me that it might be possible to write a gem that changes the behavior of Ruby for all the cases I care about. That reminds me of "use strict;" in Perl. It wasn't there originally. I was hoping that my blog post might instigate the creation of a "use strict" for Ruby.jjinuxhttps://www.blogger.com/profile/03270879497119114175noreply@blogger.comtag:blogger.com,1999:blog-11788780.post-29172546315557685062011-05-03T09:44:00.584-07:002011-05-03T09:44:00.584-07:00> Having those ugly existence checks all over t...> Having those ugly existence checks all over the place would, if nothing else, make the code completely unreadable.<br /><br />I don't know what ugly existence checks you're referring to. When I write "self.a" in Python, I don't have an ugly existence checks. Python will catch me, though, if I try to write "self.a" before I set "self.a".<br /><br />> If you need to check it specifically, go ahead -- there are several statements for that, but in most cases nil or not nil is all you need.<br /><br />Actually, if I try to access an instance variable that isn't set, I'd prefer the interpreter to catch me and raise an exception. That way I can correct my code. That's extra work for the interpreter, but it's not extra code for me.<br /><br />> In the case with f(:a => 1), I personally don't care if it's f() or f(:a => nil).<br /><br />Actually, my complaint about keyword arguments is that if you misspell one, you don't get an exception. In Python, you do. Misspellings have resulted in bugs for me, and they're hard to find. If Python raises an exception because I misspelled a keyword argument, it's trivial to spot and trivial to fix. To be fair, I think that my point may be slightly off topic, and I know it's going to be fixed in Ruby before too long.<br /><br />> As simple as that. If there's a case when I need to account for nil's as valid values (which is extremely rare if you think about it), I can check for the key existence specifically.<br /><br />> I believe it's the case when old habits are getting in a way. They aren't necessarily bad. They just don't apply everywhere.<br /><br />I code in many languages. Notice that I referred to how Python, Ruby, Haskell, and Scala solve the problem of looking up something in a hash that doesn't exist? I think Haskell and Scala's approaches are the most modern. I certainly wouldn't call that an "old habit". Why is it that no one has commented on the Haskell and Scala approach that I wrote about?jjinuxhttps://www.blogger.com/profile/03270879497119114175noreply@blogger.comtag:blogger.com,1999:blog-11788780.post-65611858137351560592011-05-03T09:43:45.394-07:002011-05-03T09:43:45.394-07:00> The title of the post is way bolder than it s...> The title of the post is way bolder than it should IMO. A billion dollar one? Really? :)<br /><br />The guy who invented the concept of Null wrote an article called "Null References: The Billion Dollar Mistake". My title is an allusion to that.<br /><br />> The whole ecosystem of Ruby is nil-centric if you will.<br /><br />Python and Ruby are very similar languages. Python uses exceptions in a lot of places where Ruby uses nil. There are a lot of things I like about Python and a lot of things I like about Ruby. However, the way Python prefers exceptions over nils is one place where I prefer the Python way.<br /><br />> The fact that you don't define class / instance variables upfront makes all the difference.<br /><br />That's true of Python too. However, if you try to access self.a before it's set, you get an exception rather than a nil. You still don't have to make any declarations.<br /><br />> A variable with any name can be defined at any moment and that's the beauty.<br /><br />Same in Python.jjinuxhttps://www.blogger.com/profile/03270879497119114175noreply@blogger.comtag:blogger.com,1999:blog-11788780.post-84103355416460727102011-05-03T02:16:36.707-07:002011-05-03T02:16:36.707-07:00@Aleksey, so to the point. Can't agree more mo...@Aleksey, so to the point. Can't agree more more.Dmytriihttps://www.blogger.com/profile/00858741986129879076noreply@blogger.comtag:blogger.com,1999:blog-11788780.post-4502546152717268012011-05-03T01:07:27.308-07:002011-05-03T01:07:27.308-07:00The title of the post is way bolder than it should...The title of the post is way bolder than it should IMO. A billion dollar one? Really? :)<br /><br />The whole ecosystem of Ruby is nil-centric if you will. The fact that you don't define class / instance variables upfront makes all the difference. A variable with any name can be defined at any moment and that's the beauty. Having those ugly existence checks all over the place would, if nothing else, make the code completely unreadable. If you need to check it specifically, go ahead -- there are several statements for that, but in most cases nil or not nil is all you need.<br /><br />In the case with f(:a => 1), I personally don't care if it's f() or f(:a => nil). As simple as that. If there's a case when I need to account for nil's as valid values (which is extremely rare if you think about it), I can check for the key existence specifically.<br /><br />I believe it's the case when old habits are getting in a way. They aren't necessarily bad. They just don't apply everywhere.<br /><br />As for kicking anyone out from community, well, no one said that. All Mark meant is that why torture yourself if it's so against the hair growth. There should a reason why you decided to make this post (and port it on Ruby Reflector). Did you really expect that everyone would agree with you and say "oh, right, how did we live all these years"? When you post insights like this, you have to expect some argument and smirks, while 99.99% of the world will simply ignore.<br /><br />Cheers.Aleksey Gureievhttps://www.blogger.com/profile/05062679270725461366noreply@blogger.comtag:blogger.com,1999:blog-11788780.post-83028577894446553772011-05-02T20:14:31.432-07:002011-05-02T20:14:31.432-07:00> And please do not remove my comment or otherw...> And please do not remove my comment or otherwise explain the reason why you do that.<br /><br />If you wish to leave a comment, please do so in a polite manner. I enjoy discussing differences of opinion, but messages that seem more inflammatory than useful will be deleted.jjinuxhttps://www.blogger.com/profile/03270879497119114175noreply@blogger.comtag:blogger.com,1999:blog-11788780.post-34958957575386007582011-05-02T17:07:09.096-07:002011-05-02T17:07:09.096-07:00And please do not remove my comment or otherwise e...And please do not remove my comment or otherwise explain the reason why you do that.Dmytriihttps://www.blogger.com/profile/00858741986129879076noreply@blogger.comtag:blogger.com,1999:blog-11788780.post-29080615548087164342011-04-23T12:07:27.410-07:002011-04-23T12:07:27.410-07:00Thanks, Martin. You said it better than I did.Thanks, Martin. You said it better than I did.jjinuxhttps://www.blogger.com/profile/03270879497119114175noreply@blogger.comtag:blogger.com,1999:blog-11788780.post-85900402416853733322011-04-23T09:58:45.337-07:002011-04-23T09:58:45.337-07:00I agree so much with your article. Most of the tim...I agree so much with your article. Most of the time programmers use the [] operator to fetch a value, when in fact they should use fetch. The problem here is that programmers don"t know their standard library well. If it's generalized, I think that the API has a problem.<br /><br />On top of that the bracket operator returns nil when the key is not found. It also returns nil when the value of a matching key is set to nil. So it has 2 semantic, which I think is wrong.<br /><br />Mark when you say that "Ruby is based on making programming fun". I think the undefined method for nil:NilClass, is the exception that I lose more my time on. For me this is not fun at all. And most of the time it's not caused by me but the gems creators.<br /><br />For me if you have to fail, fail fast.Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-11788780.post-43828050872601107892011-04-20T15:28:28.118-07:002011-04-20T15:28:28.118-07:00> I dislike the term "weakly typed". ...> I dislike the term "weakly typed". K&R C is weakly typed compared to ANSI C. Ruby is strongly typed in that you can't treat a reference to a foo as if it were a reference to a bar. Hence, I prefer the terms "dynamically typed", "duck typed", or "latently typed".<br /><br />You are correct, sir. :)Mark Wildenhttps://www.blogger.com/profile/07153901140004937121noreply@blogger.comtag:blogger.com,1999:blog-11788780.post-32452962794035275032011-04-20T13:30:54.890-07:002011-04-20T13:30:54.890-07:00> I used to use C# (and C++ and C). It's a ...> I used to use C# (and C++ and C). It's a fine language. It just has a different philosophy behind it than Ruby. Matz explicitly said that Ruby was to make programming fun. Ritchie, Stroustrup and Hejslberg had no such goals for their languages.<br /><br />You're right.<br /><br />> WRT shooting yourself in the foot, I was talking about strongly typing vs. weak typing. The goal of strong typing is to make programmers fix errors and to make programs run faster. Neither of these are Ruby's goals.<br /><br />I agree with your point, but I dislike the term "weakly typed". K&R C is weakly typed compared to ANSI C. Ruby is strongly typed in that you can't treat a reference to a foo as if it were a reference to a bar. Hence, I prefer the terms "dynamically typed", "duck typed", or "latently typed".<br /><br />(A C programmer might think that treating a pointer to a booger as a an int is a good idea, but it's snot!)<br /><br />> I didn't read the same conclusions from the Microsoft studies that you did. They were separate studies. One said that assertions catch bugs (certainly true). Another said that 100% code coverage did not catch all bugs (also true). The studies did not compare these groups. <br /><br />Excellent point.jjinuxhttps://www.blogger.com/profile/03270879497119114175noreply@blogger.comtag:blogger.com,1999:blog-11788780.post-79216503396671984042011-04-20T13:25:04.437-07:002011-04-20T13:25:04.437-07:00> Like with fetch, you can get a KeyError initi...> Like with fetch, you can get a KeyError initializing the hash with a block raise KeyError<br /><br />Nice tip! Too bad that doesn't help with the options parameter when you call a function like "f(:a => 1)".jjinuxhttps://www.blogger.com/profile/03270879497119114175noreply@blogger.comtag:blogger.com,1999:blog-11788780.post-45057121334209317382011-04-19T17:22:18.131-07:002011-04-19T17:22:18.131-07:00I used to use C# (and C++ and C). It's a fine ...I used to use C# (and C++ and C). It's a fine language. It just has a different philosophy behind it than Ruby. Matz explicitly said that Ruby was to make programming fun. Ritchie, Stroustrup and Hejslberg had no such goals for their languages.<br /><br />WRT shooting yourself in the foot, I was talking about strongly typing vs. weak typing. The goal of strong typing is to make programmers fix errors and to make programs run faster. Neither of these are Ruby's goals.<br /><br />I didn't read the same conclusions from the Microsoft studies that you did. They were separate studies. One said that assertions catch bugs (certainly true). Another said that 100% code coverage did not catch all bugs (also true). The studies did not compare these groups.Mark Wildenhttps://www.blogger.com/profile/07153901140004937121noreply@blogger.comtag:blogger.com,1999:blog-11788780.post-65988099280676976482011-04-19T15:14:17.071-07:002011-04-19T15:14:17.071-07:00Like with fetch, you can get a KeyError initializi...Like with fetch, you can get a KeyError initializing the hash with a block raise KeyError<br /><br />h = Hash.new { raise KeyError }<br /><br />h[:foo] = 'bar'<br /><br />puts h[:foo]<br />puts h[:foooo]Sebashttps://www.blogger.com/profile/15857779782013139928noreply@blogger.comtag:blogger.com,1999:blog-11788780.post-86052258543130506992011-04-19T14:35:01.404-07:002011-04-19T14:35:01.404-07:00> No, dynamically-typed languages are explicitl...> No, dynamically-typed languages are explicitly against the concept of protecting the programmer from himself.<br /><br />I'm going to have to disagree. In C, not only can you shoot yourself in your foot with buffer overflows, but you can arbitrarily point to random locations in memory, and you can forcibly cast a pointer to the wrong type. These are all things that Ruby doesn't allow you to do.<br /><br />> If you want protection use C#.<br /><br />Gees, you don't have to get nasty!<br /><br />(Although, I've heard that C# is a nice language that adds a pinch of Haskell to Java.)<br /><br />> Ruby is based on making programming fun (ask its inventor).<br /><br />There's nothing about fighting a "unsupported method called on nil" bug that is particularly more fun than a KeyError exception.<br /><br />Furthermore, about half the programming books out there on any programming subject promise that the subject they teach is somehow going to be more fun than normal programming.<br /><br />> Maybe Ruby just isn't the right language for you?<br /><br />Just because I disagree with some core philosophy of a language doesn't mean I should be kicked out of the community. There are things I disagree with in every programming language I use.<br /><br />> I ask because you say you use lots of assertions, which, while well established in the C/C++/C# world, just isn't generally done with Ruby.<br /><br />There's a reason I use assertions. A few years ago, Microsoft research published a paper with empirical data stating that programmers who used lots of assertions tended to have fewer defects than programmers who achieved 100% code coverage via heavy use of mocking and stubbing.<br /><br />http://www.infoq.com/news/2009/10/exploding-mythsjjinuxhttps://www.blogger.com/profile/03270879497119114175noreply@blogger.com