Peppermint Dev Den

Saturday 2 April 2016

Gulp: import tasks from other files

Recently I've been doing a lot of JavaScript work and have found it useful to use Gulp to perform build operations such as cleaning my repo of temporary files, compiling Sass stylesheets, etcetera. After using the same clean task in several projects, I was wanting to stop the copy-and-paste madness and import a shared clean task into my individual project gulp files.

In searching the cornucopia of knowledge that is the world-wide-web, I found a number of places that said to install the require-dir npm package and require a directory of tasks. This was not the approach I wanted as I was hoping to import individual files as required into my project gulpfiles not just importing a directory wholesale.

the failed attempt

First I created a separate clean.js file:

// clean.js
var gulp = require('gulp');
gulp.task('clean', function() {
  console.log(clean up); // the scope of the clean is for another post!
});

My hope was that I could simply require this file in my project's gulpfile and the task would be imported:

// project gulpfile.js
require('clean');

Unfortunately, this did not work but resulted in an error:

[17:26:19] Using gulpfile ~/Work/recce.bak/apps/web/gulpfile.js
[17:26:19] Task 'clean' is not in your gulpfile
[17:26:19] Please check the documentation for proper gulpfile formatting
The project's gulpfile just was not getting the task that was added in the imported file.

it's all about the gulp instance

The problem here was that the instance of gulp used by the imported file was not the instance of gulp that was running in the project's gulpfile. Instead, the file import needs to export a function so that the instance of gulp can be passed in from the project's gulpfile on import: This is a working approach:

// clean.js
module.exports = function(gulp) {
  gulp.task('clean', function() {
    console.log(clean up); // the scope of the clean is for another post!
  });
}
// gulpfile.js
var gulp = require('gulp');
require('clean')(gulp);

Using this approach, the gulp task defined in the imported file is added to the instance of gulp used by the running gulpfile and the world is put to rights:

[17:42:47] Using gulpfile ~/Work/recce.bak/apps/web/gulpfile.js
[17:42:47] Starting 'clean'...
clean-up
[17:42:47] Finished 'clean' after 146 μs

So, the long and the short is, when importing external files into a gulpfile, expose a function which takes the current gulp instance and pass it to the function to augment it with the tasks from the external file.

Thursday 11 April 2013

INotifyPropertyChanged - Strongly typed notifications

If you've used the INotifyPropertyChanged interface in WPF you might have wished that there was some way to raise the property changed events in a strongly typed way, rather than using property strings. Traditionally, a property changed notification would be raised something like this:

public class Person: INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private string _name;

    public string Name {
        get
        {
            return _name;
        }

        set
        {
            if (_name == value) return;
            _name = value;
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs("Name"));
            }
        }
    }

}

The problem with this is that the name of the property ("Name") is hard coded as a string, which means that if you rename the property you have to remember to rename the string and if you forget you won't know until runtime. Likewise, a type-o ("Nam") will also not be reported until runtime. It would be so much better if these notifications could be strongly typed and raised using expressions.

For example, why can't I raise the notification like this?

this.Notify(x => x.Name);

Well, I've written a few extension methods to allow exactly that:

public static class NotifyPropertyChangedExtensions
{

    // Raise the property change notification for the property identified by the
    // received expression.
    public static void Notify<T, TReturn>(this T notifier, Expression<Func<T, TReturn>> propertyExpression)
        where T : INotifyPropertyChanged
    {
        var args = new PropertyChangedEventArgs(propertyExpression.ToPropertyName());
        notifier.RaiseEvent("PropertyChanged", args);
    }

