magpiebrain

Sam Newman's site, a Consultant at ThoughtWorks

Archive for ‘June, 2005’

The inclusion of the enclosure element in the RSS 2.0 specification opened the door for what Ben Hammersley called Podcasting. The enclosure element was originally introduced by Dave Winer to allow Christopher Lydon to associate mp3’s of his radio shows. Adam Curry and other’s software took enclosures and developed software such as iPodder to automatically download mp3’s (for more information on this see the increasingly excellent wikipedia).

Recently I was mentally bemoaning the lack of developers who provided RSS/Atom feeds that let me know when their software has been patched, or when new versions of their software is available. Then a thought occurred to me – if software such as iPodder can automatically download mp3s referenced in RSS enclosure elements, then why couldn’t a similar system automatically download software patches and new versions, and perhaps even instal them?

At it’s simplest you could use existing technology to download the patches, then notify the user that new patches are available. Taken to the logical extreme and using some application/os specific plugins such software could also enable you to install the patch/upgrade. Even better, information on the plugin required could be contained in the RSS/Atom feed itself in some way – you subscribe to the update feed in this new bit of software, the program then detects which plugin is needed to enable installing the plugins, and does the rest for you.

The simplest plugins would simply download and run the executable. Others might work with OS’s built in upgrade mechanisms, such as debian’s apt-get – others still could use language specific management techniques such as Ruby Gem’s. This would be useful for a single user, but imagine how useful this would be in a large organisation – rather than using often expensive centralised installation software, system admins could create their own RSS feeds of the needed patches and enable automatic download and patching for all company workstations.

It’s possible that some of the more advanced features such as identifying he needed plugins, downloading via BitTorrent or detailing OS specific updates (or perhaps even general update criteria such as “upgrade only if you have version 2.11”) that you might need to use an RSS extension, but even using simple RSS enclosures you could achieve a lot.

So the name? Well, it’s not simply mp3s any more. I originally thought “Patchcasting” which has a nice ring, but still seems limiting – “Softwarecasting” is too unwieldy, so I was very happy to come up with Bitcasting – which seems like a blanket term to cover the distribution of any binary format using an RSS feed to determine when and what to distribute. Annoyingly enough a company called “Digital Bitcasting Corporation” already exists…

The uses are varied, and the technology is there, but as you know if you’ve spent any time reading this blog (unlikely given the stats) then I very infrequently follow through with this stuff, so I’m pinging LazyWeb too.

Advertisements

Seems to be a UK English usage. A snagging list details the outstanding and remedial work as a construction scheme comes to an end. Sometime the final stage payment is conditional on rectifying the items on the list.

There are always things that we miss. The building industry has known this for a while – towards the end of a construction project, a snagging list is drawn up to detail all those little mistakes that have been made, or damage that has been done inadvertently.
Continue reading…

