Thursday, June 12, 2014

Golang tip to check if a variable is an array: get the variable value with the reflect package and then the kind of the value: see http://play.golang.org/p/eUS6I4a50e

All possible kinds: http://golang.org/pkg/reflect/#Kind

If you know something simpler, let me know...

Code:

package main

import ("fmt"
"reflect")

func isArray(a interface{}) bool {
var v reflect.Value
v = reflect.ValueOf(a)
fmt.Println("a value: %T %v", v, v)

var k reflect.Kind
k = v.Kind()
fmt.Println("a kind: %T %v", k, k)

if (k == reflect.Array) {
return true
}
return false
}

func main() {
a := [...]string{"1","2"}
//a := "fred"
if (isArray(a)) {
fmt.Println("a is an array")
} else {
fmt.Println("a is NOT an array")
}

t := reflect.TypeOf(a)
fmt.Println("a type: %T %v", t, t)

var v reflect.Value
v = reflect.ValueOf(a)
fmt.Println("a value: %T %v", v, v)

var k reflect.Kind
k = v.Kind()
fmt.Println("a kind: %T %v", k, k)

}

Run:

a value: %T %v <[2]string Value> <[2]string Value>
a kind: %T %v array array
a is an array
a type: %T %v [2]string [2]string
a value: %T %v <[2]string Value> <[2]string Value>
a kind: %T %v array array

Tuesday, May 20, 2014

BigQuery Google App Engine (GAE) Java Example


I recently wrote a technical "How-to" on "Using the BigQuery API with Java in an Eclipse Project on the Google App Engine". The application uses a service account for authentication that allows an application to run without asking the user for specific credentials. It shows how to authenticate and make some API calls to BigQuery.

Being a servlet, the code is probably portable to another servlet container like Tomcat.

The project and code are here:


Happy BigQuerying!

Saturday, December 07, 2013

Optional boolean argument for a java method:

void testOptionalArgument(boolean ... flag) {
    if (flag == null) {
        log.info("optional flag null");
    } else {
        int length = flag.length;
        log.info("optional flag: " + flag + " length: " + length);
        if (length > 0) {
            log.info("optional flag: " + flag[0]);
        }
    }
}

Calling this method in 3 different ways:

testOptionalArgument(); // optional flag: [Z@ed3c51 length: 0
testOptionalArgument(true);  // optional flag: [Z@1131359 length: 1 optional flag: true
testOptionalArgument(false); // optional flag: [Z@15b3baf length: 1 optional flag: false


Sunday, June 02, 2013

How to remove the copy/print protection in a pdf file for free

Sometimes I download a document and to my surprise, I can't copy text from it or print the document. That protection is only the copy/print text of a pdf document, not a password protection that prevents opening the document if one doesn't have this password.

Here is a quite easy way, and free, to remove this copy/print protection. I saw it mentioned several years ago on the web, but now it is drowned in the flurry of links. It's for Windows, but you can changes the paths for Linux/MacOS.

- download and install ghostscript, the open source library for pdf http://www.ghostscript.com/
- open a console and set the current directory to the one where ghostscript was installed
- run the following line after changing the path/filename for your original file (the one with the restrictions) and the path/filename for the output file