    // Find the property info for the property identified by the received expression.
    public static PropertyInfo ToPropertyInfo<TSource, TProperty>(this Expression<Func<TSource, TProperty>> propertyLambda)
    {
        Type type = typeof(TSource);

        MemberExpression member = propertyLambda.Body as MemberExpression;
        if (member == null)
            throw new ArgumentException(string.Format("Expression '{0}' refers to a method, not a property.", propertyLambda));

        PropertyInfo propInfo = member.Member as PropertyInfo;
        if (propInfo == null)
            throw new ArgumentException(string.Format("Expression '{0}' refers to a field, not a property.", propertyLambda));

        if (type != propInfo.ReflectedType &&
            !type.IsSubclassOf(propInfo.ReflectedType))
            throw new ArgumentException(string.Format("Expression '{0}' refers to a property that is not from type {1}.", propertyLambda, type));

        return propInfo;
    }

    // Find the name of the property identified by the received expression.
    public static string ToPropertyName<TSource, TProperty>(this Expression<Func<TSource, TProperty>> propertyLambda)
    {
        return propertyLambda.ToPropertyInfo().Name;
    }

    // Raises an event via reflection.
    // More details in: 
    //     http://blog.peppermint-it.com/2013/04/raising-net-events-using-reflection.html
    public static void RaiseEvent<T>(this object instance, string eventName, T eventArgs)
        where T : EventArgs
    {
        Type type = instance.GetType();
        FieldInfo field = FindEventInfo(type, eventName);
        if (field == null) throw new ArgumentException("Cannot find event named: " + eventName + " on type: " + type.Name, "eventName");
        object handler = field.GetValue(instance);
        if (handler != null)
        {
            Type invokeType = handler.GetType();
            MethodInfo invoke = invokeType.GetMethod("Invoke", new[] { typeof(object), eventArgs.GetType() });
            invoke.Invoke(handler, new[] { instance, eventArgs });
        }
    }


    // Supports RaiseEvent.
    // More details in: 
    //     http://blog.peppermint-it.com/2013/04/raising-net-events-using-reflection.html
    private static FieldInfo FindEventInfo(Type type, string eventName)
    {
        var field = type.GetField(eventName, BindingFlags.NonPublic | BindingFlags.Instance);
        if (field != null) return field;
        if (type == typeof(object)) return null;

        return FindEventInfo(type.BaseType, eventName);

    }
}

Now that's all fine and dandy, but what about when handling the change event. Once again, typically you get code like this:

Person person = new Person();
person.PropertyChanged += (sender, args) =>
{
 if (args.PropertyName == "Name")
 {
  // do stuff.
 }
};

Once again, hard coded strings reduce compile time safety and once again an extension method comes in handy:
public static class NotifyPropertyChangedExtensions
{
    // Check whether or not the property name in the received event args corresponds to the
    // property name identified by the received property expression.
    public static bool IsProperty<T, TReturn>(this PropertyChangedEventArgs args, Expression<Func<T, TReturn>> propertyExpression)
    {
        return args.PropertyName == propertyExpression.ToPropertyName();
    }
 
    // Raise the property change notification for the property identified by the
    // received expression.
    public static void Notify<T, TReturn>(this T notifier, Expression<Func<T, TReturn>> propertyExpression)
        where T : INotifyPropertyChanged
    {
        var args = new PropertyChangedEventArgs(propertyExpression.ToPropertyName());
        notifier.RaiseEvent("PropertyChanged", args);
    }

    // Find the property info for the property identified by the received expression.
    public static PropertyInfo ToPropertyInfo<TSource, TProperty>(this Expression<Func<TSource, TProperty>> propertyLambda)
    {
        Type type = typeof(TSource);

        MemberExpression member = propertyLambda.Body as MemberExpression;
        if (member == null)
            throw new ArgumentException(string.Format("Expression '{0}' refers to a method, not a property.", propertyLambda));

        PropertyInfo propInfo = member.Member as PropertyInfo;
        if (propInfo == null)
            throw new ArgumentException(string.Format("Expression '{0}' refers to a field, not a property.", propertyLambda));

        if (type != propInfo.ReflectedType &&
            !type.IsSubclassOf(propInfo.ReflectedType))
            throw new ArgumentException(string.Format("Expression '{0}' refers to a property that is not from type {1}.", propertyLambda, type));

        return propInfo;
    }

