My hobbyist coding updates and releases as the mysterious "Mr. Tines"

Wednesday, 23 January 2008

Steps forwards, steps back.

It would be nice to have the getX()/setX() map to a property, syntactically, in general use Jython as well, along the lines of the previous essay. Alas, that simple "X indirects to getX()" method doesn't seem to work as is. I wonder if I'm relying on things that are a more modern version than Jython yet supports. I need to investigate more.

Meanwhile, on another front, even using the invaluable vjsresgen tool, I have to have platform specific interludes to handle resources -- especially to convert from .png format to something that the back-version Java support understands.

Colour me slowpoke ... Swing on J#

I'd not caught this before:

The Microsoft Supplemental UI Library provides much of the functionality described in the Java 2 JFC Swing specification. It also adds support for much of the functionality found in the JDK 1.2 java.util package.

Version 2.0 of the Supplemental UI Library is included as part of the Visual J# Version 2.0 Redistributable Package. No additional download is required.

To access the functionality in the Supplemental UI Library, simply add a reference to VJSSupUILib.dll in your project.

Betterer and betterer…

Of course this throws a little bit of a spanner in the works of the Jythonizer effort -- I might have subclassed javax.swing.JFrame, but not the component that I get from calling its shiny new contentPane attribute delegating to getContentPane(). Oh, well. At least I might be able to get some cute tricks along the lines of some of the ideas in Swing Hacks instead.

Tuesday, 22 January 2008

Making IronPython and J# more Jythonic -- Part 1

For the Nine Unknown Men who might also be attempting this sort of thing.

Persistance pays…

import dtai.gwt.GadgetFrame

def my__getattr__(self, name):
  if name.startswith("__"):
    raise AttributeError(name)
  getter = "get"+name.capitalize()
  if getter in dir(self):
    tmp = getattr(self, getter)
    return tmp()
  iser = "is"+name.capitalize()
  if iser in dir(self):
    tmp = getattr(self, iser)
    return tmp()
  raise AttributeError(name)
        
class Local:    
  def getFred(self):
    return "Fred!"
  
Local.__getattr__ = my__getattr__
   
test = Local()   
print test.fred

class WrappedGadgetFrame(dtai.gwt.GadgetFrame):
  pass

WrappedGadgetFrame.__getattr__ = my__getattr__
dtai.gwt.GadgetFrame = WrappedGadgetFrame

window =  dtai.gwt.GadgetFrame()
print window.visible

when executed, yields

C:...>PyInterop.exe
Fred!
False

which is the get() side of attributes done at the cost of a pass of subclassing. The equivalent set() shouldn't be too difficult, but automating the subclassing will be the next challenge.

Then adding the listener-based attributes; and finally, hiding it from Jython…

Monday, 21 January 2008

How Jythonic can it get?

Following up from my previous post, I've been thinking that it would be nice if I could make the code there a bit more Jythonic -- wrapping Java-style bean properties and event handlers transparently in the IronPython/J# world, where the inherent properties will be the Capitalized .Net ones, and we only have the .Net delegate-style handlers.

I will need to experiment to see exactly how open the IronPython proxy classes are to extension, first.

So many projects, so little free time. And I really need to do more with F# and PowerShell, not to mention wanting to try writing a generic protocol-terminating proxy framework in Erlang, probably with SOCKS5 as an exemplar protocol.

LATER

As I suspected, setting Local.__getattr__ = my__getattr__ for a function of suitable signature works where Local is a pure IronPython class; but for an imported .Net class I get


TypeError: can't set '__getattr__' in dictproxy

even with the indirect approach of something like dtai.gwt.GadgetFrame.__dict__["__getattr__"] = my__getattr__.

So Java/J# idioms at the interface it may have to be.

Wednesday, 16 January 2008

Pushing at an open door…

Compared with the travails required to shim Ruby.Net and JRuby onto a shared Java/J# code platform, doing the same for Jython (in NetBeans 5.0)/IronPython (using the DevStudio extension build for IronPython 1.1) was trivial. In fact most of the work was re-gearing my mind to Python after thinking in Ruby for some weeks.

