Monday, March 28, 2011

IT Celebrity Deathmatch?

Apparently James Gosling joined Google today, and with Anders Hejlsberg at Microsoft, I was reminded of this old claymation show for some reason.  Hmmm...

Saturday, March 26, 2011

Firefox 4... a major disappointment

Battleship grey, and a bit uninspiring
I've been a user of Mozilla's Firefox since it was first called Phoenix, then Firebird.  It's been an amazing web browser, but something has happened with this latest release of Firefox and I fear the magic has gone.  Google's release of its browser Chrome appears to have shaken things up at Mozilla, and the result is that Firefox 4 has become a cheap knock-off playing catch-up instead of the innovative leader.  Much like all the wanna-be iPads, Firefox has decided it wants to be Chrome and fails to distinguish itself.

I was part of the beta test group that used Firefox 4, and I used it on both my PC and my Mac.  The deeper into the beta testing, the worse it got.  Consider the initial look - it's really, really ugly.  The tabs are uninspiring compared to Chrome, and the battleship grey on the Mac makes me throw up a little in my mouth.  Googling for "Firefox fonts look bad" turns up a whole host of people who noticed too.  It looks pretty bad, and the solution appears to be messing around with settings in the about:config.

Another oddity is that the download size has also more than tripled.  The last version of the 3.x series was just over 8MB.  The 4.x series comes in at a whopping 28MB.  Not huge by today's standards, but certainly noteworthy in it's stark contrast from the previous trim-and-slim size.  Firefox 4 has put on some sizable love handles, without much to show for it.

The one new feature that appears to be somewhat innovative is the "tab groups".  This is sort of a task manager for your browser windows.  It seems neat at first, but it winds up being a solution in search of a problem.   Other than an initial time playing around, I've never felt the need to use this feature.  I find that when I get too many tabs, I just open a new browser window.  Then, you can actually drag tabs from one browser session to another.  Problem solved without this "tab groups" thing.  It seems like a lot of wasted development, which may have been part of why the download is so big and the final release was delayed so long.  Tab groups would have been better suited to a plug-in than a bloated browser feature.

What's most notable to me about Firefox 4 isn't so much what's in it, but what's missing.  The orange RSS feed button that showed in your URL bar when a site you visited had a feed is sadly gone.  It's replaced with a hidden toolbar button, much like the bookmarks button that you have to find in the toolbar customization dialog.  However, it's really difficult to tell when the button is lit up indicating an available feed, so it's just not nearly as nice as the original.  Mozilla got this feature right a long time ago before any of the other browsers did, and then they threw it all away.

The other head-scratcher is that they ditched the status bar, which is the bar that sits at the bottom of your screen and tells you what site you're about to go to when you hover over a link.  This move was presumably to mimic Chrome and regain some screen real estate for page content.  The trouble is, Mozilla also had this one right too and blew it.  Chrome lets its plugins take up precious space in the primary menu bar, whereas many Firefox plugins like Grease Monkey and Add Block Plus sit out of the way on the status bar.  So great is the love of the status bar, that there is a plugin called Status-4-Evar that brings it back which has over 100,000 downloads already.

As far as quick, stable and functional, Firefox 4 does well here.  But frankly, that's to be expected from a browser that isn't Internet Explorer.  But much the same way the only thing John Kerry had going for him was that he wasn't George W. Bush, I'm not sure that just being better than Internet Explorer is going to work out for Firefox in the long run.  And I'm not convinced they're that much better than IE anymore... with IE9 now clearly the best browser ever to come from Microsoft, as well as Chrome being the best browser available today, Firefox is going to have to step up its game.  They need to quit pulling features that work and people love, quit trying to be Chrome and doing it badly, and quit coming up with complicated solutions to simple problems in an effort to look innovative.

Sunday, March 20, 2011

Amazon Prime and our giant Sasquatch-sized carbon footprint

We recently tried Amazon Prime free for a month on the recommendation of a friend. Amazon Prime is a service Amazon.com offers where you get free two-day shipping on most everything you order directly from Amazon. The service runs $79 a year, but the idea is that with free shipping and frequent orders, enhanced customer service and saved trips out, it'll pay for itself quickly.