    // Find the name of the property identified by the received expression.
    public static string ToPropertyName<TSource, TProperty>(this Expression<Func<TSource, TProperty>> propertyLambda)
    {
        return propertyLambda.ToPropertyInfo().Name;
    }

    // Raises an event via reflection.
    // More details in: 
    //     http://blog.peppermint-it.com/2013/04/raising-net-events-using-reflection.html
    public static void RaiseEvent<T>(this object instance, string eventName, T eventArgs)
        where T : EventArgs
    {
        Type type = instance.GetType();
        FieldInfo field = FindEventInfo(type, eventName);
        if (field == null) throw new ArgumentException("Cannot find event named: " + eventName + " on type: " + type.Name, "eventName");
        object handler = field.GetValue(instance);
        if (handler != null)
        {
            Type invokeType = handler.GetType();
            MethodInfo invoke = invokeType.GetMethod("Invoke", new[] { typeof(object), eventArgs.GetType() });
            invoke.Invoke(handler, new[] { instance, eventArgs });
        }
    }


    // Supports RaiseEvent.
    // More details in: 
    //     http://blog.peppermint-it.com/2013/04/raising-net-events-using-reflection.html
    private static FieldInfo FindEventInfo(Type type, string eventName)
    {
        var field = type.GetField(eventName, BindingFlags.NonPublic | BindingFlags.Instance);
        if (field != null) return field;
        if (type == typeof(object)) return null;

        return FindEventInfo(type.BaseType, eventName);

    }
}

Now the previous code can be changed to:

Person person = new Person();
person.PropertyChanged += (sender, args) =>
{
    if (args.IsProperty(x => x.Name))
    {
        // do stuff.
    }
};

Compile time balance is once again restored!



Raising .NET Events Using Reflection

Recently I needed to raise an event on an instance of an interface without having direct access to the concrete class. I knew the event existed (as it was declared in the interface) but external classes only have access to subscription to and de-subscription from the event, not the event itself, so I resorted to reflection.

The solution I ended up with was:


public static class EventExtensions 
{
    /// <summary>
    /// Raises the event with the specified name on the received object instance.
    /// passing to the handler the event arguments provided.
    /// </summary>
    /// <typeparam name="T">The type of the event arguments to pass to the event handler.</typeparam>
    /// <param name="instance">The instance to raise the event on.</param>
    /// <param name="eventName">Name of the event to raise.</param>
    /// <param name="eventArgs">The event args to pass to the event handler.</param>
    public static void RaiseEvent(this object instance, string eventName, T eventArgs)
        where T: EventArgs
    {
        Type type = instance.GetType();
        FieldInfo field = FindEventInfo(type, eventName);
        
        if (field == null) 
        {
            throw new ArgumentException("Cannot find event named: " + eventName + " on type: " + type.Name, "eventName");
        }

        object handler = field.GetValue(instance);
        if (handler != null)
        {
            Type invokeType = handler.GetType();
            MethodInfo invoke = invokeType.GetMethod("Invoke", new[] { typeof(object), eventArgs.GetType() });
            invoke.Invoke(handler, new[] { instance, eventArgs });
        }
    }

    /// <summary>
    /// Finds field info for the event with the specified name.  This method looks firstly in the
    /// passed type and of a non-public instance field with the specified name cannot be found it
    /// looks at the type's base type.  This is continued up the type hierarchy until a field with
    /// the event name is found or we reach the <see cref="Object"/> type.
    /// </summary>
    /// <param name="type">The type to check for the event of the specified name.</param>
    /// <param name="eventName">Name of the event to find.</param>
    /// <returns>A field info instance for the specified event.</returns>
    private static FieldInfo FindEventInfo(Type type, string eventName)
    {
        var field = type.GetField(eventName, BindingFlags.NonPublic | BindingFlags.Instance);
        if (field != null) return field;
        if (type == typeof(object)) return null;

        return FindEventInfo(type.BaseType, eventName);

    }
}


