Posts Tagged ‘ispec’

Getting started with ISpec and Ioke – part 4

Tuesday, June 23rd, 2009

Part 4

This is part 4 of the increasingly mis-named Getting started with Ispec and Ioke trilogy. Last time we discussed the let keyword and I started working on the template object which represented the template to be parsed into a document.

Previously I used ISpec to assert that we could evaluate on cells on Bag. I wanted to start off this time by proving to myself that I could just as easily use activatable cells on Bag as well.

    it("should evaluate method on bag",
      bag = Bag mimic
      bag bread = method("butter")
      evaluator = Evaluator mimic(bag)
      evaluator evaluate(bread) should == "butter"
    )

As you can see, this time instead of assigning a string to a cell on the property bag an evaluating it, I instead assigned a method which returned a string to a cell and evaluated it. Sure enough it worked without any changes to the code. This creates some interesting possibilities, though I haven’t thought through all of the ramifications at the moment.

Sure enough it worked.

Next I wanted to push the envelope on Evaluator a little bit by defining the method which will do the work of parsing the template and injecting the values from the property bag into it.

describe("parsing",
    it("should return the template when the bag is nil",
      evaluator = Evaluator mimic(nil)
      template = Template mimic
      template text = "An extra special template"
 
      document = evaluator combine(template)
      document should == "An extra special template"
    )
  )

This is really a small step, and as I get more familiar with TDD and BDD, these seem to the the steps that I’m most comforable with lining up and knocking down when implementing new features. The other part of this is, doing the simplest thing that could possibly work to pass the spec / test. In this case, this is the simplest thing.

Evaluator combine = method (
  "Generates a document from a template and bag",
 
  template,
  template text
)

From here, I think that the next step is going involve using Ioke’s implementation of Regexp, which I will need to read up on. So I think I will cut this short for today and wait for next time for that topic.

The Code

The code for this example is available on github tagged as start_ispec_4

Getting started with ISpec and Ioke – part 3

Thursday, June 4th, 2009

Ruby, not that there’s anything wrong with that

A little while ago, I issued my Summer of Learning Challenge. As a suggestion, Ioke would be a great thing to learn for those that would like to learn something this summer, but aren’t sure what to learn. My project for the challenge is Ruby based, though I have a goal for the year to learn Ioke. As you can see from my Calendar About Nothing, which currently has a 15 day string of commits, I’ve been busily plugging away at both.

A few days back, Sam Aaron stopped by and commented on part 2 of this series, pointing out an error with my code.

Oops

Well, there were two errors there. First my spec stated that Bag should evaluate nil as an empty string, but code specified that it should be nil. Secondly, I had a problem with the way I had constructed my message chain so that my spec was evaluating nil should == nil. Of course this will always evaluate to true. I patched it up with the help of some advice in the comments. In the future I’ll need to remember to be more explicit in my intent by remembering to use parens when passing parameters to methods so that they aren’t interpreted as part of the message chain.

My initial solution, which I updated to the post, was to monkeypatch bag so that the cell nil returned an empty string. This solution didn’t really set well with me, but it passed the spec so I stuck with it. After some rest, I remembered reading about the keyword let.

The joy of let

I wasn’t familiar with the let method from the other languages I use, which are primarily Ruby and C#. But a little research showed that it provided an alternate solution to the specification. Opening up the specification for let, you will see that it accepts zero or more comma separated name value pairs and a block of code. It will then create a new temporary scope where the name is assigned the value and the code block is evaluated. At the end of the execution of the code block, the scope goes away and everything returns to normal.

Evaluator = Origin mimic
 
Evaluator initialize = method (
  "Pass the property bag into the evaluator, this will be used for future evaluations.",
 
  bag,
  @bag = bag
)
 
Evaluator evaluate = macro (
  "Takes the supplied message and evaluates it on the property bag. If nil is passed, it will return an empty string",
 
  msg = call arguments first
  let(bag nil, "",
    msg evaluateOn(bag)
  )
)

This is an interesting alternative. It provides a way to temporarily modify an object while ensuring that your modifications don’t touch anything else once you are done.

Variations on a theme

One thing that I found particularly interesting is that all of the following variations seem to work

  let(@bag nil, "",
    msg evaluateOn(bag)
  )
  let(bag nil, "",
    msg evaluateOn(@bag)
  )
  let(Bag nil, "",
    msg evaluateOn(bag)
  )

