Stop by #openmrs on
irc.freenode.org
for more information -- ask for docpaul or burke.
irc.freenode.org
for more information -- ask for docpaul or burke.
Hi robby, thanks for testing, i will incoporate test cases based on your examples
in the test suite.
Currently properties is in a weird state between version 3 and unpublished version 4
of the spec. I've done major design changes. I have rewrittent the runtime support,
drop the writeonly properties from the spec, etc.
Currently the runtime library (java.lang.Property and helper classes)
only support read-write property, i think it explain these bugs.
class Book {
String title;
}
def gina = new Book();
gina.title = "Groovy In Action";
println gina.title;
svn checkout https://kijaro.dev.java.net/svn/kijaro/branches/properties kijaro --username username --password yourpassword
replace username and yourpassword with the username and password you registered with. cd kijaro/langtools/make
ant -Dboot.java.home=$JAVA_HOME
/**
* Created: Mar 23, 2008 9:13:54 PM
*
* @author Robert O'Connor
*/
public class BeanExample {
private String userName;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public static void main(String[] args) {
BeanExample example = new BeanExample();
example.setUserName("rob");
System.out.println(example.getUserName());
}
}
/**
* Created: Mar 22, 2008 5:37:41 PM
*
* @author Robert O'Connor
*/
public class ReadOnlyPropertiesExample {
private String userName;
public property String name get { return userName; };
public ReadOnlyPropertiesExample() {
this.userName = "rob";
}
public static void main(String[] args) {
System.out.println(new ReadOnlyPropertiesExample().userName);
}
}
/**
* Created: Mar 23, 2008 8:11:41 PM
*
* @author Robert O'Connor
*/
public class ReadWritePropertiesExample {
private String userName;
public property String name
get { return userName; }
set(String name) { userName = name; };
public static void main(String[] args) {
ReadWritePropertiesExample example = new ReadWritePropertiesExample();
example.userName = "rob"; // set the name
System.out.println(example.userName); // output it.
example.userName = "robby"; // set it to something different
System.out.println(example.userName); // output the new value
}
}
example.userName
is NOT using direct field access. The final example is a write-only example; note that it is a compile-time error to attempt to retrieve the value; however the compiler currently let's you do it; which in my opinion is bad. I coded against the spec, so to circumvent that, I defined a getter (I know properties are supposed to eliminate those, but I needed a way to test that the value was set properly.)
/**
* Created: Mar 23, 2008 8:45:02 PM
*
* @author Robert O'Connor
*/
public class WriteOnlyPropertiesExample {
private String userName;
public property String name set;
/**
* this is used purely to check that the property set the field's value properly.
* @return the username
*/
public String getUserName() {
return userName;
}
public static void main(String[] args) {
WriteOnlyPropertiesExample example = new WriteOnlyPropertiesExample();
example.userName = "rob"; // we can only *SET* it since it's write-only
System.out.println(example.getUserName());
example.userName = "robby";
System.out.println(example.getUserName());
}
}
curl -Is slashdot.org | egrep '^X-(F|B)' | cut -d \- -f 2
curl -Is slashdot.org
returns:
HTTP/1.1 200 OK
Date: Sun, 23 Mar 2008 01:04:28 GMT
Server: Apache/1.3.37 (Unix) mod_perl/1.29
SLASH_LOG_DATA: shtml
X-Powered-By: Slash 2.005000198
X-Leela: I'm a millionaire! Suddenly I have an opinion about the capital gains tax.
Cache-Control: private
Pragma: private
Vary: User-Agent,Accept-Encoding
Connection: close
Content-Type: text/html; charset=iso-8859-1
java FCMGui
and you're set. If you need help feel free to e-mail me.
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JButton;
import javax.swing.SwingUtilities;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
/**
* Created: Mar 19, 2008 5:48:43 PM
*
* @author Robert O'Connor
*/
public class UsualJavaGui {
JFrame frame = new JFrame("Usual Java Example");
JButton button = new JButton("Press me");
public UsualJavaGui() {
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("Button pressed");
}
});
frame.add(button);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new UsualJavaGui();
}
});
}
}
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.SwingUtilities;
import java.awt.event.ActionEvent;
/**
* Created: Mar 21, 2008 6:55:52 PM
*
* @author Robert O'Connor
*/
public class FCMGui {
JFrame frame = new JFrame("FCM Example");
JButton button = new JButton("Press Me");
public FCMGui() {
button.addActionListener(#(ActionEvent evt) {
System.out.println("Button pressed");
});
frame.add(button);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(# { new FCMGui();
});
}
}
Josh Bloch
Bob Lee
Doug Lea
import java.io.BufferedReader;
import java.io.IOException;
import java.io.FileReader;
import java.io.File;
/**
* Created: Mar 21, 2008 12:46:07 AM
*
* @author Robert O'Connor
*/
public class JavaExample {
BufferedReader r = null;
public JavaExample() {
try {
r = new BufferedReader(new FileReader(new File("names.txt")));
String line;
while ((line = r.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(r!=null)r.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
new JavaExample();
}
}
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
/**
* Created: Mar 21, 2008 12:25:43 AM
*
* @author Robert O'Connor
*/
public class ARMExample {
BufferedReader r = null;
public ARMExample() throws IOException {
do (r = new BufferedReader(new FileReader(new File("names.txt")))) {
String line;
while ((line = r.readLine()) != null) {
System.out.println(line);
}
}
}
public static void main(String[] args) throws IOException {
new ARMExample();
}
}
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JButton;
import javax.swing.SwingUtilities;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
/**
* Created: Mar 19, 2008 5:48:43 PM
*
* @author Robert O'Connor
*/
public class UsualJavaGui {
JFrame frame = new JFrame("Usual Java Example");
JButton button = new JButton("Press me");
public UsualJavaGui() {
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("Button pressed");
}
});
frame.add(button);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new UsualJavaGui();
}
});
}
}
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.SwingUtilities;
import java.awt.event.ActionEvent;
/**
* Created: Mar 19, 2008 7:35:15 PM
*
* @author Robert O'Connor
*/
public class BGGAGui {
JFrame frame = new JFrame("BGGA Frame");
JButton button = new JButton("Press me");
public BGGAGui() {
button.addActionListener({ActionEvent evt => System.out.println("Button pressed");});
frame.add(button);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
// thanks to neil gafter!
SwingUtilities.invokeLater({ => new BGGAGui(); });
}
}
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JButton;
import javax.swing.SwingUtilities;
/**
* Created: Mar 19, 2008 5:48:43 PM
*
* @author Robert O'Connor
*/
public class UsualJavaGui {
JFrame frame = new JFrame("Usual Java Example");
JButton button = new JButton("Press me");
public UsualJavaGui() {
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("Button pressed");
}
});
frame.add(button);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new UsualJavaGui();
}
});
}
}
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.SwingUtilities;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
* Created: Mar 19, 2008 5:57:45 PM
*
* @author Robert O'Connor
*/
public class CICEGui {
JFrame frame = new JFrame("CICE Gui");
JButton button = new JButton("Press me");
public CICEGui() {
button.addActionListener(ActionListener(ActionEvent e){
System.out.println("Button pressed");
});
frame.add(button);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(Runnable() {
new CICEGui();
});
}
}
public void run() { ... }and
public void actionPerformed(ActionEvent e) { ... }How can this be and how do I get access to the ActionEvent reference? Well notice the following:
button.addActionListener(ActionListener(ActionEvent e) {I passed in the ActionEvent parameter to the Concise Instance Creation Expression! Using CICE, I was able to eliminate the methods. Also note, that I was able to eliminate using the word new is not needed with CICE. I was also able to state my intent cleanly, and in a lot less verbose way. How many lines were eliminated between the Java version and the CICE version?
System.out.println("Button pressed");
});
(rob-laptop)rob@~/playground/src/main/java$ wc -l misc/UsualJavaGui.java misc/CICEGui.java
43 misc/UsualJavaGui.java
34 misc/CICEGui.java
77 total
(rob-laptop)rob@~/playground/src/main/java$
public class StringTester { public static void main(String[] args) { System.out.println(new String("foo") == "foo"); } }
"foo" == "foo"it will be true. Reason: Java interns String literals. This is precisely why using == on String isn't advised. However groovy converts all == instances to .equals() so we basically get the same result as if we interned the String in java. This makes sense, since in groovy there are no primitive data types; it uses the wrapper classes from java. Integer, Double, Byte, etc. More information about the wrapper classes can be found here.
class StringTester { static void main(args) { println new String("foo") == new String("foo") println new String("foo") == "foo" println "foo" == "foo" } }
public class StringTester { public static void main(String[] args) { System.out.println(new String("foo").intern() == "foo"); System.out.println(new String("foo").intern() == new String("foo").intern()); } }
public class FibonacciSequenceWithClosures {
public static void main(String[] args) {
int fib = {int n => fib(n)}.invoke(Integer.parseInt(args[0]));
System.out.println(fib);
}
/**
* Helper method to recursively calculate the
* n-th number in the fibonacci seqeunce.
* @param n
* @return the n-th number
* @throws IllegalArgumentException if you pass in a negative number
*/
public static int fib(int n) {
if(n < 0) {
throw new IllegalArgumentException("Must be Postive!");
} else if(n == 1 || n==2) {
return 1;
} else {
return fib(n-1) + fib(n-2);
}
}
}
int fib = {int n => fib(n)}.invoke(Integer.parseInt(args[0]));Answer: it's a closure! We'll examine that line closer.
int fib = { int n => fib(n)}.invoke(Integer.parseInt(args[0]));First, we have the parameters that we're passing into the closures, then you see
int fib = { int n => fib(n)}.invoke(Integer.parseInt(args[0]));and you're probably wondering what in god's name that operator is, it's the closure operator! Now, the final piece:
int fib = { int n => fib(n)}.invoke(Integer.parseInt(args[0]));What i'm doing here, is calling the invoke method on the closure itself, and passing in the first argument passed to the program via a command-line argument. Finally, After all this is done, I print the value returned from the closure that i stored in the variable fib and we're done. You'll get a StackOverFlowException if you pass too large a number. I could probably fix this, but this is sufficient for a simplistic example.