Let's say you keep a list of items you need from the store on your next trip.  With Amazon Prime, in theory, instead of keeping that list you could order the item from Amazon and it would probably arrive at your house before you made that next trip to the store(s).  If you used it that way, it would change the way you shopped.  And that was the way we tried to use it - as a way to order anything we thought we would have picked up on our next trip out.  The kids wanted to spend allowance on Nerf guns, so we did the research online and ordered in our PJs.  I wanted to get Beth a nice necklace for her birthday.  We knew we needed a baby gate and some odds-and-ends for Alison.  Whenever we thought of something we 'needed', we ordered it.

Of course, there were things that didn't qualify for the free 2-day shipping because Amazon wasn't the supplier, but just a storefront for someone else.  And there were things that weren't cheaper on Amazon, even with the free shipping.  And there was the knowledge that Amazon doesn't do sales tax, so I'd have to keep track of it for filing my state taxes next April.  And things like baby food had to be bought in bulk because you can't get that stuff in small packages online.  And every review was begging to be read for every purchase because there were there, and somehow random people on the internet started to have some say in what I bought.  The UPS guy started having conversations with me like we were old friends.  I was making two trips a week to the recycling drop-off to account for all the extra boxes.  And it wasn't just the boxes and deliveries started to add up - so did the credit card bill.  Not too bad, but certainly not typical.

And after a month of watching this occur, it became obvious to us what we were sacrificing so that we didn't have to plan for or think about our purchases.  What was the real cost of this convenience - in manpower, in shipping and handling, packaging, fuel, and ultimately to our expectations?  How had our attitude toward planning and budgeting and smart shopping changed?  How had our strong beliefs in living simply, spending wisely, budgeting effectively, and being good stewards of our world held up?  I wasn't sure I liked those answers, and so we happily let our month-long trial expire.

Saturday, March 19, 2011

Fun with DynamicObject and making .NET reflection less painful

If you're a Microsoft techie, you probably noticed that RC1 of Entity Framework 4.1 was released this week.  One of the things I've been waiting for with EF is the ability to run cross database queries on the same server - for example, being able to join MyDB.dbo.MyTable to YourDB.dbo.YourTable when MyDB and YourDB are SQL Server databases on the same server.  It's crazy that MS hasn't added this feature yet, since they seem to want to speed up EF adoption and since Linq-to-SQL does this perfectly.  But, I don't want to actually talk about this... this isn't what this post is about.  This issue is what started me on a different track.

You see, I wondered if there was a way to hack this functionality in by examining the EF code using Red Gate's Reflector tool.  As I examined the guts of EF, the parts that mattered were buried deep in the code - internal objects and private properties and methods.  Figuring out the code seemed like it would be way easier if I could examine the guts and change parts at run-time (I haven't figured this out by the way, so if you're here hoping I cracked this nut, you need to go back to Microsoft and the EF team and complain to them).  In order to really examine the code though, I'd need to use reflection and call methods and properties of private areas of the code, which is always a painful experience.  And that's when I turned to the new dynamic features of C#, and is the topic of this post.

If you don't know about the dynamic keyword in C#, it's purpose is to remove the compile time type safety on a variable.  If a variable is declared dynamic, you can call properties and methods on the variable and those calls aren't handled until run-time.  Those properties and methods may not exist, but you can intercept those calls and do some magic with them, like dynamically adding those properties or methods to the object.  See this stackoverflow question here and my answer to get some idea of how this works.  This sort of thing is nothing new for users of dynamic languages like Ruby, but for compile time checked languages, this is a really nice advancement.

So, all that to say, I decided to experiment with the dynamic features to provide a much simpler way of accessing private and protected aspects of a class at run-time.  I've code named this project "LookingGlass" as a play on reflection.  Here's a sample:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Dynamic;
using System.Reflection;

public class LookingGlass : DynamicObject {
 public dynamic TheObject { get; private set; }
 public Type TheObjectType;

 public LookingGlass(dynamic theObject) {
  this.TheObject = theObject;
  this.TheObjectType = this.TheObject.GetType();
 }