gswin32c -dSAFER -dBATCH -dNOPAUSE -sDEVICE=pdfwrite -sOutputFile="c:\noprotection.pdf" "c:\protected.pdf"
If you want to skip a few pages (like the "How to use this form", add the "-dFirstPage" option, it will output the document starting with the page specified. There is also a last page option, see the ghostscript manual.

gswin32c -dSAFER -dBATCH -dNOPAUSE -sDEVICE=pdfwrite -dFirstPage=10 -sOutputFile="c:\noprotection.pdf" "c:\protected.pdf"

Links:
http://www.ghostscript.com/download/gsdnld.html
http://www.ghostscript.com/
http://www.ghostscript.com/doc/9.07/Use.htm#PDF

Monday, April 29, 2013

on save, validation & uuid in Grails

I want to to add a "uuid" field to my domain classes exposed to the world to prevent scanning with sequential ids. Using the Hibernate id generator works, but that means that the "id" field in the domain class has to be a String, and some plugins could have assumed that the "id" property is always a Long, causing grief and hours of debug. Also, while developing, it's a lot easier for us humans to deal with short and sequential ids.
So I added a "uid" field in my domain class, but I want to catch the case where the UUID is already used. Very very small probability, but I wanted to put in place some code that could catch exceptions while saving the domain instances even for other reasons. I also didn't want to interfere with the normal controller flow.

First, I generate an app with Grails 2.2.2 and create a "Country" domain class, its controller and views. I used "grails generate-all Country" for that. The scaffolded controller assumes that the "id" is a Long, explaining why I prefer to leave the "id" alone and use another property instead. That issue might be fixed in the future.
Here is the domain class code:
package app
class Country {
    // Long id is still generated by Grails
    String uid = null
    String name
    static constraints = {
        uid unique: true
        name size: 2..25
    }
    static mapping = {
        version false
    }
    // using beforeInsert doesn't work, since validation runs before.
    def beforeValidate() {
        if (uid == null) {
            uid = UUID.randomUUID().toString() // works
            //uid = 1
            println "Country beforeValidate uid: $uid"
        }
    }
}

The "uid" property is added and null assigned to it, then it is checked in the "beforeValidate" method and not in the "beforeInsert" method. The Grails documentation specifies that the validation is run *before* saving and since the "uid" cannot be null (by default), the validation would fail if not assigned a value prior validation. Be aware too that the validation can be run several times before saving, according to the Grails documentation. By checking if the "uid" is already set, we don't do the work twice. You will notice the line: "uid=1". This is to test the "duplicate uid" catching code in the controller, see below.

The controller "save" method, the only modified one:

    def save() {
        def countryInstance = new Country(params) // (1)
        // saves returns the instance if successful, null if failed
        def saveOK = countryInstance.save(flush: true)
        if (saveOK) {
            println "save OK"
            flash.message = message(code: 'default.created.message', args: [message(code: 'country.label', default: 'Country'), countryInstance.id])
            redirect(action: "show", id: countryInstance.id)
            return
        }
        else {
            def error = countryInstance.errors.getFieldError('uid')
            if (error) {
                println "error code: $error.code"
                if (error.code == 'unique') {
                    countryInstance.uid = UUID.randomUUID().toString()
                    println "CountryController RESAVE countryInstance.uid: $countryInstance.uid"
                    if (countryInstance.save(flush: true)) {
                        println "save OK"
                        flash.message = message(code: 'default.created.message', args: [message(code: 'country.label', default: 'Country'), countryInstance.id])
                        redirect(action: "show", id: countryInstance.id)
                        return
                    }
                    else {
                        println "save NOT OK"
                        // could be another validation error
                        def errors = countryInstance.errors // all the field errors with names & codes
                        println "errors: $errors"
                        render(view: "create", model: [countryInstance: countryInstance])
                        return
                    }
                }
            } else {
                println "no UID error"
                // show the error
                def codes = countryInstance.errors.getFieldErrors().code
                println "errors.code: $errors"
                render(view: "create", model: [countryInstance: countryInstance])
                return
            }
        }
   }
The flow is:
1) a "new Country(params)" instance is created , "save" calls the validation, the Country.beforeValidation method is called, the "uid" assigned, then the real "save" is performed.
2) if the "save" is successful, nothing to do
3) if the "save" fails, there is a check to see if the "uid" property has the "unique" error, in which case, we assign another UUID and retry the save. If there is another error, there is no retry, that must be something else. Chances to generate twice an existing id are probably nil.
4) if the "save" succeeds, then it means we had an existing UUID in the DB and generated another one successfully.

To test the flow, I assigned 1 to the "uid" in the Country domain class, and watched the controller assign a UUID to it after catching the exception.

Beyond the UUID scheme, in the controller code, we can see how to catch a validation exception.It shows how to check the field in error and the type of error.

Refer to the Grails javadocs and also these:

