Rich Web Experience

JSFOne

Private Events

Blogs

View all Blogs >>
  • Venkat Subramaniam

    Founder of Agile Developer, Inc.

    I am delighted to receive copies of the Japanese edition of "Practices of an Agile Developer." It's nice to see Thirukural verses translated... more»

  • Michael Nygard

    Agile technology leader and dynamicist

    "Release It" has now been translated into Korean. I just received three copies of a work that's hauntingly familiar, but totally... more»

  • Andrew Glover

    Co-author of "Continuous Integration"

    more»

  • Jason Rudolph

    Author of Getting Started with Grails

    Want to help convince your peers to take Grails for a spin? Are you looking to give a presentation to your dev team, your company, or perhaps... more»

  • Craig Walls

    Author of Spring in Action

    Alas, I must report that I will not be speaking at nor attending The Spring Experience 2008. That' more»

  • Graeme Rocher

    Project Lead of the Grails Project & CTO of G2One

    Our busy community of plugin developers have been at it again and now there is a brand new more»

  • Pramod Sadalage

    Co-author of "Refactoring Databases:Evolutionary Database Development"

    Couple of weeks back I was given a choice to upgrade my work Laptop to a Mac Book Pro or a Windows Laptop. I choose Mac ( I know everyone is... more»

  • Mike Levin

    Software Developer specializing in Web2.0 websites

    Come visit Codet own at www.c odetown.us. It's a social network that cen more»

  • Nathaniel Schutta

    Author, speaker, software engineer focused on user interface design.

    My friend Brian Sletten sent me a link to this v more»

  • Stuart Halloway

    CEO of Relevance

    This is Part Three of a series of articles on Java.next. In Part Three, I will explore how the Java.next languages (JRuby, Groovy, Clo more»

  • Neal Ford

    Application Architect at ThoughtWorks, Inc.

    I was talking to my friend Brian Goetz recently, and he reminded me of more»

  • John Heintz

    Principal Consultant with New Aspects of Software

    In a recent discussion interview questions came up, here's my favorite one.To set some context this question is designed to gauge the abst more»

  • Scott Leberknight

    Chief Architect at Near Infinity

    In almost every application I've done, the database tables have some kind of audit trail fields. Sometimes this is a separate "audit log"... more»

  • Alex Miller

    Sr. Engineer with Terracotta Inc.

    It’s time again for my monthly music club mix. This month is a bit of indulgent power pop and just a smattering of stuff I’ve... more»

  • Matt Raible

    Creator of AppFuse and author of Spring Live

    The developers of Seam have come up with a list of major issues with JSF. I'm assuming many more»

  • Jared Richardson

    Agile coach and co-author of Ship It

    The first scheduled class for the NFJS One venture is now official! And we don't even have the website live yet. :) This class will be a go... more»

  • Pratik Patel

    Enterprise Architect

    A fine fellow by the name of Srini came to my talk on JPA at the NoFl more»

  • Richard Haefel

    VP of Developer Relations, Curl Inc.

    more»

  • Kenneth Kousen

    President of Kousen IT, Inc.

    A couple of weeks ago I participated in a BriefingsDirect podcast about using more»

  • Ted Neward

    Enterprise, Virtual Machine and Language Wonk

    As Joel points out, we've made a draft of the S more»

  • Erik Doernenburg

    Principal Consultant @ Thoughtworks

    The Spring framework has become ubiquitous in the Java world, and there are a large number of to more»

  • Ryan Shriver

    Business and Technology Consulting

    more»

  • Mark Johnson

    Director of Consulting at CGI

    At the Columbus NFJS show held on July 25-27th during one of the BOF sessions Dave Bock, Scott Davis and I discussed unit tests vs functional... more»

  • Joseph Nusairat

    Author of Beginning JBoss Seam & Co-Author of Beginning Groovy & Grails

    Well i am assuming Apress has the most random site in the world at times.But today only they have our recent book, Beginning Groovy & Grai more»

  • Jeff Brown

    G2One Director Of North American Operations - Groovy and Grails Developer

    We are really excited to have a 3 day Groovy/Grails training event coming up in Chicago later this month. The training dates are August... more»

  • Brian Pontarelli

    Brian Pontarelli - founder of Inversoft

    I went to the 37 Signals event last night sponsored by CPB. The speake more»

  • Keith Donald

    Lead of Spring Web and Creator of Spring Web Flow

    I am pleased to announce that Developing Rich Web Applications with Spring, a three-day bootcamp lead by SpringSource engineers on web... more»

  • Vladimir Vivien

    Software Engineer / Consultant

    Judging from the list of features that will be included in NetBeans 6.5, more»

  • David Bock

    Principal Consultant, CodeSherpas Inc.

    I just spent this weekend speaking at the Ag ile IT Exchange conference i more»

  • Kirk Knoernschild

    Software Developer & Mentor

    I’ve published a summary of the OSGi survey results on the APS blog more»

  • Brian Goetz

    Author of Java Concurrency in Practice

    This surprised the heck out of me.  We recently finished a new TV room down in the basement.  We have a 50″ plasma TV, mounted on the... more»

  • Jason Harwig

    Senior Software Engineer at Near Infinity

    I was reading a blog entry at more»

  • Pete Behrens

    Organizational Agility Coach

    Marti nig & Associates Methods & Tools group recentl more»

  • Brian Sam-Bodden

    Java author, Ruby geek and Open Source Advocate

    In this installment we are going to build the Dashboard page of the Tempo application. T more»

  • Mark Fisher

    Spring Integration Lead

    In my recent post, I had mentio more»

  • Ron Bodkin

    Chief Software Architect, Quantcast

    I'm looking forward to speaking at The Rich Web Experience conference in San Jose next month. The event runs from September 7th through 9th.... more»

  • Mark Goodwin

    Web Application Security Specialist

    We've already looked at one of the two big problems posed by anti DNS pinning on Java applets; because there's rebinding on the applet and... more»

  • Scott Davis

    Author of "Groovy Recipes" & TDD Expert

    Every time I see a live show at the Denver Botanic more»

  • Romain Guy

    Java User Interface expert.

    more»

  • Ramnivas Laddad

    Author of AspectJ in Action, Principal at SpringSource

    InfoQ.com has published my AOP myths and realities talk recorded at a No Fluff Just Stuff conference. InfoQ.com founded by Floyd Marine more»

  • David Geary

    Author of Graphic Java and co-author of Core JSF

    The 2006 NFJS tour kicked off t more»

  • Howard Lewis Ship

    Creator of Tapestry and HiveMind

    <p> Just spent many minutes on a wild goose chase and the underlying cause was that I had a &lt;div&gt; and a... more»

  • Kito Mann

    Editor-in-chief of JSF Central and the author of JSF in Action

    This article explains how to implement the sorting feature of the dataTable component of the JavaServer Faces Widget Library, which is... more»

  • Jason Hunter

    Author of Java Servlet Programming

    I just posted the JDOM 1.1 release for download. This release includes about 20 improvements and bug fixes. more»

Groovy Fun With ObjectRange

Posted by: Scott Leberknight on 06/25/2008

I ran into a situation the other day with Groovy that baffled me at first. Let's create a range from 0.0 to 10.0 and then use it to check if a certain number is contained within that range, like this:

groovy:000> r = 0.0..10.0
===> 0.0..10.0
groovy:000> r.contains(5.6)
===> false

WTF? The number 5.6 is not contained in the range 0.0 to 10.0? I beg to differ. So what's actually going on here? Using the shell we can do some more digging, interrogating the range object to see what its bounds are, what values it contains if you iterate it, and so on:

groovy:000> r = 0.0..10.0
===> 0.0..10.0
groovy:000> r.class
===> class groovy.lang.ObjectRange
groovy:000> r.from.class
===> class java.math.BigDecimal
groovy:000> r.to.class
===> class java.math.BigDecimal
groovy:000> r.each { print " $it " }  
 0.0  1.0  2.0  3.0  4.0  5.0  6.0  7.0  8.0  9.0  10.0 ===> 0.0..10.0
groovy:000> r.contains 5 
===> true
groovy:000> r.contains 5.0
===> true
groovy:000> r.contains 5.6
===> false

So what did we learn? First, the range is an ObjectRange whose bounds are BigDecimals. Second, that iterating by default iterates in increments of one. And third that the contains method does not quite do what I would expect by default. Looking at Groovy's ObjectRange class makes it clear exactly what's going on, so let's look:

public boolean contains(Object value) {
  Iterator it = iterator();
  if (value == null) return false;
  while (it.hasNext()) {
    try {
      if (DefaultTypeTransformation.compareEqual(value, it.next())) return true;
    } catch (ClassCastException e) {
      return false;
    }
  }
  return false;
}

The Groovy ObjectRange's contains method defines containment as whether a value is contained within the values generated by its iterator. By now many of my many millions of readers are about to post a comment telling me the problem, so I'll preempt that temptation by adding a few more lines of interaction with the Groovy shell:

groovy:000> r.containsWithinBounds 5.0
===> true
groovy:000> r.containsWithinBounds 5.6
===> true

Aha! So contains doesn't do what you might think it should, but containsWithinBounds does. Its JavaDoc says "Checks whether a value is between the from and to values of a Range." Conspicuously there is no JavaDoc on the contains method to tell me that what it actually does is check whether a value is contained within the discrete values generated by the iterator. Let's try more more thing:

groovy:000> r.containsWithinBounds 5
ERROR java.lang.ClassCastException: java.lang.Integer
        at groovysh_evaluate.run (groovysh_evaluate:2)
        ...

Oops! Not only do you need to call containsWithinBounds rather than contains, you also need to call it with the correct type, as there is no coercion going on since it uses Comparable.compareTo() under the covers.

Notwithstanding all the recent activity regarding all the Ruby security flaws recently discovered, how does Ruby handle inclusion of a number within a range? Here's some irb output:

>> r = 0.0..10.0
=> 0.0..10.0
>> r.class
=> Range
>> r.begin.class
=> Float
>> r.end.class
=> Float
>> r.each { |item| print " #{item} " }
TypeError: can't iterate from Float
        from (irb):53:in `each'
        from (irb):53
>> r.include? 5
=> true
>> r.include? 5.0
=> true
>> r.include? 5.6
=> true

To me this is more semantically and intuitively correct behavior. First, while I can create a range with float bounds, I cannot iterate that range - for non-integral numbers, how exactly can you define the next item after 0.0 for example? 0.1, 0.01, 0.001, and so on till infinity. Second, the include? method behaves as I would expect no matter what type of argument I pass. I am able to iterate ranges of integral numbers, however, which could arguably also be confusing since the behavior of the method depends on the type. Then again, that's pretty much what polymorphic method behavior is about I suppose.

>> r = 0..10
=> 0..10
>> r.each { |item| print " #{item} " }
 0  1  2  3  4  5  6  7  8  9  10 => 0..10

In the case of integers Ruby uses an increment of one by default. You could use the step method to get a different increment, e.g.:

>> r.step(2) { |item| print " #{item} " }
 0  2  4  6  8  10 => 0..10

So what's the point of all this? That Ruby is better than Groovy? Nope. I really like both languages. I think there are a couple of points that were reinforced to me:

First, RTFM (or source code --> RTFC). Even though Groovy's contains method doesn't behave how I think it should, there is the method I was looking for with containsWithinBounds.

Second, having a shell to play around with short snippets of code is really, really useful, without needing to create a class with a main method just to play around with code.

Third, documentation and semantics matter. If something doesn't feel intuitively correct based on how similar things act, it is more likely to cause confusion and errors. In this case, since my unit test immediately caught the error, I was able to figure the problem out in a few minutes.

Finally, following on from the last point, unit tests continue to remain valuable. Of course anyone who knows me would roll their eyes over my anal-ness (which Mac's dictionary is telling me is not really a word but I don't care at the moment) expecting me to get something about unit testing in somehow.


be the first to rate this blog


About Scott Leberknight

Scott is Chief Architect at Near Infinity Corporation, an enterprise software development, training, and consulting services company based in Reston, Virginia. He has been developing enterprise and web applications for over 13 years professionally, and has developed applications using Java, Ruby/Rails, Groovy/Grails and Python. His main areas of interest include object-oriented design, system architecture, testing, and frameworks of all types including Spring, Hibernate, Ruby on Rails, Grails, and Django. In addition, Scott enjoys learning new languages to make himself a better and more well-rounded developer a la The Pragmatic Programmers' advice to "learn one language per year."

Scott holds a B.S. in Engineering Science and Mechanics from Virginia Tech, and an M. Eng. in Systems Engineering from the University of Maryland. Scott speaks at the No Fluff Just Stuff Symposiums and various other conferences. In his (sparse) spare time, Scott enjoys spending time with his wife, two daughters, and two cats. He also tries to find time to play soccer, go snowboarding, and mountain bike whenever he can.

More About Scott »