Example

To raise the PropertyChanged event on an instance of INotifyPropertyChanged you can use the following code:

INotifyPropertyChanged instance; // Assume this variable has been assigned a valid value.
PropertyChangedEventArgs args = new PropertyChangedEventArgs("Example");

instance.RaiseEvent("PropertyChanged", args);

Saturday 4 February 2012

Callbacks in Four Flavours

Recently I've had to learn a little PHP for a technical test I was required to do. As part of the test I wanted to implement a little event driven model and came up with a solution using PHP 5.3's anonymous functions. That got me thinking, why don't I try implementing a similar, simple eventing script using four different dynamic languages: Python, PHP, Ruby and JavaScript and see which I like best? So here's the results:

Python

class Event:
    def __init__(self):
        self.subscriptions = []
        
    def subscribe(self, handler):
        self.subscriptions.append(handler)
        
    def publish(self, args):
        for x in self.subscriptions:
            x(args)
        
        
class Raiser:
    def __init__(self):
        self.running = Event()
    
    def run(self):
        self.running.publish("I'm running")
        
class Client:
    def __init__(self):
        self.raiser = Raiser()
        self.raiser.running.subscribe(self.handler)
        
    def handler(self, args):
        print(args)
    
    def run(self):
        self.raiser.run()
        
        
        
client = Client()
client.run()

PHP

<?php
class Event {
    function __construct() {
        $this->subscriptions = array();
    }
    
    function subscribe($handler) {
        array_push($this->subscriptions, $handler);
    }
    
    function publish($args) {
        foreach($this->subscriptions as $subscription) {
            $subscription($args);
        }
    }
}

class Raiser {
    function __construct() {
        $this->running = new Event();
    }
    
    function run() {
        $this->running->publish("I'm running");
    }
}

class Client {
    function __construct() {
        $this->raiser = new Raiser();
        $handler = function($args) {
            print $args;
        };
        $this->raiser->running->subscribe($handler);
    }
    
    function run() {
        $this->raiser->run();
    }
}

$client = new Client();
$client->run();
?>

Ruby

class Event
    def initialize()
        @subscriptions = []
    end
    
    def subscribe(handler)
        @subscriptions.push(handler)
    end
    
    def publish(args)
        @subscriptions.each do |x|
            x.call(args);
        end
    end
end

class Raiser
    attr_reader :running
    def initialize()
        @running = Event.new
    end
    
    def run()
        self.running.publish("I'm running")
    end
end

class Client
    def initialize()
        @raiser = Raiser.new
        @raiser.running.subscribe(lambda {|x| handler(x)})
    end
    
    def handler(args)
        puts args
    end
    
    def run
        @raiser.run
    end
end

client = Client.new
client.run

JavaScript

var util = require('util'); // required for node.js only
function Event() {
    this.subscriptions = [];
    
    this.subscribe = function(handler) {
        this.subscriptions.push(handler);
    }
    
    this.publish = function(args) {
        for(var i=0; i<this.subscriptions.length;i++) {
            this.subscriptions[i](args);
        }
    }
}

function Raiser() {
    this.running = new Event();
    
    this.run = function() {
        this.running.publish("I'm running");
    }
}

function Client() {
    this.raiser = new Raiser();
    
    this.handler = function(args) {
        util.print(args);
    }
    
    this.run = function() {
        this.raiser.run();
    }
    
    this.raiser.running.subscribe(this.handler);
}

var client = new Client();
client.run();

My Thoughts

Python

Pros

  • Brevity: I love how succinct the code is in Python
  • Easy function passing: functions can simply be passed in without the brackets
  • No need for semi-colons

Cons

  • Every function seems to need to have 'self' passed to it. It becomes I minor irritation
  • Similarly, all references to class methods and variables need to be prepended with 'self.'