http://grails.org/doc/latest/api/grails/validation/ValidationException.html#errors
http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/validation/FieldError.html
http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/context/support/DefaultMessageSourceResolvable.html#getCode()

This was a quick hacking/testing session, let me know if I missed something or any improvement.

Happy Grailling.


Wednesday, April 24, 2013

Google Cloud SQL with Grails

2014-06 NOTE: the following article doesn't apply anymore since Google Cloud SQL is now available publicly as a service without special authentication. see https://developers.google.com/cloud-sql/

Here are the steps to access a Google Cloud SQL database with a Grails application not hosted on Google App or Compute Engine. That means that a Grails application running on your local machine, a server or one of the cloud platform can still use the Google Cloud SQL services. First you need to enable SQL in your account and create your SQL instance and the database from the Google APIs console see https://developers.google.com/cloud-sql/docs/before_you_begin.
Then check the following docs: the Google Cloud SQL online doc for external access is at https://developers.google.com/cloud-sql/docs/external . It explains what the driver configuration is and how to get the OAuth tokens on your machine. For that download the command line tools at http://dl.google.com/cloudsql/tools/google_sql_tool.zip You need to run the command line tool once, it will ask you to use your browser to authorize access from your machine see the doc here https://developers.google.com/cloud-sql/docs/commandline .

Here are the steps:
1) enable SQL on your Google Account
2) create a SQL instance (container for your databases). You can use the console to interact with your database (click on the "SQL Prompt" tab).
3) download the command line tools, unzip them in the folder of your choice
4) run them with the name of your SQL instance (the same name that the APIs console shows)
5) follow the instructions to get the authorization code to access the SQL instance from your machine
6) the "sql>" prompt shows up.
7) use the mySQL commands to verify the connection like "show databases"...
8) copy the "google_sql.jar" file from the command line folder created earlier to the /lib folder in the grails app. It contains the jdbc driver to access the Google SQL instance
9) change the Grails datasource.groovy file with your instance and database params as:
environments {
    development {
        dataSource {
        dbCreate = "create"
pooled = false // true doesn't work with Google SQL
driverClassName = "com.google.cloud.sql.Driver"
dialect = "org.hibernate.dialect.MySQL5InnoDBDialect"
username = 'root'
password = ''
//jdbc:google:rdbms://instance_name/database_name"
url = 'jdbc:google:rdbms://yourinstancename/yourdatabasename'
        }
...

10) run your app.

Notes:
1) The driver doesn't seem to support dbCreate = "create-drop" as of April 2013. Grails fails with a "DatabaseMetaData; nested exception is
 com.google.cloud.sql.jdbc.internal.SQLFeatureNotYetImplementedException: Not implemented Yet" error. It works with "create" or "update", not so bad. If you find a way to get the dbCreate = "create-drop" mode to work, please let me know! See update below.
2) Once your app is up and running, create a user/password for it, don't use the "root" as shown above.
3) "pooled = true" doesn't work. See https://developers.google.com/cloud-sql/docs/external : "Note that connections to a cloud hosted database should be managed differently to those on a conventional server. In particular, be aware that your database instance may be taken offline while not in use, and any pooled connections would be closed. Rather than using a connection pool we recommend that a new connection is created for each new transaction since the time to create a new connection is similar to that required to test the liveness of an existing connection."

Update: thanks to Sergio Michels on the Grails Users list and Burt Beckwith's blog http://burtbeckwith.com/blog/?p=312 , the connection works now with dbCreate = "create-drop". I changed the file "myapp\grails-app\conf\spring\resources.groovy" to:


import org.springframework.jdbc.support.lob.DefaultLobHandler

beans = {
// for the Google Cloud SQL config
// see http://burtbeckwith.com/blog/?p=312
lobHandlerDetector(DefaultLobHandler)
}




Friday, April 20, 2012

console.log for all browsers...

Just a line of JavaScript that allows me lo leave my 'console.log' lines while doing cross-browser development:

var console = console || { log: function() {} };

