Thursday, September 24, 2009

Blog has moved

I have moved my blog to a new host, and there are a number of added and updated posts. I apologize for not making this post sooner. Please go to http://innovatian.com/blog for all of my new posts.

Sunday, December 28, 2008

Ruby First Impressions

I decided to try out Ruby today. I have wanted to try it out for quite a while. Some of my impressions may be inaccurate, but I have done what I can. I have Zero interest in DB and web ‘programming’ so I am going to skip rails and related material.

I tried to use JetBrains’ RubyMine, but I couldn’t get anything to run. I know it is a public preview, but for the time I am willing to put into Ruby, there was just too much friction for now. I look forward to trying out the full product when it is RTM.

I installed Ruby In Steel Personal Edition and that was a great way to get started. I ran the installers and I was up and running in a familiar environment. I created a Ruby project and I started with hello world. After that I started going through the guide at Techtopia and the RDocs. I love the product for a free version, but for someone trying to learn Ruby, the intellisence feature would be handy. I am never going to pay $200 for an IDE that I would use as a hobby; that being said, if I ever were to program Ruby as a job, $200 is a great price.

What I like

  • very straightforward language
    • I loved that when I wanted to shift the elements of an array I found it was built-in
  • Class library
  • being able to have a line of code like this; I wish I knew what to call it
    • return SolveUsingClosedFormExpression( n ) if ( 0..1474 ).include? n
    • return SolveUsingClosedFormExpression( n ) if (0..1474) === n
  • I will complain about this as well, but in writing the closed form Fibonacci solution, the data type changes allowing for huge results
    • def SolveUsingClosedFormExpression(n)
          left = GOLDENRATIO ** n
          right = (-GOLDENRATIOINV) ** n
          return ( (left - right) / ROOT5 ).to_i
      end

What I didn’t like

  • Trying to figure out how to use gems (packages, not the tool) and files in the class library
  • Lack of type information
    • Yes, yes, I know, I know, but for a c, c++/cli, c#  programmer, it feels just wrong
    • Declaring a variable feels like I am introducing a magic variable - *poof* it exists. At least in TI-Basic I had to declare my dynamically typed variables. \
    • Lack of method return types
  • At least four ways to return a value from a method, see below.
  • Inconsistent API
    • I was very frustrated when trying to use .power! only to find that it isn’t defined for Float types – I have to use ** everywhere.
  • Ruby is supposed to be super OO, but what object contains puts/print?

What I really didn’t like



def multiplyWithReturn(val1, val2 )
result = val1 * val2
return result
end

def
multiplyLocalVariable(val1, val2 )
result = val1 * val2
end

def
multiplyNoVariables(val1, val2 )
val1 * val2
end

def
multiplyAssignToMethodName(val1, val2 )
multiplyAssignToMethodName = val1 * val2
end

puts multiplyWithReturn(5,6)
puts multiplyLocalVariable(5,6)
puts multiplyNoVariables(5,6)
puts multiplyAssignToMethodName(5,6)



Running this code prints








30
30
30
30



I don’t know if I am missing a key ‘feature’ of the language, but at least four ways to return a value from a method just really irks me. Given that there is no return type of a method, reading code to determine what is returning a value and what methods are void seems ridiculous.



I have never programmed in a dynamic language, so it has been a bit of a ride. There a so many nuances to the language, it will take a while to get them down, but they allow for very concise code.

Monday, December 15, 2008

Continuous Build Systems

I have gone through so many tools trying to create the right build environment that it is a bit disheartening. I have set up multiple continuous integration systems and it keeps getting easier, but there is still a bit too much friction.

I tried to look into using Team Foundation Server and Team Build, but the cost is very high for a startup (even with the top msdn subscription). This is compounded when you have external developers that must also hook into the system.

I have fallen for TeamCity but with one deal breaker for me: no FinalBuilder support. I submitted some feedback and I received a detailed response from JetBrains; I have always received great customer support from JetBrains:

There are several ways to support FinalBuilder:
1. You may start using CommandLine runner to start the process.
2. To Add custom FinalBuilder reporting you may use TeamCity service messages.
   Please refer to
http://www.jetbrains.net/confluence/display/TCD4/Build+Script+Interaction+with+TeamCity
   documentation article on service messages for details
3. You may start FinalBuilder from any other build scripts,
   for example NAnt, MSBuild, Ant, Maven.
   If  you  need  custom  logging,  you  may  consider using TeamCity
   Service messages as well
4. Write a build runner plugin for TeamCity. There are two
   public available examples on the build runners at:
http://www.jetbrains.net/confluence/display/TW/Rake+Runner
   and
http://svn.jetbrains.org/teamcity/plugins/fxcop/
   Please feel free asking any questions on the integration.
5. Post an issue to our tracker at
   http://www.jetbrains.net/tracker