I assume that the first two versions work because the sigil version of bag (@bag) simply points to the instance stored in the cell bag on the evaluator object. In other words, when using Evaluator as ground, from inside the object, bag and @bag have the same meaning. I’ll need to look into this to see if what I suspect is true.

I think that the third variation works because bag mimics Bag and so changes to Bag cascade to bag. If it is true that modifications to the parent object made after the mimic has been made will cascade to all mimics, then that is a very powerful and easily abused feature of Ioke. Again these are speculation on my part, and I will need to look into the truth of the matter.

Starting Templates

Once I had that figured out I started thinking of the next specification to tackle. I decided that if I’m going to be able to use Ioke, I’d need to figure out how to work with files. I feared that working with files might have been left out of the Ioke implementation as it is a very young language. As it turns out, I was dead wrong. The FileSystem object is implemented and quite easy to use.

Ioke and the FileSystem

I was quite happy to find a spec for the FileSystem so that I could get a feel for it. It turns out that there are a number of useful methods available and it appears to have support for Windows filesystems as well.

I decided to have my template object check to see if the string passed to it is a valid file. If it is, it will load it. If not, it will assume that the string passed to it is the template text. I made it this way for testing purposes more than anything, and may change it around if it causes issues. But it was simple to setup and it works.

 
Template = Origin mimic
 
Template load = method("load will load a template file.",
 
  template,
  if(FileSystem exists?(template),
    Template text = FileSystem readFully(template),
    Template text = template
  )
)

The Code

Current source snapshot is available on github tagged as start_ispec_3

Getting started with ISpec and Ioke – Part 2

Sunday, May 17th, 2009

What I’m trying to make

I was recently reading a post on using Ioke’s web kit, IKanServe, on Google’s App Engine. It comes with a built-in HtmlBuilder object, but I wanted to try making something more like a rudimentary erb. Basically a way to embed code in template files.

Evaluating on the property bag

So far I have created a basic property bag, which is really just a basic Ioke Object. At it does is serve as a portable ground on which to evaluate messages on. Next there is the Evaluator which takes a bag when it’s initialized and evaluates messages against it, returning the results.

Don’t be put off by Ioke’s advanced features, it’s quite usable

When I first thought using this as an example, this was as far as I got. I figured that If I could get to the point where I could have a parameter object that could be be evaluated against from another context, I would probably have put in a siginificant amount of work for a basic example and I could wrap it up call it a day and try using it with IKanServe. Well as it turns out it wasn’t all that difficult to do. Really it was quite simple. I updated my test/evaluator_spec.ik to read:

use("test/helper")
use("evaluator")
use("bag")
 
describe("Evaluator",
  it("should have the correct kind",
    Evaluator kind should == "Evaluator"
  )
 
  it("should have accept a bag on initialization",
    bag = Bag mimic
    bag foo = "bar"
    evaluator = Evaluator mimic (bag)
    evaluator bag foo should == "bar"
  )
 
  describe("Evaluation",
    it("should evaluate nil as an empty string",
      bag = Bag mimic
      evaluator = Evaluator mimic(bag)
      evaluator evaluate(nil) should == ""
    )
 
    it("should evaluate string on bag",
      bag = Bag mimic
      bag foo = "wuzzle"
      evaluator = Evaluator mimic (bag)
      evaluator evaluate(foo) should == "wuzzle"
    )
  )
)

Looking at it now, the last spec should read “should evaluate message on bag” but you get the idea. At this point, I set out to implement this spec.

Don’t forget commas

My biggest problem by far was of my own design, and my own fault. When I first typed up the spec I left off the comma at the end of

    it("should evaluate nil as an empty string",

This caused the compiler to output a not so pretty error message, that that took me quite some time to track down. You see, I was sure that the issue was with my implementation of Evaluator rather than a syntax error in my spec. So, if you are getting an error that says that it can’t import your spec, look for syntax errors there first. You might be missing a comma.

Principle of least surprise

One of the things I really enjoy about Ruby is that it subscribes to the principle of least surprise. That is, if you don’t know the syntax for something, there is a good chance you will find it by trying the syntax that would make sense to you. I think that this is a side effect (or not so side-effecty) of what Ola Bini recently termed Syntax over Explicit APIs in the Ioke Philosophy.

In any case, the code to pass the spec was simply:

Evaluator = Origin mimic
 
Evaluator initialize = method (
  "Pass the property bag into the evaluator, this will be used for future evaluations.",
  bag,
  @bag = bag
)
 
Evaluator evaluate = macro (
  "Takes the supplied message and evaluates it on the property bag. If nil is passed, it will return an empty string",
 
  msg = call arguments first
  msg evaluateOn(@bag)
 )
)
Bag = Origin mimic
 