'console' is supported in Chrome and IE9 (and some others...) but not in IE6 that chokes on it. The line above just executes a 'null' console.log when console is not supported and lets me keep all the 'console.log' lines while I am developing my code.

Sunday, January 08, 2012

Caching jQuery objects in callbacks

In my code I try to avoid re-computing things when they don't need to be. One thing that John Resig mentions in his blog is that we should avoid re-computing jQuery objects with selector over and over for performance reasons. He talks about Twitter's experience.

I was browsing through John Resig's blog when I saw his "Learning Advanced Javascript" interactive slides here: http://ejohn.org/apps/learn/ . #21 caught my eye, since I have been trying to improve my code when I write callbacks in jQuery:

function isPrime( num ) { 
  ...
  isPrime.cache[ num ] = prime 
  ...
  }

The important part here is that functions can have properties. The issue is that we often need to access DOM elements or jQuery objects from inside the callback function, but we really should not re-calculate, i.e $('.someelements')), the jQuery objects every time the event callback is called. I also want to write the code as a one-liner if I can. I used to write:

var inp = $('#input');
var out = $('#output');

$('#copyname').click( function(e) { out.val(inp.val()); } )

but then the variables would pollute the namespace and make the code more verbose. Until recently I was using the jQuery 'data' property to *cache* the $() call:

$('#copyname').click( {src: $('#inputname')}, function(e) { $('#outputname').val(e.data.src.val()); } );

$('#inputname') is computed only once, but $('#outputname') is still computed every time the callback is called. Also the 'e.data.src' construct assumes a knowledge of jQuery. Granted, I could use an object  in 'src' with both jQuery objects. But instead, let's use a closure:


$('#copyname1').click(
    (function x() { var i = $('#inputname1'); var o = $('#outputname1'); return function(e) { o.val(i.val()); }; })() );

It's easy to read and short, doesn't pollute the namespace. We can also use John's caching technique like this:


$('#copyname').click(
    (function x() { x.i = $('#inputname'); x.o = $('#outputname'); return function(e) { x.o.val(x.i.val()); }; })() );

Here function x is called before the jQuery click function is called. it returns the anonymous callback 'function(e)'. That callback function will be passed the 'e' event object when called by jQuery when the use clicks on the button. The cool thing is that the callback function has access to 'x.i' and 'x.o', created in a closure inside the function x. No need for jQuery repeated calls or data property. The namespace is free of x or any temporary variable.

I just hope that the function x is garbage collected when the click handler is unbound... Any idea how to check that? Is it a good application of closures and function properties?

Friday, March 18, 2011

High order loop function in Javascript

Writing Javascript code after Groovy code makes you wish you could extend the language. So I tried to write a Javascript function to rewrite the 'for' loop in a different way, passing the loop parameters and a function to my new 'loop' function. Here are a few ways of doing it, the difference is how the 'for' parameters are passed to the 'loop' function. I wish this was integrated in jQuery, that would make some code more fluid than a 'for' loop in the middle of jQuery code. The next step could be to add the little bit of code to make it a jQuery extension.

OBJECTIVE:
I want to replace a *normal* for loop like this:

var res = []; // array to hold all the results of the fn(args) calls
for (var i = 0 ; i < max ; i + step) res.push(fn(args)); // loop and call the fn(args) function, collecting the results in the res array

by something a bit less verbose like that:

var res = loop(0, max, step, fn, args);

First try:

Passing the parameters in an array [start, end, increment] and the function to call as the second argument. The argument for the function is not there, because I worked out a second form that I like better before including the argument for the function.

Params:
p : number or array

- if number: end index value. The start index is set to 0 and the increment to 1.
- if array of numbers:
p[0] = loop index start
p[1] = loop index end + 1
p[2] = loop index increment

fn: function to apply in the loop. The function receives the loop index as its argument

Result:
Array of results returned by the function

Loop function definition:

function loop(p, fn)
{
var ar = [];
for (var k = (p[0] || 0) ; k < (p[1] || p) ; k += (p[2] || 1))
{
var r = fn(k);
if (r !== undefined) ar.push(r);
}
return ar; // return an array of the function results
}