PHP

Pros

  • One possible (but rather dubious) pro is that at least variable are clear with their prefixed '$'.
  • It is possible to define private methods and member variables.

Cons

  • Using '->' instead of '.' to access class members is a right pain in the rump! Why require two characters (one requiring a SHIFT) to do the job of one?
  • Prefixing all calls to class functions and methods with '$this->' is a pain.
  • Functions must be passed as anonymous variables, which means the code must be declared inside the function that does the subscription.
  • Some operations (such as pushing to an array) are done in a functional way rather than and OOP kind of way.
  • Quite verbose.

Ruby

Pros

  • Lack of curly braces makes it quite easy to read.
  • Use of '@' to access member variables is much less verbose than prefixing everything with 'this' or 'self'.

Cons

  • It's not a big thing, but function call must be passed as lambdas which add a little bit more complexity to remember
  • A bit more verbose than Python.

Javascript

Pros

  • Like Python, functions can simply be passed without the round brackets.

Cons

  • A bit verbose
  • Access to class members requires 'this' prefix

Conclusion

Really there's not much in it. All four dynamic languages allow for some kind of eventing/callback option. Overall, my preference has always been for Ruby, however, since doing this experiment, I am really liking the look of Python, so my allegiances may switch.

Monday 5 April 2010

Why I'm Starting to Love Ruby on Rails (pt 1)

Testing Controllers

For a while I've been wondering what the fuss was about Ruby on Rails. As an ASP.NET developer, the switch from Web Forms to ASP.NET MVC was an epiphany, a glorious moment of light and a sudden realisation that I never wanted to go back to the darkness of Web Forms again, but the same had not been the case with Ruby on Rails. My previous RoR dabblings had felt OK, but there had been no earth shattering revelations. This time round, I'm feeling much more moved. The primary reason: TDD.

When I looked at RoR before, I had not really 'been into' TDD. Now I am big style and the first thing that strikes me with RoR is how well it is tailored to TDD. As the Rails guys themselves say, testing was not a bolt-on afterthought with RoR, but was designed in from the ground up, and it shows. One of the real benefits of RoR are 'functional tests'. Functional tests are effectively tests run against the controller. While testing controllers is certainly very possible in ASP.NET MVC, a certain amount of set-up and careful structuring is required to make it work, especially in a 'test first' way. Also, if you're using strongly typed view models instead of ViewData to communicate between your controller and your view (which I've always recommended), several steps are usually needed for your model assertions. Typically:

  • Injecting mocked versions your HTTP context stuff (request, session, response, etc.)
  • Structuring persistence in an implementation agnostic way, usually through the use of interfaces and patterns such as a 'repository' or 'service'
  • Cast your controller result to a specific result type (ViewResult, RedirectResult, etc.)
  • Assert on any properties of the specific result type (ViewResult.Model, RedirectResult.Url, etc.). Further casting may be required.

An example of a simple action to take a first name and last name and create a new contact via an IContactService might be:

// The code
public class ContactController: Controller 
{
    IContactService _contactService;
    public ContactController(IContactService contactService) 
    {
        _contactService = contactService;
    }

    [AcceptVerbs(HttpVerb.Post)]
    public ActionResult Create(string firstName, string lastName)
    {
        var contact = _contactService.Create(firstName, lastName);
        return Redirect("/contact/show/" + contact.Id);
    }
}