Apart from the fact that that the IronPython build ignores any directory structure and smooshes all classes into the one assembly and considers that the package, which will impact on the broader code shape for any project, there is no shimming. Just build your assembly with references to the appropriate external files and you don't even need all the clr.AddReference to do it by hand

Doing the same as the J# and Ruby.Net — string and baling wire example, in a project that references the appropriate assemblies just requires the same Python code as a Jython build with the equivalent .jar files on the classpath

## pyinterop.py
import dtai.gwt.GadgetFrame
import java11.awt.event.WindowListener
import java.lang.System

window = dtai.gwt.GadgetFrame()
window.setSize (800, 600)
window.setTitle("Proof of Concept")

class Handler(java11.awt.event.WindowListener):
  def __init__(self, window):
    self.window = window

  def windowClosing(self, e):
    self.window.hide()

  def windowClosed(self, e):
    java.lang.System.exit(0)

  def windowActivated(self, e):
    pass

  def windowDeactivated(self, e):
    pass

  def windowDeiconified(self, e):
    pass

  def windowIconified(self, e):
    pass

  def windowOpened(self, e):
    pass

adapter = Handler(window)
window.addWindowListener(adapter)
window.show()

It still works in either case, if I simply use the WindowAdapter class and just override the methods I need. W00t! Indeed, so far it almost seem too easy!

Now I just have to keep working around the weird problems I ran into last time around this loop. Keeping Java beneath everything this time around should help.

Tuesday, 15 January 2008

Ruby.Net and Ruby.Net — foiled again

A reboot (of the machine, and myself) later, I realised that the obscure "Wrong argument type String (Class expected)" was the result of a sleep-addled 'C'-drenched brain putting include 'Wizard' where require 'Wizard' was expected.

Not so good with the memory issue. After a couple of hours debugging and finally getting the code to interoperate, DevStudio was peaking at over 370Mb of memory, and still thrashing (on a 512Mb machine), while building a project with < 1000 lines of Ruby. NetBeans, by comparison has about 150Mb (if I have a lot of files open)in the IDE and and under 40Mb in the spawned application.

I've put the Interop example code -- showing how to call from shared code JRuby/Ruby.Net to shared-code Java/J# libraries. main.rb calls Wizard.rb which calls through the interop layer defined by .jsl files for Ruby.Net->J#, and Interfaces.rb plus the .java files for JRuby->Java -- on one of my sites, for those who are interested in taking this further.

Until I upgrade my hardware to something that permits more than a toy Ruby.Net layer, though, I don't think I'll be taking the ideal of a shared code/multi-VM project further with Ruby. Which sucks, because that has the best IDE support (I don't even know if the Jython add-in for NetBeans still works at 6.0).

Still a little experimentation is needed with that, and with Scala, to get to an equivalent proof of concept stage.

Monday, 14 January 2008

Ruby.Net and Ruby.Net — first steps

Not a typo, alas.

I was testing calling from a Ruby.Net .exe file into a Ruby.Net .dll, to see if partitioning like that would work; though not in such a simple setup as that : I was trying to test a Ruby implementation of a wizard dialog using the GWT... So I create a Testbed.Net.exe that refers to gwt_ruby.dll (which is built from a single source file Wizard.rb).

That fails with a Key Not Found Exception, and looking at the Ruby.Net code, and ildasm-ing the assembly, I discern that it was looking for a gwt_ruby.rb file having been built into the project. So I give it one to satisfy it

require 'Wizard'
class Gwt_Ruby
end

Later...

The Ruby.Net build is being a voracious memory hog on my 3 year old machine with only 512Mb RAM -- even for only a few hundred lines of Ruby code each build and test is taking more than half an hour of thrashing madly at almost 0% CPU. And I thought that NetBeans was memory hungry -- that I can work on in realtime, with the same code in JRuby. I'm not sure that testing this is going to be practical, even without having to work around packaging quirks.

It's almost enough to drive me to Scala!