Examples:

var fn1 = function(index)
{
alert("fn1 index: " + index);
return (index);
}

var res = loop(4, fn1);
alert("fn1 result: " + res); // [0,1,2,3]

res = loop([1, 10, 2], fn1);
alert("fn1 result: " + res); // [1,3,5,7,9]


Second try: to avoid the array for the loop parameters, the loop function can be written like the following. Parameters for the function have been added as well.

function nloop(_s, _e, _i, _f, _c, _a0, _a1, _a2)
{
// _a0, _a1, _a2 are the argument to pass to the function, on top of the index. Optional
// Default if all arguments are specified
// call arguments: (start, end, step, function [,context [arg0 [, arg1 [, arg2]]]]).
var c; // function context: 'this' for the function. Optional
var f; // function to call, required
var i; //  step, loop increment. Optional
var e; // loop end. Optional
var s; // loop count or loop start if _e is defined. Required
var ar = []; // result, array of results from the function _f calls

if (_f instanceof Function)
{
c = _c;
f = _f; // function to call
i = _i; //  step
e = _e; // end
s = _s; // loop count or loop start if _e is defined. Required
}
// call arguments: (start, end, function, context). Default step = 1.
else if (_i instanceof Function)
{
c = _f;
f = _i; // function to call
i = 1; //  step
e = _e; // end
s = _s; // loop count or loop start if _e is defined. Required
}
else if (_e instanceof Function)
{
c = _i;
f = _e; // function to call
i = 1; //  step
e = _s; // end
s = 0; // loop count or loop start if _e is defined. Required
}
else return ar;
// alert('start: ' + s + ' end: ' + e + ' step: ' + s);
// var undef; // to test if the function result is undefined
for (var k = s ; k < e ; k += i)
{
var r = f.call(c, k, _a0, _a1, _a2);
// if (!(r === undef)) // looks like it's working in FF and IE6. Is it a proper way to test for undefined?
if (typeof(r) !== 'undefined') // would it be a bit slow to test for a string?
{
// alert('f result: ' + r);
ar.push(r);
}
}
return ar;
}

Examples of calls:

var fn2 = function(index, a, b, c)
{
// check the parameters and the context
alert("fn2 index: " + index + ' a: ' + a + ' b: ' + b + ' c: ' + c + ' this.name: ' + this.name);
return (index);
}

// An object to pass as the context (aka 'this') for the function called in the loop
var anobject = { name: 'an Object' };

// loop from 1 to 10 step 2, calling fn2 with 'anobject' as 'this' and with 'a', 'b' and 'c' as parameters to fn2
res = nloop(1, 10, 2, fn2, anobject, 'a', 'b', 'c');
alert('nloop fn2 result: ' + res);

res = nloop(1, 3, 1, fn2, anobject, 'a', 'b', 'c');
alert('nloop fn2 result: ' + res);

// function parameters are optional
res = nloop(1, 10, 2, fn2, anobject);
alert('nloop fn2 result: ' + res);

// step optional
res = nloop(1, 5, fn2, anobject);
alert('nloop fn2 result: ' + res);

// start index optional, 4 is the end index + 1
res = nloop(4, fn2, anobject);
alert('nloop fn2 result: ' + res);

var fn3 = function(index)
{
alert('fn2 index: ' + index);
return index;
}
res = nloop(1, fn3, anobject);
alert('nloop fn3 void result: ' + res + ' res == []: ' + (res == []) + ' res == null: ' + (res == null) + ' res.length: ' + res.length);


Sunday, July 18, 2010

On Reserved Words in Programming languages...


I just got bitten by IE when I inadvertently used 'class' as a variable name in Javascript. Firefox doesn't mind but IE generates an error (and I am glad it does). My reference (the David Flanagan "Javascript, The Definitive Guide", 4th Ed) shows that 'class' is not a reserved word in the ECMAScript (aka Javascript) Language definition, but is in the ECMA extension. I should not have used it anyway, I wasn't not paying attention, especially when Notepad++ was showing it as a reserved word in italic.