Bag nil = ""

I figure that there is probably a pretty big hole in my code here somewhere that I’m going to expose as I play with this more, but for now, I’m happy that it’s passing my spec.

Update: Thanks to Sam Aaron for pointing out the flaw in my spec.

Documentation arity

Before I conclude this post I wanted to mention the optional documetation that can be added to a method / macro / etc by passing the string that documents it in the first position. It reads well and it’s better than standard comments because the documentation is treated as it’s own first class member of the language.

Code

Source for this example can be found on github tagged as added_evaluator.

Getting started with ISpec and Ioke

Saturday, May 16th, 2009

Searching for common ground

Now that I have downloaded and built the source for Ioke E, I wanted to start using it. After all, I made a goal back in January to start using it, but as of yet had failed to follow through with it. Oh sure, I’ve been keeping up with the blog posts and looking at it from time to time, but really hadn’t made any steps to speak of. Until today.

I think that what I really needed was to find some common ground with Ioke. Something I could call familiar and the branch out from. ISpec is where I found it. I found it in two ways really, first in the ability to write specs to test my knowledge of Ioke coding and also in reading existing specs that have been written. These specs run when you download and build Ioke from source, which incidentally, is a painless process I would recommend to any interested.

So what’s next?

Note:I’ve pushed my code out to github tagged as start_ispec

I started out by creating a directory for my project with subdirectories for src and test

~/working $ mkdir ioke-examples
~/working $ cd ioke-examples
~/working/ioke-examples $ mkdir src test

Next I created my first spec as test/bag_spec.ik.

use("ispec")
use("src/bag")
 
describe("Bag",
  it("should have the correct kind",
    Bag kind should == "Bag"
  )
 
  it("should return the values in assigned cells",
    Bag name = "cheeze"
 
    Bag name should == "cheeze"
  )
)

There is nothing really interesting being tested here, the behavior is that of pretty much any Ioke object. The only thing of note is that the use directive is from the root of the project so to specify bag.ik which as a relative path from the spec would be ../src/bag.ik, was actually just src/bag.ik. Next I made an implementation src/bag.ik as

Bag = Origin mimic

This passed. Next I started making a another spec and class. Thinking that I would keep going with this path of thought. I made test/evaluator_spec.ik as:

use("ispec")
use("src/evaluator")
 
describe("Evaluator",
  it("should have the correct kind",
    Evaluator kind should == "Evaluator"
  )
 
  describe("Evaluation",
    it("should evaluate nil as nil"
      Evaluator evaluate nil should == nil
    )
  )
)

and src/evaluator.ik as

Evaluator = Origin mimic
 
Evaluator evaluate = method (
 
)

This results in the following

~/working/ioke-examples$ ispec test
.P..
 
Pending:
 Evaluator Evaluation true (Not Yet Implemented)
 
Finished in 0.26 seconds
 
4 examples, 0 failures, 1 pending

Pretty neat that it sees it as a pending implementation. Overall this was a great success, ISpec was working, but something was still nagging me.

Something isn’t right

Maybe it’s my Ruby roots, maybe it’s that I was being picky but having to specify the source directory when referencing bag.ik and evaluator.ik just didn’t seem right. I needed something like test_helper.rb in Ruby.

I looked around for a while and finally started digging into the test directory for Ioke, which is a great reference for the language. Three cheers for TDD! After a little fiddling I found that I could make a file called test/helper.ik as follows:

use("ispec")
System loadPath << "src"

This automatically loads ISpec and also adds the src directory to System loadPath, which is a list of the locations that Ioke will look for files in the use directive.

This allowed me to change use directives at the beginning of my specs to something like:

use("test/helper")
use("bag")
 
describe("Bag", ....

Comfort level

Now that I have my ISpec basics up and running, I hope to be playing more with this interesting language. Hopefully you will be seeing more Ioke posts here soon.