// The test
[TestFixture]
public class ContactControllerFixture
{
    [Test]
    public void Create_ValidFirstNameAndLastName_CreatesAndRedirects()
    {
        // Arrange
        const int id = 21;
        const string firstName = "Aaron";
        const string lastName = "Janes";
        var contactService = MockRepository.GenerateStub();
        var contact = new Contact {
                                     Id = id, 
                                     FirstName = firstName, 
                                     LastName = lastName
                                  };
        contactService.Stub(x=>x.Create(firstName, lastName)).Return(contact);

        // Act
        var controller = new ContactController(contactService);
        var result = controller.Create(firstName, lastName);

        // Assert
        Assert.That(result, Is.Not.Null);
        Assert.That(result, Is.TypeOf(typeof(ViewResult)));
        
        var redirectResult = (RedirectResult)result;
        Assert.That(redirect.Url, Is.EqualTo("/contact/show/" + id);
    }
}

This test would verify that when the 'Create' method is called, the contact service's 'Create' method was also called with the received name parameters and that a view result was created using the resulting contact as the model. What it does not verify is that IContactService.Create would actually create and save a contact. More tests are required for that. It's also worth noting that I opted for a straight RedirectResult instead of RedirectToAction as the latter can be a pain to test as blogged here and here.

Now compare Ruby on Rails:

# The code
class ContactsController < ApplicationController
    def create
       @contact = Contact.new(params[:contact])
       if @contact.save
          flash[:notice]='Contact was successfully created.'
       else
           render :action=>'new'
       end
    end
end

# The test
class ContactsControllerTest < ActionController::TestCase
  test "create successfully saves contact" do
    first_name = 'Aaron'
    last_name = 'Janes'
    assert_difference('Contact.count') do
      post :create, :contact=>{:first_name=>first_name, :last_name=>last_name}
    end

    assert_equal first_name, assigns(:contact).first_name
    assert_equal last_name, assigns(:contact).last_name
    assert_equal "Contact created successfully.", flash[:notice]
    assert_redirected_to contact_path(assigns(:contact))
  end
end

The first difference is the conciseness of the Ruby code. This is always touted by Ruby enthusiasts as a big boon. While the brevity is nice, it isn't the biggest advantage, in my opinion. The real advantage is that the short Ruby code is actually testing so much more than the .NET test:

  1. The test verifies that the created contact is actually saved
  2. It asserts that the correct notification method is displayed on the resulting page (without a web-test!)
  3. It verifies that the path which is redirected to is the correct path for showing that particular venue

This is all possible because testing is in-built as a fundamental part of RoR. Access to the request, response and session are all available. For each test a super fast database of known data is created and destroyed allowing you to test database operations. The known data is easily created using a light weight syntax called YAML (another blog post in its own right is needed for this super feature). All this right out of the box with no extra coding.

One of the reasons why I'm (finally) starting to love Ruby on Rails.

Saturday 30 January 2010

Lambda Basics

Lambda expressions arrived in .NET 3.5. If you've never come across them they might seem a little confusing at first, but in reality they are really just a convenient shorthand way of expressing anonymous methods (an anonymous method is just a method that has no name and is only available in the local scope). In order to thoroughly explain how to use lambda expressions I'm going to follow several steps, starting with concepts that most .NET developers will be familiar with and progressing logically to less familiar ones. The steps are:

  1. Delegates
  2. Anonymous delegates/methods
  3. Lambda expressions
  4. No parameter and multi-parameter lambdas

Delegates

Hopefully you are familiar with delegates, but just a little re-cap. A delegate assigns a name (type) to a method signature which can then be used to assign or pass a method with a matching signature that can the be executed. Let's take a look at a real world example in the MatchEvaluator delegate. The MatchEvaluator (System.Text.RegularExpressions namespace), is defined like this:

public delegate string MatchEvaluator(Match match);

This simply says that the type MatchEvaluator must be a method that takes a Match object as the sole parameter and returns a string. It can be used to perform complex replacements with regular expressions, say for example, if we wanted a simple utility class which would truncate all integers greater than three digits in a string, we could do this:

public class Truncator
{
    private Regex _longIntRegex = new Regex(@"\d{4,}"); // Find four or more digits.

    public string Truncate(string input)
    {
        return _longIntRegex.Replace(input, new MatchEvaluator(TruncateDigits));
    }