I checked out the code for the build runner plugins, but it is too much work. It is hard not to sound lazy in saying that, but I haven’t used java since my sophomore  year in college, and it doesn’t sit high on my list to spend hours getting a build runner going (I am looking for less friction, not more). I chose the 5th option and submitted a feature request TW-6442. With FinalBuilder support I don’t need any other build runners/tools as FinalBuilder most likely wraps them up in its UI.

One other feature that I would like to have, but am hesitant to request right now, is to be able to selected a successful build, and run a publish script (through the web interface (see Cruise)) that can tag the build and use the build  artifacts to deploy that build to Dev/Stage/Production environment.

Saturday, November 29, 2008

Ninject MessageBroker Update

It has been a long time (10 months) since I worked with the Ninject MessageBroker and a couple things have changed since my last post. In the old version you had to connect the MessageBroker as a kernel component by hand. Since then the extension environment has been flushed out a lot more. Now you can register the MessageBrokerModule when constructing your kernel object.



using System;
using System.Diagnostics;
using System.Net;
using System.Text.RegularExpressions;
using Ninject.Core;
using Ninject.Extensions.MessageBroker;

namespace NinjectMessageBroker
{
internal class Program
{
private static void Main()
{
// Intialize our injection kernel adding message broker functionality.
using (var kernel = new StandardKernel(new[] { new MessageBrokerModule() }))
{
// Get the event publisher. It reads the current time and fires an event
var pub = kernel.Get<TimeReader>();
Debug.Assert(pub != null);

// Get the subscriber, it waits to get the current time and writes it to stdout
var sub = kernel.Get<TimeWriter>();
Debug.Assert(sub != null);

// Verify that they were wired together
Debug.Assert(pub.HasListeners);
Debug.Assert(sub.LastMessage == null);

// Get the current time. It should automatically let the TimeWriter know
// without either of them ever knowing of one another.
pub.GetCurrentTime();

// Wait to exit.
Console.ReadLine();
}
}
}

internal class TimeWriter
{
public string LastMessage { get; set; }

[
Subscribe("message://Time/MessageReceived")]
public void OnMessageReceived(object sender, EventArgs<string> args)
{
LastMessage = args.EventData;
Console.WriteLine(LastMessage);
}
}

internal class TimeReader
{
public bool HasListeners
{
get { return (MessageReceived != null); }
}

[
Publish("message://Time/MessageReceived")]
public event EventHandler<EventArgs<string>> MessageReceived;

/// <summary>
///
Gets the current time and updates all subscribers.
/// </summary>
public virtual void GetCurrentTime()
{
string text = GetWebPage();
var regex = new Regex(@"\d\d:\d\d:\d\d");
MatchCollection matches = regex.Matches(text);
string time = ((matches.Count == 2) ? matches[1] : matches[0]).Value;
SendMessage(time);
}

/// <summary>
///
Gets the contents of a web page as a string.
/// </summary>
/// <returns></returns>
private static string GetWebPage()
{
const string url = "http://www.time.gov/timezone.cgi?Eastern/d/-5";
var webClient = new WebClient();
return webClient.DownloadString(url);
}

/// <summary>
///
Sends the message to all subscribers in a threadsafe manner.
/// </summary>
/// <param name=
"message">The message.</param>
public void SendMessage(string message)
{
EventHandler<EventArgs<string>> messageReceived = MessageReceived;

if (messageReceived != null)
{
messageReceived(this, new EventArgs<string>(message));
}
}
}

public class EventArgs<TData> : EventArgs
{
public new static readonly EventArgs<TData> Empty;

static EventArgs()
{
Empty = new EventArgs<TData>();
}

private EventArgs()
{
}

public EventArgs(TData eventData)
{
EventData = eventData;
}

public TData EventData { get; private set; }
}
}

Friday, November 28, 2008

C++ if statement oddity

I found that you can do work such as assigning a variable and executing a method outside of the main expression of an if statement. For example:



    if(hRes = GetApplicationState(), NT_SUCCESS(hRes))
{
// Do something
}



Yes, that is a comma inside of the if statement. To the left of the comma is executed first and then the if statement uses the right side as its evaluation expression.

Open Source Projects

I had two open source projects: Ensurance, and IMAPI.Net.

  • Ensurance did not really fit into any particular group. It was a tool for me while Spec# was still a research project at MS. I wanted to be able to use pre/post conditions, parameter constraints, and tie them into logging and debugging. I don’t think that Spec# will do the last bit, but I am really looking forward to its release.
  • IMAPI.Net is a C# cd authoring library that wraps the IMAPI system in windows to allow programmers of any application to write to CD. It supports data and audio discs. It was expensive to test the library and the COM issues were a huge problem for a while.
    • PInvoke.net was a good help for the most part, but the marshalling took a long time to get right. I started the project back in .net 1.1 while working on my BS - and it worked. With each .NET release the project would have been easier to write with the COM interop support increasing. I used to be the lead of the XPBurn component project on GotDotNet before it shut down; in truth though, I had stopped supporting it a couple months before that. No one would read directions, read the forum, follow any kind of guidelines and would essentially expect me to figure out why they are using the code wrong. It became too much hassle in the end for what I got out of the project. It was a great learning experience though.