 public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result) {
  result = null;
  int index = (int)indexes[0];
  var value = this.TheObject[index];
  result = new LookingGlass(value);
  return true;
 }

 public override bool TryGetMember(GetMemberBinder binder, out object result) {
  result = null;

  var field = GetField(binder.Name);
  if (field != null) {
   var value = field.GetValue(this.TheObject);
   result = new LookingGlass(value);
   return true;
  }

  var prop = GetProperty(binder.Name);
  if (prop != null) {
   var value = prop.GetValue(this.TheObject, null);
   result = new LookingGlass(value);
   return true;
  }
   
  return false;
 }

 public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result) {
  result = null;
  var flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod;
  var value = this.TheObjectType.InvokeMember(binder.Name, flags, Type.DefaultBinder, this.TheObject, args);
  if (value != null) {
   result = new LookingGlass(value);
  }
  return true;
 }

 private FieldInfo GetField(string fieldName) {
  var flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
  var field = this.TheObjectType.GetField(fieldName, flags);
  return field;
 }

 private PropertyInfo GetProperty(string propertyName) {
  var flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
  var prop = this.TheObjectType.GetProperty(propertyName, flags);
  return prop;
 }

 public override string ToString() {
  return this.TheObject.ToString();
 }
}

Obviously, this is quite a lot to take in, but the gist of this is that this lets you open up any object as if it's private fields, methods, and properties were all public.  It's not exactly fast, nor was it designed to be robust if the thing you're calling isn't part of that object, but this solved my immediate need of inspecting some of the Entity Framework guts at run time.  To use this, make yourself a class called Test() and put some private fields, methods, or properties on it and then call it like this:

var tst = new Test();
dynamic totallyOpenObj = new LookingGlass(tst);
Console.WriteLine(totallyOpenObj._privateField);
Console.WriteLine(totallyOpenObj.InternalMethod("asdf"));
Console.WriteLine(totallyOpenObj.PrivateProp.PrvProp2[10]);

You can also chain calls as each object returned is a new dynamic LookingGlass object that lets you explore it as well.  It handles overloaded methods and indexers too.  If you'd like to change the objects you're interrogating, DynamicObject lets you override TrySetMember and TrySetIndex and their ilk.  Hope this gives you some ideas on where you can go with the new dynamic features in C#.  This opens up a whole new world of possibilities for C# devs.  Happy coding!

Thursday, March 3, 2011

Poetry

The fun things you find when digging through old hard drives... here are some poems I've run across from a very long time ago when I actually had time to write poetry...

Leaving...
“better to leave when you don’t want to”
She Says
but that kind of absence appeals only to the tortured
or to hermits
of which I am neither

but the idea seems so intriguing
That I Am
forced to consider
that maybe friends ought to try harder
to leave before they want to

if it means that
Her Very
last thoughts
were not wanting to leave
‘cause those thoughts were mine too

Best Friend


Mind you, I'm not saying these are necessarily any good...

Spork…

Why? What is the point
in the sharing of joints
between two things that we eat with.
Why did they do it?
Who could construe it?
Did they think that it was a gift?

I wonder the maker.
a Monk or a Quaker
in some lab somewhere out there.
He’s crazy and old,
or bitter and cold
with some wild, freaky white hair.

I can picture the place
and the look on his face
when he came up with this “plan.”
I can see the light
as his face got bright
and he asked his friend for a hand.

They glued those utensils
like erasers and pencils
And stared again and again.
This monster’s to lewd
to use on your food
Stabbing with Siamese twins.

But they proceeded to patent
I wish that they hadn’t
subjected the world to this tool.
It’s called a spork,
it’s neither a spoon nor a fork
and to eat with it you look like a fool.

And now that I've weeded out the riff-raff with the last two, I'll share two more I really like with those who made it this far... This one reminds me of holding Alison...

Memory
A thousand kisses just aren't enough
to hold the memory of her touch
and millions more would not begin
to grasp the softness of her skin
Those big blue eyes and thoughtful gaze
float off, into her sleepy daze
And there upon my arm she sleeps
Moments fleeting I yearn to keep

And this one, which always makes me want to write again, and shows my appreciation for a really fine pen...
mightier than…
a green pen’s liquid
random, scribbled ink
Bleeding chlorophyll
breeding as it flows
Planted by the silky hands of an angel
an angel loved by mere primates
primates who’s hands could never hope
to leak such beauty
As the soundless words.
like the blood of The Savior
An angel with actions so fluid
that the seeds on the paper never thirst
Motion so liquid that one cannot help
but to thirst, to drink, to sip
to tenderly, gingerly, lift to the mouth
But by lifting the pen
the life flowing must cease
and leave the plants thirsty
begging for more