I’m taking a break from my recent series of articles on Ruby (see Parts one, two and three of Ruby for Java (and C#) programmers) to revisit the subject of mocking in Ruby. My recent overview of the currently available mocking tools lead me to discuss a better syntax for the next mocking API.

One of my aims when talking about a new syntax for a mocking API was in order to make expectations more readable – and more usable as a living document detailing how the code being tested actually works. As has already been discussed, Ruby’s flexible syntax makes it particularly suitable for the creation of Domain Specific Languages – and I think we can do much better than the existing API’s (or even the more mature JMock) in moving towards a DSL for mocking.

My original idea was to steal from the structure of JMock:

mockObject = Mock.new(ClazzToMock)
mockObject.expects(:someOperation).
  with(arg1, arg2).
  willReturn(someReturn)

To which Carlos (correctly) pointed out that I should make use of Ruby’s built-in language constructs – he proposed using hashes to avoid chaining calls together:

mock_obj = Mock.new(ClassToMock)
mock_obj.expects(
:do_stuff,
:with => [arg1, arg2],
:returns => someReturn
)

The obvious difference here is that the API cannot enforce the expectation to be written in a way that makes sense, as I could just as easily write:

mock_obj = Mock.new(ClassToMock)
mock_obj.expects(
:do_stuff,
:returns => someReturn,
:with => [arg1, arg2]
)

Also of note is that (when we get a decent one) IDE’s won’t be able to help you construct your expectations – this was part of the aims behind JMock’s structure.

Nat countered with the use of a mocking mixin, and using blocks as the expectations:

mock = Mock.new “exampleMock”
expect 1 { mock.do_something(eq(10), !null) }
expect 3..4 { mock.something_else(eq(“hello”) }

In EasyMock terminology, when you define the expectation in a block, it is in a record state – that is you are registering the calls that you expect to be made. In EasyMock, you then have to call replay before the mock can be used. This really doesn’t help readability (JMock gets around this by having a different object for recording expectations to the one used as the mock). With Nat’s approach, the mock is only in replay mode within an expect.

Taking this further, I cannot see why multiple expectations on multiple mocks couldn’t be defined inside a single expect call:

expect {
  mock1.halve(eq(10)).returns(5)
  mock1.double(eq(5)).returns(10)
  mock2.insult.returns("Boogers!")
}

Before (more importantly if) I decide work on this, I want to try and get some consensus of opinion as to what would make a sensible syntax, so feedback on Nat’s approach is appreciated!

Following on from Part 2, we look at two of Ruby’s most important collection classes, Hashes and Arrays, as well as have a brief look at the typing system.

Update 1: Fixed typo, thanks Anjan – any day now I’ll stop writing this stuff so late at night I’m too tired to proof read.

Update 2: Fixed blatant syntax error – thanks Chris

Arrays

We’ve already seen a little of one of Ruby’s built in types, the array. You can work with them much like Java’s Array:

[ruby]
array = [4, 6.0, “Hello”]
array0 —> 4
array1 —> 6.0
array2 —> “Hello”
array.length—> 3
[/ruby]

Where in Java we’d need a for loop to iteratie through the elements in an array, in Ruby we can use a number of built-in array method each. For example to print out the string value of each item in the array:

[ruby]
array.each { | item | puts item.to_s }
[/ruby]

The array class makes use of the Enumerable module – any class which implements each and @ can include the @Enumerable module, getting a variety of helpful methods for free:

[ruby]
array = [4, 6, 8, 10]
array.find_all { | item | item => 8 } —> [8, 10]
array.include?(6) —> true
array.include?(“Fish”) —> false
array.partition { | item | item [[4, 6], [8, 10]]
array.min —> 4
array.collect { | item | item – 2} —> [2, 4, 6, 8]
[/ruby]

Hashes

Another of Ruby’s collection types is Hash. Like Java’s Hashtable or HashMap classes – a construct which uses a key to index an object. To access the values in a hash, you use the element reference construct, []:

[ruby]
ages = { “sam” => 28, “norman” => 60, “fred” => 45 }
ages[“sam”] —> 28
ages[“fred”] —> 45
ages[“jane”] —> nil
ages[“sam”] = 30
ages[“sam”] —> 30
[/ruby]

Hash also implements Enumerable:

[ruby]
ages = { “sam” => 28, “norman” => 60, “fred” => 45 }
ages.each { | name, age | puts ”#{name} is #{age} years old”}
ages.sort —> [[“fred”, 45], [“norman”, 60], [“sam”, 28]]
ages.include?(“sam”) —> true
ages.include?(“jane”)—> false
ages.partition { | name, age | age [ [[“fred”, 45], [“sam”, 28]], [[“norman”, 60]] ]
[/ruby]

We’ll be looking at more advanced uses of both Arrays and Hashes later on.

“Quack quack” – the Ruby typing system

There is a saying – “If it walks like a duck and talks like a duck, it must be a duck”. In Ruby, you don’t say something is a duck – you make it act like a duck. In Java, you hang a nice big sign around it’s neck saying “duck”, then go about implementing the duck methods. On the face of it, this isn’t a big difference. Compare:

public interface Duck {
  void waddle(int distance);

  String speak();
}

	

public class Mallard implements Duck {

public void waddle(int distance) { ... } public void speak() { return "Quack!"; } }

public class Pintail implements Duck {

public void waddle(int distance) { ... } public String speak() { return "Quack!"; } }

And in Ruby:

class Mallard
  def waddle(distance)
    ...
  end

  def speak
    return "Quack!"
  end
end

	

class Pintail

def waddle(distance) ... end def speak return "Quack!" end end

Now lets imagine a Dog class, who can also speak:

public interface Dog {
  String speak();
}

	

class Dalmation implements Dog {

public String dog() { return "Woof!"; } }

And in Ruby:

class Dog
  def speak
    puts "Woof!"
  end
end

Now lets imagine a Naturalist, who’s job it is to study the sights and more importantly the sounds of the wildlife around him. If we just wanted to study ducks, then we could define a simple interface:

public interface Naturalist {
  void study(Duck duck);
}

	

public class WildlifeReporter implements Naturalist {

public void study(Duck duck) { tapeRecorder.record(duck.speak()); } }

And in Ruby:

class Naturalist
  def study(duck)
    tape_recorder.record(duck.speak)
  end
end

Now if we wanted our Naturalist to also study a Dog, in Java we’d either have to define two methods – one study that takes a Duck, and another that takes a Dog – but more likely we’d define another interface (say, Animal) from which both Dog and Duck derive, and redefine study to take that new interface. With Ruby, our Naturalist is the same for both – all it cares about is that whatever gets passed into study defines a speak method.

Now implementing the Animal doesn’t seem like a big deal, and in this (highly contrived) example, it isn’t. But you can see how you’ll quickly end up with a number of type definitions, all defining the same operations, just so you can work in a generic fashion with a variety of objects. The typical solution to this in Java is to have many very fine-grained interfaces (in some cases you’ll even see many interfaces only implementing a single method).

We’ll be looking more at the Ruby typing system in later parts.

Update: Fixed bonehead misunderstanding on my part, thanks to Daniel spotting it, and a typo thanks to riffraff.

I left a few loose ends from Part 1, so I’m moving a discussion on the type system to Part 3 so I can revisit methods and classes.

Returning from methods

In the normal way, you can return from a method using the return keyword:

[ruby]
def calculate_sum(a, b)

return a + b
end
[/ruby]

By default however, the return value of any ruby method will be the result of the last line of execution, so the above method could be written as:

[ruby]
def calculate_sum(a, b)

a + b
end
[/ruby]

Personally, I prefer to use explicit return calls as it reduces ambiquity as to how a method should be used.

Class and Instance variables

Last time we didn’t talk about instance variables. Unlike Java, you have no need to define instance variables before you use them. Instead, when you need one, use it with the @ prefix, like so:

[ruby]
def initialize(name)

@name = name
end
[/ruby]

To define class variables (the equivilent of Java static variables) you use two @ symbols:

[ruby]
def initialize(name)

@name = name
@@last_creation_time = DateTime.now
end
[/ruby]

Variables without the @ prefix are considered local variables, and are only available within the scope of the block they were defined in.

unless

As I showed before, you can construct simple if/elsif/else blocks like so:

[ruby]
if some_value = = 0


elsif some_value = = 1

else

end
[/ruby]

Like Java, you can use ! to negate a boolean expression, or you can use != to denote not-equals. Ruby also adds the unless keyword – so rather than:

[ruby]
if some_value != 0


end
[/ruby]

You can write the following instead:

[ruby]
unless some_value = = 0


end
[/ruby]

Use of unless can help make code more readable, especially when using methods with a ? suffix, as we’ll show in the next section.

Special Method Suffixes

Ruby allows the use of two special suffixes for method names – ? and !. Any method followed by a ? is assumed to have a boolean return type, for example:

[ruby]
if task.completed?


end
[/ruby]

And rather than the ugly !task.completed?:

[ruby]
unless task.completed?


end
[/ruby]

The second suffix is used to denote destrcutive methods – that is those methods which affect the target of the method. For example, imagine we have a Sqaure class, which has two methods, flipHorizontal and flipHorizontal! – the first method should define a non-desctructive call which returns a copy of the Sqaure, whereas the second form should rotate the object itself.

Operators

In Java, operators such as +, -, * and the like all have meanings defined in the language itself. You can use + to concat strings, or you can use it for normal arithmetic, but that is about it. In Ruby, you can define the behaviour of these operators for each class. You’ll find yourself using this often when defining comparison operators. In Java, you’d implement the Comparable interface, which defines compareTo – returning -1, 0 or +1 if the object was less than, the same as or more than some other object. You would also have to seperately define equals() for equality, and the definition of == always asserts object identity. In Ruby, you can implement the <=> operator, which does the same job as Java’s Comparable, except that it can be used as an operator. For example if we wanted to define comparison in terms of a classes name:

[ruby]
def (rhs)

return name rhs.name
end
[/ruby]

And we could then do:

[ruby]
some_object some_other_object
[/ruby]

Include the Comparable module in your code however, and you automatically get the <, <=, = =>, > operators for free, as they can all be defined in terms of the result of the <=> operator. The fun doesn’t stop there – you can also define the [] oeprator to provide array indexing of your objects:

[ruby]
class RecordCollection

def [] (index)
return @records[index]
end
end
[/ruby]

And you can even define []= to provide a way to assign arrays:

[ruby]
def []= (array)

logger.debug(“Taking array #{array}”)
@records = array
end

collection = RecordCollection.new
collection[] = [Record.new(“Some Record”), Record.new(“Some other Record”)]
collection0 => Record.new(“Some Record”)
collection1 => Record.new(“Some other Record”)
[/ruby]

In Part three we’ll finally look at the Ruby typing system, and might have time to look at arrays and hashes.

In the first part, I’m just going to be covering the basics.

Conventions

Before we start, some coding conventions. Firstly, CamelCase for methods and variable names is out – for Ruby it’s lowercase and underscores all the way – it_is_this_way, itIsNotThisWay. Classes and Modules (of which more later) should start with an uppercase letter, but the files can start with a lowercase letter. The only break with this convention is in terms of class and module names – here you camel case should be used. Of course you can use CamelCase everywhere if you want, but it’ll be confusing when calling Ruby code written by other people.

Syntax

Some things you’ll notice straight off – brackets for methods with parameters are optional, so do_stuff(10, 20, 30) works, as does do_stuff 10, 20, 30. The current recommendation is to use paranthesis when you have arguments as there is a chance that Ruby 2 might break some method calls without brackets (I’d appreciate some clarification on this!).

Methods and if blocks use end to terminate rather than brackets:

[ruby]
def do_stuff

if something

elsif something_else

end
end
[/ruby]

Classes

Classes in Ruby are similar to classes in Java (we’ll deal with typing later). For example to define a Polygon class, you do the following:

[ruby]
class Polygon


end
[/ruby]

You can also subclass:

[ruby]
class Square < Polygon
[/ruby]

You implement constructors by defining an initialize method:

[ruby]
def initialize


end
[/ruby]

And call them using Polygon.new, Square.new etc.

Modules

You define modules using:

[ruby]
module Utils


end
[/ruby]

You use modules as mixins using the include keyword. For example imagine the following:

[ruby]
module Renderer

def draw_line(x,y)

end
end
[/ruby]

Your Square class can then include Renderer to use the draw_line method:

[ruby]
class Square < Polygon

include Renderer
end
[/ruby]

Some might argue you could get this using an Abstract base class – and you’d be right. However there are no limits to the number of mixins you can include, whereas you can only have one Abstract base class. Ruby provides several very useful mixins – for example if you define the = operator (we’ll be covering operators later), by including the comparable module you get <, <=, ==, >=, and > for free.

<h3 id="methods>Methods and visibility

As you’ve already seen, you define a method using def method_name – if you have parameters, you define it using def method_name(arg1,arg2)). Ruby does support optional parameters. In Java, you’ll often see code like this:

[java]
void doSomething(String name) {

doSomething(name, null);
}

void doSomething(String name, String description) {


}
[/java]

In Ruby you can do:

[ruby]
def do_something(name, description = nil)


end
[/ruby]

In Java, where you have protected, public, private and default visibility, you have protected, public, private in Ruby. private in Ruby is more like protected in Java however – it can be called from either the class it was defined in, or subclasses. private methods however can only be called when using self as the reciever, so if do_stuff is private:

[ruby]
self.do_stuff #Allowed
do_stuff #Not allowed
[/ruby]

Put more simply, a private method cannot be called in a static context.

Ruby’s protected methods can be called only in the class itsef or subclasses, but can be called without a reciever as well as with a reciever:

[ruby]
self.do_stuff #Allowed
do_stuff #Allowed
[/ruby]

You have two options when defining method visibility. You can use the visibility keywords to define private/protected/public regions:

[ruby]
protected

def this_is_protected

end

private

def this_is_a_private_method

end

def this_is_also_private

end
[/ruby]

You can also do it on a single line:

[ruby]
def this_is_protected


end

def this_is_a_private_method


end

def this_is_also_private


end

protected :this_is_protected
protected :this_is_a_private_method, :this_is_also_private
[/ruby]

Personally I prefer the first technique.

Next time we’ll be looking at operators, arrays, hashes and perhaps even the Ruby typing system.

  • Update 1: Fixed wording in the modules section
  • Update 2: Updated methods section thanks to feedback from Curt Hibbs
  • Update 3: Fixed typos in the classes and methods sections (thanks Gavri Fernandez)
  • Update 4: Fixed typos (thanks Eliot and Alex) and clarified use of camel case (thanks Jon ).
  • Update 5 21st April 2006: Fixed up some missing text due to WordPress import. Used new syntax highlighting for code samples

A Screenshot of the backpack plugin for Quicksilver

Some of you may of seen the recent Quicktime movie showing Quicksilver posting Backpack updates. There isn’t that much information out there explaining how to do it, so I thought I’d post a quick tutorial on getting it all to work.
<!-more->

  1. Make sure you’re using the latest version of Quicksilver, with the Apple Mail and Backpack plugins installed
  2. Make sure Mail.app is setup properly. You can check this simply by firing up the client and try sending some emails.
  3. Next, you need to configure the email actions. In Quicksilver preferences, you need to enable the "Email Item... (Send Directly)" action, for the "Email Addresses", "Text" and "Files & Folders" types.
  4. Check this works – fire up quicksilver, hit ”.” and type some text in. Then hit Tab, and select the "Email Item... (Send Directly)" action and hit tab again – finally press ”.” and type in the destination (or select an address form your address book). If that works out, you’re ready to try sending email to backpack.
  5. Log in to Backpack to get your developer key. Go to your Account page, and towards the bottom, you’ll see an option to show your developer key.
  6. In the Catalog preferences for Quicksilver, click the ”+” button to add a new catalog – select "Backpack Pages" from the drop down. This will be the catalog that will work out how to talk to our Backpack pages. Your newly added catalog will be under “Custom”. Select it, then click the “i” icon in the bottom right. Put your username and developer key in.
  1. To try out your integration, bring up quicksilver and enter "note>> sometext". Hit tab and select "Email Item... (Send To)", tab again and bring up the backpack page you want to send the note to, hit enter and enjoy!