Both projects are essentially dead and I will be closing down the Ensurance  project on CodePlex. I will leave IMAPI.Net up on google code in case anyone ever finds use for the code. If I get the time I will try to add my PInvoke code to the wiki so others don’t have to work as hard as I did.

Friday, June 13, 2008

Yet Another Video Update (YAVU)

Here is the latest PLAYXPERT video demo. While playing the game the user:

  • Starts playing a song.
  • Searches the web for a video.
    • Web browser
    • AJAX
    • FLASH
  • Opens the Friends widget and initiates an IM session
  • Continues playing the game the whole time.

STAY IN GAME!

Friday, May 2, 2008

PLAYXPERT in Action

Although this blog is in no way associated with my employer, I feel I need to post this. It is a video of PLAYXPERT running in game. For many years I had wished there was a product like this, and now I get to be part of the team that brings it to life :)

Wednesday, January 16, 2008

Ninject Message Broker

I updated my local copy of Ninject today and decided to try out the message broker. I opened the test fixture to see how it is used and wrote up this little test.  Overall I am very happy with how this simple demo worked out. I am going to try to set aside some time to try something more in depth. This simple example has one object getting the current time from the Internet and then publishes the new time it received. The second object listens for the time to be updated and then writes it to the console. What I really dig is that the two objects never know of one another.

 

internal class Program
{
private static IKernel _kernel;

private static void Main(string[] args)
{
// Intialize our injection kernel
_kernel = new StandardKernel();

// Add message broker functionality.
_kernel.Connect<IMessageBroker>(new StandardMessageBroker());

// Get the event publisher. It reads the current time and fires an event
TimeReader pub = _kernel.Get<TimeReader>();
Debug.Assert(pub != null);

// Get the subscriber, it waits to get the current time and writes it to stdout
TimeWriter sub = _kernel.Get<TimeWriter>();
Debug.Assert(sub != null);

// Verify that they were wired together
Debug.Assert(pub.HasListeners);
Debug.Assert(sub.LastMessage == null);

// Get the current time. It should automatically let the TimeWriter know
// without either of them ever knowing of one another.
pub.GetCurrentTime();

// Wait to exit.
Console.ReadLine();
}
}

internal class TimeWriter
{
private string _lastMessage;

public string LastMessage
{
get { return _lastMessage; }
set { _lastMessage = value; }
}

[Subscribe("message://Time/MessageReceived")]
public void OnMessageReceived(object sender, EventArgs<string> args)
{
_lastMessage = args.EventData;
Console.WriteLine(_lastMessage);
}
}

internal class TimeReader
{
public bool HasListeners
{
get { return (MessageReceived != null); }
}

[Publish("message://Time/MessageReceived")]
public event EventHandler<EventArgs<string>> MessageReceived;


/// <summary>
/// Gets the current time and updates all subscribers.
/// </summary>
public virtual void GetCurrentTime()
{
string text = GetWebPage();
Regex regex = new Regex(@"<b>\d\d:\d\d:\d\d<br>");
Match match = regex.Match(text);
string time = match.Value.TrimStart("<b>".ToCharArray()).TrimEnd("<br>".ToCharArray());
SendMessage(time);
}

/// <summary>
/// Gets the contents of a web page as a string.
/// </summary>
/// <returns></returns>
private static string GetWebPage()
{
string url = "http://www.time.gov/timezone.cgi?Eastern/d/-5";
HttpWebRequest webRequest = WebRequest.Create(url) as HttpWebRequest;
webRequest.Method = "GET";
using (WebResponse webResponse = webRequest.GetResponse())
{
using (StreamReader sr = new StreamReader(webResponse.GetResponseStream(), Encoding.UTF8))
{
return sr.ReadToEnd();
}
}
}

/// <summary>
/// Sends the message to all subscribers in a threadsafe manner.
/// </summary>
/// <param name="message">The message.</param>
public void SendMessage(string message)
{
EventHandler<EventArgs<string>> messageReceived = MessageReceived;

if (messageReceived != null)
{
messageReceived(this, new EventArgs<string>(message));
}
}
}

Tuesday, December 11, 2007

Visual Studio 2008 InstallFest

I will be attending the Visual Studio 2008 InstallFest in Spokane Valley on Wednesday the 12th with a few other deve lopers from PLAYXPERT. It will be nice to meet some other .NET coders in the Spokane area. Hopefully we can pick something up soon (better SIGS). I was really looking forward to attending the Agile Philly and Philly ALT.NET group meetings before the move to Spokane.