Ruby style blocks in java

Is there a nice way to implement Ruby-style blocks in Java? I have to code in Java and I really miss this feature. This is the best thing I came up with, but it is soooo verbose (untested, just from my head):

interface Block {
   public Object yield(Object o);
}

class Array {
   public void do(Block b) {
     // do something here
     while (it.hasNext()) {
       Object o = it.next();
       block.yield(o);
    }
}

class Someth
   public void doSomething() {
     Array a = new Array();
     // do something before
     a.do(new Block() {
       public void yield(Object o) {
         // here is the yield code
       }
     }
     // do something afterwards
   }
}

···

--
martinus

That's probably as close as it can get. If you want methods from Enumerable you probably end up writing static methods that receive an Iterator or a Collection and a Block. Not very elegant though.

You can also use Groovy - which is quite Ruby like and Java under the hoods. Unfortunately it's significantly slower that pure Java - and maybe also as Ruby.

Kind regards

    robert

···

Martin Ankerl <martin.ankerl@gmail.com> wrote:

Is there a nice way to implement Ruby-style blocks in Java? I have to
code in Java and I really miss this feature. This is the best thing I
came up with, but it is soooo verbose (untested, just from my head):

interface Block {
  public Object yield(Object o);
}

class Array {
  public void do(Block b) {
    // do something here
    while (it.hasNext()) {
      Object o = it.next();
      block.yield(o);
   }
}

class Someth
  public void doSomething() {
    Array a = new Array();
    // do something before
    a.do(new Block() {
      public void yield(Object o) {
        // here is the yield code
      }
    }
    // do something afterwards
  }
}

The best way to approximate this in Java is with anonymous inner
classes. A bit ugly/verbose, though.

Have a look at Martin Fowler's article on closures, as well as
BlocksInJava from Ward's wiki:


http://c2.com/cgi/wiki?BlocksInJava

Cheers,
Ken

Those code blocks are really nice :slight_smile:

But anyway, they are usefull not because they are elegant, but because
they capture the context in which they are created. In Java only
variables declared <final> will be captured by an annonymous class, so
if you want some variable in the current context, you can do something
like this:

final int[] tmpArray = new int[0];
Object someObject = new SomeObject();
tmpArray[0] = someObject;

a.do(new Block() {
  public void yield(Object o) {
    // someObject is not captured in
    // here, but tmpArray is,
    // so you can use someObject by
    // accessing tmpArray[0]
  }
});

Groovy looks good, and it is (much) faster that Ruby (from my own
personal experience) but it is still too young, and although it's a
JSR, it's programmers only work on their free time on it, so we will
have to wait, and to be honest, right now the future does not look very
bright for Groovy (it's only my oppinion, and I hope I'm wrong).

get too (using final 1-element arrays to write back to the block's calling context). I also ran across Groovy. There's also jruby but I haven't really tried either.

I also found it better to stick the interface inside the class that uses it and name it after the method that uses it. Exception handling can also be a PITA with this kind of thing.

Despite being verbose, the sort of thing you have above actually cut down the number of lines of Java code I had to write by factoring out a whole lot of JDBC try/finally code. If you hunt around for the recommended way of using JDBC you'll see there are about 6 lines inside a finally clause that involve cleaning up the record set and statement objects.

The main problem I found though is that all those Java standard libraries simply don't use blocks, so they're only good for things you implement yourself.

···

On Wed, 07 Sep 2005 02:36:28 +1000, Martin Ankerl <martin.ankerl@gmail.com> wrote:

Is there a nice way to implement Ruby-style blocks in Java? I have to code in Java and I really miss this feature. This is the best thing I came up with, but it is soooo verbose (untested, just from my head):

interface Block {
   public Object yield(Object o);
}

class Array {
   public void do(Block b) {
     // do something here
     while (it.hasNext()) {
       Object o = it.next();
       block.yield(o);
    }
}

class Someth
   public void doSomething() {
     Array a = new Array();
     // do something before
     a.do(new Block() {
       public void yield(Object o) {
         // here is the yield code
       }
     }
     // do something afterwards
   }
}

From my experience attempting exactly the same, that's as close as I could
--
Greg McIntyre

Hi everybody

Those code blocks are really nice :slight_smile:

Very nice indeed... :sunglasses:

But anyway, they are usefull not because they are elegant, but because
they capture the context in which they are created. In Java only
variables declared <final> will be captured by an annonymous class, so
if you want some variable in the current context, you can do something
like this:

I pay the bills working as architect (but with plenty coding and field
work) in a java shop.

Thinking in blocks and closures really helps to avoid repeating
collections traversals and analisys ad-nauseam. Closures as anonymous
or inner classes keep the code simpler, making clearer what are you
doing, not how. It makes also easier the reuse of common blocks as
full classes.

We usually use jakarta commons [1]. It provides the basic interfaces
for typical functors (closure, predicate and transformer) and
collection traversal and processing functions.

Not the ideal package, but enough for our needs (and zero time
provided to implement or evaluate alternatives 8'( ).

The concept is very easy to sell to upper echelons and to developers
(it pays fast).

The only real price is more verbosity compared with Ruby.

Final variables are not a problem, as we try to make final everything
that musn't be non-final. :sunglasses:

Groovy looks good, and it is (much) faster that Ruby (from my own
personal experience) but it is still too young, and although it's a
JSR, it's programmers only work on their free time on it, so we will
have to wait, and to be honest, right now the future does not look very
bright for Groovy (it's only my oppinion, and I hope I'm wrong).

I would like to have the time for a beanshell vs. groovy comparation...

[1] Collections – Home

Just my two cents.

···

On 06/09/05, bonefry <bellarchitects@gmail.com> wrote:

--
Saludos mercenarios...

A los vampiros no les gusta el sol
y yo, como es normal, no soy una excepción.
Llegó el verano, llegó el verano...

In article <op.swpkw1c7hcrp7p@mcintyre>, Greg McIntyre wrote:
[...]

The main problem I found though is that all those Java standard libraries
simply don't use blocks, so they're only good for things you implement
yourself.

[...]

If you use the Apache Commons libraries then blocks abound. All sorts of
useful stuff that should be part of standard Java.