ruby style blocks in java

M

Martin Ankerl

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
}
}
 
R

Robert Klemme

Martin Ankerl said:
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
}
}

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
 
P

Pedro Arnal Puente

Hi everybody

Those code blocks are really nice :)

Very nice indeed... :cool:
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. :cool:
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] http://jakarta.apache.org/commons/collections/

Just my two cents.

--=20
Saludos mercenarios...

A los vampiros no les gusta el sol
y yo, como es normal, no soy una excepci=F3n.
Lleg=F3 el verano, lleg=F3 el verano...
 
G

Greg McIntyre

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
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.
 
T

Tim Sutherland

Greg McIntyre wrote: said:
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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,153
Latest member
NamKaufman
Top