That's not the first time I encounter that issue, SQL has many variants and it's quite difficult to know and remember what words are reserved in which dialect of SQL. Using Hibernate or other layers on top of a SQL database complicates that as well. I spent some time in the past chasing a bug like this in one of my Grails applications.


So, in conclusion: if I was a good boy, I would get the list of reserved words of all the components that have some in each of my projects and keep them handy for a check when things look really weird, or as part of a final Q&A check.

Thursday, October 15, 2009

Over my last few Grails projects, although Grails cuts the number of code lines for a Web application down a lot, I realized that I was doing a lot more of code editing than I wanted to. A few areas on my projects needed some improvement: the controllers and the views (show, edit, create) are mostly the same for different domain objects and a lot of code for the persistence should be in services instead of the controllers.

I also wanted to be able to test the persistence layer independently from the controllers and being able to switch to something else than Hibernate if I wanted to without having to touch the controller code. So I designed a project with an "InstanceController", two views and an "InstanceService" that implements the common code for most domain objects. This is really the first draft and I envision a lot of improvements over this concept. With the dynamic features of Groovy, it could be possible to add the same features in a Groovy-er way. Work in progress.

The InstanceController works with two views for each domain object: "crud.gsp" and "list.gsp" and the InstanceService sub-classed for the particular domain object. So the structure of the Grails project is basically the same but "crud.gsp" implements all the functions of "edit.gsp", "show.gsp", "create.gsp".

So no more of editing three files when the domain object changes or the GUI changes. The GUI is consistent across the CRUD operations. The controller has an additional action "formactions" used in "crud.gsp" to manage the "cancel", "save", "edit" and "delete" buttons in the "crud.gsp" view. It also has a "void bindmore(instance, params)" method that can be overridden to bind checkboxes or other particular HTML elements to the domain class properties.

The usual "index", "list", "show", "create", "edit", "update", "delete" and "save" actions are still there if needed, but the view is handled by "crud.gsp" and the "formactions" in the controller. "formactions" calls "create", "edit", "save" and "delete" from the buttons clicked in "crud.gsp". All action closures call the methods of the same name to be able to override them in a subclass of the InstanceController.

The UI flow is: display "list.gsp", from an application menu for example, then a click on an item in the list calls "show" in the subclass of InstanceController for the domain object, which displays "view/domainobject/crud.gsp". Then clicking "delete", "edit", "save" or "cancel" calls the "formactions" closure in "/controller/domainobjectController". "formactions" calls "save", "update", "delete", "create" or displays the "list.gsp" view.

A couple of things there, the handling of "cancel" can be done with consistence, depending on the context and the application. "cancel" while editing means drop the changes and go back to the "show" mode, but "cancel" in show mode should go back to the "list" view. We could also hide the "cancel" button in "show" mode in "crud.gsp".

A small, but quite appreciated by the users, feature is highlighting the last object worked on in the "list.gsp" view. The object instance "id" is passed to "list.gsp" which adds the "selected" class to the line where the object is displayed, so the line is highlighted in the table (in yellow with my CSS style). It makes it very easy for the user to locate the last line worked on.

