Friday, November 4, 2011

Intro to Clojure-clr: How to Interact with .Net objects

Today’s blog post is another ‘quick hitter’ covering how to instantiate a .NET object and interact with it’s instance methods and properties.

The Setup

If you haven’t already installed Clojure-clr take a look at my previous post:  Getting Started with Clojure-clr and get it installed.  Next, open up a cmd.exe session and enter clojure.main.exe. to start a REPL session.  Throughout all of my Clojure-clr blog posts I will assume you have added the clojure-clr directory to your PATH variable.

Instantiating a .NET Object

According to the CLR Interop page there are two ways to instantiate an object:

(Classname. args*) or (new Classname args*)

I will use the first function to create a System.IO.StreamWriter object that I will use to write to a file.  At the REPL prompt enter:

(def file (System.IO.StreamWriter. “testing.txt”))

The line above created a StreamWriter object that will write to a file named testing.txt.  Testing.txt will be in the directory where we started the REPL.  The object is stored in the symbol named file. Now it's time to write a line to testing.txt.

Calling an Instance Method StreamWriter.WriteLine

To write our line enter the following lines into the REPL:

(.WriteLine file “This is a line sent from the REPL!”)

(.Close file)

Since WriteLine isn’t a static method we start off the list with the method call with .WriteLine. Next comes file, the symbol that represents our StreamWriter object. Everything after file is a parameter passed to WriteLine method, in this case it is the string I want to write to the output file.  The .Close call flushes the buffer and closes the file.  Ok, I’ve put the two lines into the REPL and ran them.  How do I know if the line was actually written?  Run the line below in the REPL:

(println (slurp “testing.txt”))

The slurp function reads and returns the contents of the testing.txt file. The println function prints it out to the REPL screen.  Your REPL should look something like this:

image

I can see that my code did write out the line like I had hoped.  However the slurp function generated a deprecated message.  It is an easy issue to resolve by adding :encoding “ascii” to the call. The deprecation message only appears in the CLR REPL.  If I run the same line in the JVM REPL I don’t see this message.  So when I’m using slurp in CLR land I call slurp like this:

(slurp f :encoding “ascii”)

Now when I run slurp I see the line from testing.txt without the deprecation message.  If you want to see a list of all the possible encoding values check out io.clj in the Clojure-clr source repo.  The encoding values start on line 179.

Summary

You should now be able to instantiate a .NET object and call an instance method.  In this case I created a StreamWriter object and used it to write a line out to a file.  During the process we did see a difference between the JVM version of slurp and the CLR version of slurp which was easy to resolve the issue by passing in :encoding “ascii”. 

Resources

Clojure-clr download pageClojure-clr Interop page, Getting Started with Clojure-clr, An example that parses a web page and writes to a file using .NET objects

1 comment: