#!/usr/bin/perl -w ##################### # # Example of using the Pickle, PickleJar, Can, CanComparer objects from # http://bob.marlboro.edu/~msie/2001/ipl/java/code/2html/oct28/Pantry.java # within a perl program which has embedded java. # # I had to make some modifications to the java to keep Inline::Java happy: # * added 'public' to the all the methods and constructors I wanted visible in perl. # * added explicit PickleJar and CanComparer constructors. # # Compare the perl code below with the main() routine in Pantry.java. # I haven't tried to copy all the code; just a few representative chunks. # # In particular, the perl code doesn't know about the classes and methods # in java.util.*, so I can't use the Java list and hash structures without # more work - so I just used Perl's lists and hashes instead. # # I also saw at least one bug, where a function declared "int" in Java (compare) # was returning something that perl didn't think was a numeric value until after # forced conversion by 0+ (oops). # # - Jim Mahoney # ###################### use strict; use Inline 'Java'; print " -- java objects called from perl -- \n"; print " We're using Can, PickleJar, Pickle, and Comparer which are java objects. \n\n"; # ============================================================ my $jar = new PickleJar; $jar->add( new Pickle("dill") ); $jar->add( new Pickle("spicy") ); for (my $i=0; $i < $jar->size; $i++) { my $p = $jar->get($i); print "The jar has a " . $p->getFlavor . " pickle.\n"; } # as Java : # PickleJar jar = new PickleJar(); # jar.add(new Pickle("dill")); # jar.add(new Pickle("spicy")); # for(int i=0; i < jar.size(); i++) { # Pickle p = jar.get(i); # System.out.println("The jar has a " + p.getFlavor() + " pickle."); # } # ============================================================ my @cans = (); push @cans, new Can(16); push @cans, new Can(6); push @cans, new Can(10); push @cans, new Can(16); push @cans, new Can(12); push @cans, new Can(10); foreach my $can (@cans) { print "I have a " . $can->getSize . " ounce can.\n"; } print "Organize the cans!\n"; my $cc = new CanComparer; my @sorted_cans = sort { 0 + $cc->compare($a,$b) } @cans; foreach my $can (@sorted_cans) { print "I have a " . $can->getSize . " ounce can.\n"; } # This last part seems to have a bug: the "compare" method has # an (int) defined as the return value, but without the "0+" # in the sort {} I was seeing the error "compare didn't return a numeric value" # as Java : # List cans = new ArrayList(); # cans.add(new Can(16)); # cans.add(new Can(6)); # cans.add(new Can(10)); # cans.add(new Can(16)); # cans.add(new Can(12)); # cans.add(new Can(10)); # # iter = cans.iterator(); # while(iter.hasNext()) { # Can s = (Can) iter.next(); # System.out.println("I have a " + s.getSize() + " ounce can."); # } # # System.out.println("Organize the cans!"); # Collections.sort(cans, new CanComparer()); # # iter = cans.iterator(); # while(iter.hasNext()) { # Can s = (Can) iter.next(); # System.out.println("I have a " + s.getSize() + " ounce can."); # } # # ================================================== __DATA__ __Java__ import java.util.*; class Pickle { private String flavor; public Pickle(String s) { flavor = s; } public String getFlavor() { return flavor; } } class PickleJar { private List internalList = new ArrayList(); public PickleJar() {} public void add(Pickle p) { internalList.add(p); } public Pickle get(int index) { return (Pickle) internalList.get(index); } public int size() { return internalList.size(); } } /** * Note: this class has a natural ordering that is inconsistent with equals. * Why? because equals says that two equal Objects are conceptually the same * object. Here, the natural ordering is based on size, but two same-sized * Cans are not necessarily the same Can. */ class Can { private int size; public Can(int s) { size = s; } public int getSize() { return size; } } class CanComparer implements Comparator { public CanComparer() {} public int compare(Object t, Object o) { Can that = (Can) t; Can other = (Can) o; if (that.getSize() < other.getSize()) { return -1; } else if (that.getSize() > other.getSize()) { return 1; } else { return 0; } } public boolean equals(Object t, Object o) { Can that = (Can) t; Can other = (Can) o; return that.getSize() == other.getSize(); } }