The GUI mode ("SHOW", "EDIT", "CREATE" is maintained between "crud.gsp" and "formactions" in the InstanceController and allows showing or hiding elements and buttons.

The subclass of the "InstanceController" must implement the "setup" method to define the "InstanceService" associated with the controller for the persistence operations and the domain object name displayed in the views. The "InstanceController" subclass can override any of the "InstanceController" methods if need be.

For the persistence layer, the "InstanceService" implements "list", "getCount", "getById", "newinstance", "save", "update", "delete", "findByName", "createDefaults" (creates initial values if none exist in the database) and "archive" if the domain object has an "archived" property. The subclass of "InstanceService" for the domain object needs to implement the "setup" method, where the initial domain objects are defined in the "defaults" list if needed. The "instanceclassname" containing the domain class name must be defined as well as the domain object property name used for sorting the "list.gsp" view. Here too, the "InstanceService" subclass can override any of the "InstanceService" methods if need be. Last thing not to forget, the "setup" method of each "InstanceService" subclass must be called in "Bootstrap.groovy", or in the "setUp" method of any integration test.

The domain class must implement "String toMessage()", to display a user-friendly domain object name. For example, my class name is "Streettype", but "toMessage" will return "Street Type". It's used in "crud.gsp" and "list.gsp". "toString" could be used, but then a bit tricky if "toString" is also used for debugging. I guess we could check if "toMessage" is implemented and use "toString" if not.

The code is posted at http://code.google.com/p/thecodefactory/wiki/GrailsRefactoring



Friday, November 23, 2007

I just discovered the "Scala" language, thanks to an excellent article "Java EE meets Web 2.0" (http://www.ibm.com/developerworks/web/library/wa-aj-web2jee/) on IBM's developerWorks. Scala is very close to Java and generates class files that run on the JVM. I am a user and a fan of Groovy, but I am interested in Scala for its Actors library: Actors are "tasks" that can send and receive messages synchronously or asynchronously. There is a short tutorial at http://lamp.epfl.ch/~phaller/doc/ActorsTutorial.html by Philipp Haller, the author of the library.

The Scala documentation says that Scala objects can call Java objects and vice-versa. I wanted to write a code snippet to see how a Java application can create and call Scala objects. It's very basic but it works!

A Java class "Zoo" with the "main" method creates a Scala object "Dog" and calls its method "talk".

Running the Zoo main on Windows:

C:\ScalaTest>java Zoo
Zoo...
Woof, woof!

Here it is the code for the 2 files Zoo.java and Dog.scala:

Zoo.java:

class Zoo {
public static void main(String[] args)

{
System.out.println("Zoo...");
Dog dog = new Dog();
dog.talk();
} // main
} // class Zoo

Dog.scala:

class Dog
{
val sound = "Woof, woof!"
def talk() = println(sound)
} // class Dog

How to build it on Windows:

Compile the Scala file first:
C:\ScalaTest>scalac Dog.scala

Then compile the main app, Java will find the Dog.class
C:\ScalaTest>javac Zoo.java

Run it:

C:\ScalaTest>java Zoo
Zoo...
Woof, woof!

"Zoo" is printed by the Java Zoo class
"Woof, woof" is printed by the Scala "Dog" class.

That's it!

Preliminary steps to install Java and Scala:
  • install a JDK (download it from http://java.sun.com/javase/downloads)
  • add the path to your java \bin folder (something like C:\jdk1.5.0_09\bin) to your PATH environment variable.
  • check that the Java compiler is accessible by opening a cmd window an typing "javac" and return. A list of options will be displayed, starting like this: "Usage: javac ...".
  • add the Java libraries to the "classpath" environment variable, something like this: "classpath=.;C:\jdk1.5.0_09\jre\lib\rt.jar;C:\jdk1.5.0_09\lib\tools.jar;"
  • install Scala (download it from http://www.scala-lang.org/)
  • add the Scala bin folder to your PATH environment variable. Should look like this: "...;C:\scala-2.6.0-final\bin;"
  • add the Scala libraries to the "classpath" environment variable. Should look like this with the Java libraries: "classpath=.;C:\jdk1.5.0_09\jre\lib\rt.jar;C:\jdk1.5.0_09\lib\tools.jar;C:\scala-2.6.0-final\lib\scala-library.jar;"
  • check that the Scala compiler is accessible from a cmd window: "C:\ScalaTest>scalac" will display a list of options: "Usage: scalac ..."

That should do it. If not, check java.sun.com for Java installation issues and scala-lang.org for the Scala ones.

I am off to try some Actors code in Scala.

Wednesday, October 25, 2006

I just did some work with the YahooUI Calendar and created a helper to make it easier to use. It is a Javascript file that you include in your HTML page header, a SPAN or DIV element where the icon for the calendar and the calendar itself will be displayed and a SCRIPT where the YahooCalendar object is created with a few parameters.