    private string TruncateDigits(Match match)
    {
        // Truncate the string to three characters.
        return match.Groups[0].Value.Substring(0, 3); 
    }
}  

This should be straight forward to understand. The Regex takes a new instance of the delegate with the TruncateDigits method specified as the one to execute to perform the replacement.

Anonymous delegates/methods

The previous example could be modified to remove the need for the named method TruncateDigits by employing an anonyomous delegate, like this:

public class AnonymouTruncator
{
    private Regex _longIntRegex = new Regex(@"\d{4,}"); // Find four or more digits

    public string Truncate(string input)
    {
        return _longIntRegex.Replace(input, 
          new MatchEvaluator(delegate(Match match)
          {
             // Truncate the string to three characters.
             return match.Groups[0].Value.Substring(0, 3);
          }));
    }
}

Using the anonymous delegate, the required code is contained in a 'method' without a name whose signature matches the delegate as seen by the lone incoming Match parameter. It's worth noting that with anonymous delegates, a return type does not need to be specified but is determined by the delegate type (MatchEvaluator).

Lambda expressions

Through lambda expressions, this syntax can be abbreviated even further. With lambdas, not only is the return type inferred from the delegate type, but the paramters types are also inferred, requiring only the declaration of the paramter name, like so:

public class LambdaTruncator
{
    private Regex _longIntRegex = new Regex(@"\d{4,}"); // Find four or more digits

    public string Truncate(string input)
    {
        return _longIntRegex.Replace(input, 
          new MatchEvaluator(match => match.Groups[0].Value.Substring(0, 3)));
    }
}

Here, the name of the parameter is specified to the left of the => and the method body is specified to the right. Not only is the return type implicit, the keyword return is also implicit. If the delegate signature is not void we can assume that a return will take place and that the method body is required to return the correct value (match => false is invalid because the delegate requires a string to be returned, not a bool).

No parameter and multi-parameter lambdas

Lambdas can also be defined for parameterless delegates and delegates with multiple parameters. For anyone familiar with Test Driven Development with NUnit, version 2.5 introduces a new assertion for verifying that exceptions are thrown which can be expressed using a parameterless lambda.

Assert.Throws<ArgumentException>(() => throw new ArgumentException());

This example would pass as NUnit is expecting an exception and our lambda expression willingly obliges. Due to requiring no parameters, the left hand side of the expression is declared simply as (), while the right once again defines the method body on a single line.

Multiple parameters are specified in a similar way with the comma separated names of both parameters in brackets to the left hand side:

(firstParam, secondParam) => // Method body

Monday 11 January 2010

Never resize images again. Just Imagi.es!

As a web designer/developer I've spent plenty of time in Photoshop and a good portion of that has been spent flattening and resizing images. This is especially true on ecommerce sites where typically each image typically needs two or three sizes. Well, save time resizing by using Imagi.es . Simply upload your high resolution image and then, in your website image, specify the size you want in the image src attribute. Presto, auto resizing on the fly. I say on the fly, but thanks to its clever caching mechnism, after the first request, serving images is just as performant as simply having the image in the images directory.

Multiple formats including JPG, PNG and PSD are supported as well as on the fly conversion between formats. This means you can actually upload your photoshop file and request it back as JPG. No need to save for web any more.

Once you've uploaded you hi-res images, you just link to them like this:

<img src="http://imagi.es/company/Project/100/0/image_name.jpg" />

Change the 100 to 200 and you've doubled your image size. Change .jpg to .png and you've got a new format. Simple.

Another great use for this service is brand management. How many companies refer take a copy of your logo for press releases or blogs? When you update your logo, will they update thier content? I'd imagine not very quickly. With imagi.es you can encourage other sites to use the imagi.es link and then, when you change your logo, they automatically get the latest and greatest. With their cleverly chosen domain name your image URLs don't look so far from your typical '/images/' URLs anyway so your brand is not effected.

Registration is free and a limited capacity provided with the free account, so what are you waiting for?! Give it a try!