Life: The Soundtrack

Monday, February 28, 2005

Titty-Bar Studies

Track/Stream: Jack Johnson - Bubble Toes

So one of my friends (who would probably rather remain nameless) is in a massive funk today. I'm not talking funky, just in a funk. So we're going to the Flatiron Lounge for drinks and conversation. Personally, I don't think this is the best idea. I think the guy needs to go to a titty-bar, but he isn't interested (which, of course, is the number one sign that you need to go to a titty-bar).

This prompted a discussion with another friend (who would also rather remain nameless, but it was Chris) claiming that it is titty-bar season (when isn't it titty-bar season?) and that we should visit one.

Of course you don't want to go to a titty-bar when all the other perverts are there. For that reason, we propose a government grant for us to investigate which days are ideal for visiting titty-bars in various parts of the city. We figure we can do a complete study with a grant of about $25,000........ in singles.

Anyway, we figure we'll get some preliminary research in, starting early next week (we expect Monday, Tuesday and Wednesday to be ideal) to give our grant proposal some extra heft.

0 Comments:

Post a Comment | Hide

Space, Time, and Dimension

Track/Stream: Lustra - Scotty Doesn't Know

I was actually excited to come into work this morning. I don't know what madness came over me. I should have known that the feeling would pass.

I was blissful for about half an hour. Then Carl came by to remind me that I have bugs. Then Mike came by to tell me I have new bugs. I hate bugs. I really really hate bugs. These are especially annoying bugs. Like you start streaming data to the system, bring it down, then bring it back up and some of that data is lost.

It didn't take long to find the cause of most of the problems, but I'm really tired of the attitude of people who tell me to fix them. For some reason they assume that it's easy to do.


Conversation #1

Them:Just don't do this until that is done.
Me: That's all fine and good but what happens if that never gets done
Them: Well, under normal conditions it will get done
Me: We're already talking about boundary conditions that are never likely to occur. If I have to think about your boundaries, you have to think about mine
Them: Well, then just put a timeout on it
Me: How long?
Them: 2 minutes?
Me: It usually takes 3, and if there's network congestion it can take 5
Them: Then make it 10 minutes
Me: So if there's a timeout I won't respond until it times out
Them: Oh no, you can't wait 10 minutes to respond. You have to respond right away. Otherwise it's like their data is going into a black hole
Me: So you want me to let them know right away if the operation is going to time out?
Them: Yes
Me: Ummmmm, I'm going to need a little more time, budget and manpower to bend the rules of space, time, and dimension!!!!


Conversation #2

Them: I'm not getting any response to my data
Me: The service isn't running
Them: So?
Me: I can't respond when my code isn't running
Them: Well, can't you just send back rejections
Me: Not when my code isn't running
Them: This is a serious issue, we can't just not respond to data
Me: Beats his keyboard against his head


I really am beginning to hate my job.

0 Comments:

Post a Comment | Hide

Saturday, February 26, 2005

Lynda's Back

Track/Stream: Custom - Hey Mister

Lynda's cousin Brian bailed on picking her up from the airport, so I stepped in. I conveniently had taken the day off due to being sick (the trick, kids, is to dip your nose in a pan of water, then inhale sharply just before calling - this produces a nice runny nose sound along with a good phlegmy cough). So I ran a couple errands, like dropping laundry off, and got her car and picked her up.

I'm going to take a break here and extol the virtues of New York City laundromats. New York laundromats suck. Big time. The only good thing about them is that you don't have to be in them often. It usually costs me about $30 to do my laundry (when you factor in detergent, softener, dryer sheets, and a soda while I wait). It costs about $25 to have the laundromat do all your laundry for you and fold/hang it, and it's done in 6 hours. Plus you get the sadistic pleasure of knowing someone else has to clean your dirty underwear. Does life get any better?

So I got Lynda from JFK (she flew out of LaGuardia. Thank you, Delta, for that itinerary). We pretty much made out the entire car ride home. Almost rear-ended a few people, got honked at, all in all: fun. We get to her place and the following series events occur:

  • 4:40 pm - Arrive at Lynda's. Clean up cat's mess
  • 4:45 pm - Mess around
  • 5:45 pm - Make dinner
  • 6:05 pm - Eat dinner
  • 6:07 pm - Remove cat from dinner plate
  • 6:20 pm - Finish dinner
  • 6:21 pm - Mess around
  • 7:30 pm - Watch The Grudge (with Andrew too)
  • 7:35 pm - Bitch about how crappy The Grudge is
  • 8:30 pm - Pause The Grudge while Andrew answers the door
  • 8:35 pm - Stop making out, resume movie
  • 9:15 pm - Finish The Grudge, start watching Eurotrip
  • 10:00 pm - Finish Eurotrip, go to bed
  • 1:00 am - Go to sleep
  • 3:30 am - Get up to use restroom
  • 3:31 am - Step on cat's tail, wake Lynda up screaming because cat sounds exactly like creepy cat-boy-thing in The Grudge
  • 3:35 am - Go back to bed, lie awake, can't stop thinking about creepy cat-boy-thing
  • 5:00 am - Still awake
  • 6:00 am - Still awake
  • 6:45 am - Lynda wakes up
  • 7:45 am - Get out of bed, take shower
  • 8:30 am - Get out of shower
  • 8:50 am - Take Lynda to class
I need to pick her up in half an hour or so, maybe I'll try to take a nap.

0 Comments:

Post a Comment | Hide

Thursday, February 24, 2005

Easter Eggs

Track/Stream: Dido - Here With Me

On my last project I managed to sneak an easter egg in. It's nothing big, but if we receive a message with a specific field set to Kerrek it displays an image on a printout of a small dragon.

Phil just found out about the "feature" this morning. His first question was why I put it in. Carl and I just stared at him. He tried to clarify by asking if it had been because a customer requested the ability to put an image on the printout. Our eyes bug out and we keep staring at him. While he was trying to rephrase his question again I turned to Carl. Carl said maybe he doesn't know what an easter egg is. Phil insisted he knew, but again asked who had asked for the functionality.

I told him to pull up a browser and gave him the Elmer Fudd Google link to type in. I then asked him why Google had that page up. He said "because the programmers were bored?" After that he acted like he understood, but I still don't think so.

I mean, come on. Why did I put an easter egg in? Asking why a bored programmer puts easter eggs in is like asking The Pope why he's catholic, or why the sun sets in the west, or why half of the girls I've made out with have gone lesbian.

There is no "why." It's just a fact of life.

0 Comments:

Post a Comment | Hide

Donna's Rugrat

Track/Stream: Paul Van Dyk - Vega

Donna's little kid was running around the office yesterday. I think he's like 10. I don't know if we started hiring 10 year old programmers (they'd probably be better than most of the ones we already have) or it was Take Your Brat to Work day. Probably the latter.

So because I happen to have some of the more esoteric (and therefore attractive to small children) cube toys, he decided that I was his new best friend. This friendship went through several. First I ignored him. Then I neglected him. This was followed with a rapid succession of dismissing, disregarding, and evasion.

At that point I realized that I needed a new approach. I recognized that most of the office was still mimicking my earlier attempts and were still in various phases where the took no heed of his actions. So I had him start stealing me soda and water from various VP offices. I'm set for the next few weeks in all of my beverage needs.

After this his usefulness dwindled, but the problem remained. I decided the best defense was going to be a good offense. I tried to scare him off with knowledge, but that was fruitless. He just stared at me and nodded until I stopped talking and put my headphones back on. I think he kept staring and nodding. I'm not terribly sure.

Clearly the kid was not to be deterred. I soon realized I was misdirecting my offense. I could have just gone to his mother and ask that she keep her child in check, but that seemed rude. At this point the boy himself provided inspiration in the form of a plastic watergun he threatened to shoot me with. I simply explained to him that waterguns were for wimps. Real men fill their waterguns with ketchup.

So today when Donna was passing out paychecks, she refused to give me my envelope.

Pfffffttttt. I get direct deposit anyway.

1 Comments:

  • LOL that is one of the funniest posts I've read in a while...I especially like the way you set him to work pilfering soda.

    AMG
    http://www.anonymousmidwestgirl.com/

    Blogger Lara
    2:45 PM  

Post a Comment | Hide

Wednesday, February 23, 2005

Tired Evening

Track/Stream: Moby - Sky is Broken

I've been tired often lately. Monday night I crashed at 7.30 after a relatively quiet day. Last night I was ready to go down at 10.00, but stayed up watching TV until the jam session. Tonight it's not quite 10.00 and I'm ready to sleep again. Maybe it's because I have a cold. Maybe I just needed to catch up after the last few weeks of work.

There's also surprisingly little to do in my room aside from the computer. Part of that is due to the fact that I have 12 square feet of floor space. I've been trying to start reading Dr Jeckyll and Mr Hyde, but the first page is very dense and hard to get past. So instead I've been passing the time by resisting the urge to mess with Audrey and listening to music. I talked to Lynda briefly.

The only other thing that went on today is that I finally went up to Times Square and got Andy tickets to The Phantom of the Opera. She is a big fan and she and Jeremy are going to be out here next week. I promised them a wedding present, so now that's covered. The seats are decent, especially considering I bought them a week before the show.

0 Comments:

Post a Comment | Hide

Tuesday, February 22, 2005

Riffing

Track/Stream: Muddy Waters - Mannish Boy

So after my call to Lynda (still in Florida) this evening, my roommates decide to get stoned. We were going through some jazz and blues music and came across Mannish Boy by Muddy Waters (think of the blues riff in Bad To The Bone). They started talking about how awesome it would be to have that riff on infinite loop.

So I jumped on the net, pulled down some shitty mp3 of a cover band playing it in a club, and slapped a 40 minute audio file together of nothing but the opening beat. There really wasn't much that 3 white guys freestyling could do, but we gave it our best shot.

I recorded the whole thing on my mp3 player. I've got blackmail material which is going into a black hole until Zack (Josh too, but mostly Zack) decides to get married (cue evil laughter).

The best part was when they decided that we couldn't do the vocals, so Zack went looking for his harmonica, which none of us have ever played. Yeah.... right....

Best Riffs

So there's a bunch of pubes in the bathtub.
Whenever Josh takes a shower
He also uses your soap
And you see those pubes ev-er-y-where
I got the.... pubes-in-the-shower bluuuuuuuuuuues
- Zack
Sittin on my ass
Doin' shit
I looked at the TV
And then I saw some tits
I said... "love those titties, baby"
I got none
I got the no-titties blues
- Josh
Three dudes sittin around
One of the dudes starts fantasizng about the other two dudes
That one dude gets his ass like totally fuckin' beat
duh duh duh duh duh
- Zack
(about Josh)

Chick comes out Zack's room cryin'
I was all muddled
Asked Zack why she left
Said "Damn bitch wanted to cuddle"
- Paul

0 Comments:

Post a Comment | Hide

Monday, February 21, 2005

New York City Under Snow

Track/Stream: Smashing Pumpkins - Galapagos


(Southwest view from my roof)

I really like living in the city when it snows. There are a lot of reasons, but the primary ones are that it muffles the white noise of the city and it covers up the filth. I'm also looking forward to going up to see The Gates in Central Park. I was planning on going, but didn't think it would be that great with nothing but the dead foliage. I think the snow will make it a bit nicer (and keep away tourists).

So this morning, because of the snow last night, I headed up to the roof to take a couple pictures, then went to the grocery store for milk, eggs, and some fruit.

This mornin', we's havin' waffles.

0 Comments:

Post a Comment | Hide

Lynda - Gone For a Week

Track/Stream: Warren G - This D.J.

I was beginning to think that Lynda being in Florida this week was going to a good thing (Note: I am not going to link to something explaining where Florida is. Everyone knows Florida is America's wang). I didn't want my bad mood (which has been slowly escalating) unleashed on her for something that isn't her fault. I didn't really have to worry about it though; being around her relaxes me. Now the sucky part is that I'll miss her being gone.

So after dropping her at the airport I came home and went to see Constantine with Zack and Josh (worst... movie... ever). Afterward we ate at a new sushi place on 8th & A which is running a half price promo (they make their money back by having atrocious service). We watched some crap TV then I blew a couple hundred people away on video games.

Now I'm going to sleep...

Maybe after I read a bit more in my new compiler book...

0 Comments:

Post a Comment | Hide

Saturday, February 19, 2005

Not a Good Sign

Track/Stream: Dieselboy - Beckoning

I didn't leave work until 4.30. After testing (which went well) they rolled the database back and couldn't bring one of the systems back online. I depended on that system, so I was forced to stay 3 hours later than I expected. Finally my boss asked why I was still hanging around. I told him that he had told me to stay. He made me wait another quarter hour, then let me go. On top of all this, he declined my request to take some of the comp time I have earned.

So I left the building listening to Linkin Park at a fairly loud volume. This isn't necesarily a bad sign, but it is a warning sign. On the way home I ran into several situations which exacerbated my mood. The first was with dumb tourists, then dumb NYU students, then with a flamboyant staff member at Barnes & Noble, then with a Barnes and Noble "Recommended Book" about Brad Pitt and Jenifer Aniston, then with stupid people walking on the sidewalk.

By the time I got home, my music had changed from loud Linkin Park to loud Dieselboy. This is like red sirens going off. It usually means I'm very close to completely blowing my top. And this evening I have a dinner with Lynda's cousin and his girl (who sounds like a total bitch), followed by a party in Brooklyn.

I'm already tired and pissy. I'm hoping I can keep it in check.

0 Comments:

Post a Comment | Hide

Work - Good Thing We Don't Work for NASA

Track/Stream: Linkin Park - Breaking the Habit

The launch last night was less than stellar. Ray's estimate that we would be leaving around 6.45 pm proved to be hauntingly true. In fact I left the building at almost exactly 6.45..... Hawaiian Time. The night seemed to be a case study in me telling people to do things a certain way, they forget, argue, or just straight out don't, I force the issue, and things work.

So we're all back today to do final production testing. Aside from several initial run foibles (incorrect roles assigned, passwords not reset, the building fire alarms going off) things are running pretty smoothly. I haven't had any problems to fix in over an hour and with any luck I'll be out of here around 1.00, home to sleep for a bit, then out for the evening with Lynda.

On a more important note, Andy says I'm a "computer geek" because I posted code in my blog.

You'd think that she would have noticed that before, like during the 8½ years we dated, instead of a year and a half after we broke up.

0 Comments:

Post a Comment | Hide

Friday, February 18, 2005

Work - Launch

Track/Stream: Live - Lightning Crashes

We launch in T-minus 8 hours, 30 minutes. This is officially the quiet before the storm. Hopefully there won't be a storm as such, but you know what I mean. My morning will be quiet, probably testing bug fixes on my previous project.

In the afternoon I'll do the final build of my new system and deploy it to the target machines. At 4.30 pm the systems I am dependent on come down for their maintainance. At that point I'll bring my system up in order to make sure it starts up and attempts to connect. If that's successful I'll bring it back down and wait for those systems to come back online (around 6.00 pm). Once they're back up, I'll bring my system up, make sure it connects and does everything it needs, then go home. With any luck I'll be gone by 6.30 pm.

Now, because I work in a corporate hell, replace every instance of "I" in the above paragraph with "the appropriate team (with me hovering above their shoulder)." The build team does the build, the deployment team does the deployment, etc.

Developers aren't allowed anywhere near their own code running in production. Kind of a pain in the ass when something needs to be reconfigured, but oh well. I guess they think we'll be too tempted to fix a problem in-flight.

Yeah, we probably would.

0 Comments:

Post a Comment | Hide

Thursday, February 17, 2005

Porn Names

Track/Stream: Presidents of the United States of America - Kitty

I got into a discussion about the unique name thing with a couple coworkers. Of course the conversation strayed to porn. So, what porn name you would choose for yourself?

Me: Craig Shaftway (0 on Google) or Thickly Settled (13,900 on Google)
Chris:
Dick Striker (18 on Google)
Ralph: Scuba Buzz (2 on Google)
Amar:
Buck Naked (71,000 on Google)
Lynda:
Sugar (31,500,000 on Google)
Liz: Fifi Greenwood (0 on Google)

I'll add more as results come in

0 Comments:

Post a Comment | Hide

Work - Waiting for a Contractor

Track/Stream: Guns N' Roses - November Rain

In a rather amusing move today, we realized that our company only has 3 employed .NET developers. One is a VP (who rarely deigns to program), one sucks (only knows VB.NET and doesn't understand complicated things like "application domains" and "for loops"), and the other is your's truly. Most of our development is in Java, but we've also got 5 .NET consultants.

So I'm hoping to take a week off soon, and it was decided that I should start teaching another developer how my program works. To be honest, there's a lot of truck-sensitive knowledge in there. So we start casting about for the appropriate person to tutor. Immediately both employees are removed from the pool (for obvious reasons).

So now I'm just waiting for upper management to assign my soux developer. In the meantime. I'm Googling old friends' names, just to see what pops up. Apparently Judd gave up on drama and programming and is, instead, a published doctor and journalist. David works for NASA, is a surgeoun in Australia, and works for Oracle. Gabe has started writing comic books, organizes charity races in Michigan, and plays guitar in a band in San Diego (it doesn't help that he shares the same last name as half of Mexico). James has more jobs than I could think up in a year (shares the same last name as half of China).

My friends need uniquer names.

0 Comments:

Post a Comment | Hide

Wednesday, February 16, 2005

Work - Non-critical bugs

Track/Stream: Digitally Imported - Deep House

Right now my project is 2 days away from launch. My boss is incredibly paranoid and will believe just about anything you tell him. So he has mandated that, barring any critical bugs, the project is going to launch as-is. Everyone who has any sort of dealing with the project knows this.
So to remove any shadow of doubt, here are examples of critical and non critical bugs:

Critical: Someone can flood the server effectively grinding all activity to a halt

Non-Critical: A tag erroneously identifies a rejection as pertaining to a cancel instead of a modification

Critical: Under typical work-flow conditions, orders are lost

Non-Critical: It is difficult to determine where the logs for the current session begin

Critical: Users can begin World War III with a malformed message

Non-Critical: The service name should be prefixed by two characters (Not the display name, the internal name used when you run net start svc, which is never seen by anyone anywhere and only executed by automated scripts)

For the record, every single one of the non-critical examples above has come up since the code-freeze announcement a week ago. I was asked for every single one if the fix would be launched in production.

0 Comments:

Post a Comment | Hide

Tuesday, February 15, 2005

Random Browsing - Found Magazine

Track/Stream: Linkin Park - Somewhere I Belong

Just browsing some random crap. Found an unusual site: Found Magazine. Basically people just post stuff they find. I guess people are fascinated by other people's crap.

My Favorite

0 Comments:

Post a Comment | Hide

C# - Volatile Fields

Track/Stream: Moloko - Fun For Me

Fields in C# classes can be marked as volatile. I'm slightly unclear on this, but it looks like a niche task, really only needed for concurrent thread signalling issues. For example, if you have the following:

  class Foo
  {
    public int i = 0;
    public bool b = false;
 
    public void Go()
    {
      i = 42;
      b = true;
    }
 
    public int Wait()
    {
      while (!b)
        System.Threading.Thread.Sleep(1);
      return i;
    }
  }

If you call Go() from thread A, then call Wait() from thread B, it's possible to get 0 as your result. This is because .NET optimizes stuff behind the scenes, and assignment statements might not get executed in order behind the scenes. This is all covered when you're using a single thread (so if thread A checked these values, it'd be fine), but for multithreaded scenarios it isn't handled.

Now, if you were to put a volatile keyword on b (i.e. public volatile bool b; ), it would ensure that all assignments were flushed before b is assigned.

I'm sure there's an excellent reason behind this, but I'm equally sure I've pebcak'ed a bug or two due to this. Hmmmm, one more thing to watch out for.



0 Comments:

Post a Comment | Hide

Work - Command Line Configuration

Track/Stream: 3 Doors Down - Kryptonite

Still don't have much to do at work, so I finished a little project I started yesterday. Through a few of my projects now I've had to deal with command line stuff. In general it's a pain in the ass to support a bunch of dumb options. These things also tend to be formulaic, so I decided to refactor all of my command line handling into a few quick classes and put a bunch of junk into config files.

So the end result is a pretty lithe class (around 150 lines) that does the basic stuff, but can be easily extended to do whatever you want. None of it is commented, but most of it should be pretty obvious.

using System;
 
namespace System.Configuration
{
  public sealed class CommandLineSectionHandler : System.Configuration.IConfigurationSectionHandler, System.Collections.IEnumerable
  {
    private CommandLineParameter[] _Parameters = new CommandLineParameter[0];
 
    public void LoadCommandLine(string[] args)
    {
      for (int i = 0; i < args.Length; i++)
        for (int j = 0; j < _Parameters.Length; j++)
        {
          bool handled;
          bool expectMore;
          object state = null;
 
          _Parameters[j].LoadCommandLineSegment(args[i], ref state, out expectMore, out handled);
 
          if (handled)
          {
            while (expectMore)
            {
              _Parameters[j].LoadCommandLineSegment(args[++i], ref state, out expectMore, out handled);
              if (!handled)
                throw new CommandLineException("Invalid Command Line Parameter", _Parameters[j].Name);
            }
            break;
          }
        }
 
      foreach (CommandLineParameter param in _Parameters)
        if ((param.Required) && (!param.Satisfied))
          throw new CommandLineException("Missing Required Command Line Parameter", param.Name);
    }
 
    public string Help
    {
      get
      {
        System.Text.StringBuilder Result = new System.Text.StringBuilder();
        foreach (CommandLineParameter param in _Parameters)
        {
          string nextChunk = param.Help;
          if (nextChunk != null)
            Result.AppendFormat("{0}\n", nextChunk);
        }
        return Result.ToString();
      }
    }
 
    public CommandLineParameter this[string Name]
    {
      get
      {
        foreach (CommandLineParameter parameter in _Parameters)
          if (parameter.Name == Name)
            return parameter;
 
        return null;
      }
    }
 
    public System.Collections.IEnumerator GetEnumerator()
    {
      return _Parameters.GetEnumerator();
    }
 
    public object Create(object Parent, object ConfigContext, System.Xml.XmlNode Section) 
    { 
      int i = 0;
 
      _Parameters = new CommandLineParameter[Section.SelectNodes("param").Count];
 
      foreach (System.Xml.XmlElement parameter in Section.SelectNodes("param"))
      {
        if (parameter.GetAttributeNode("type") == null)
          throw new ConfigurationException("'type' attribute not specified", parameter);
        if (parameter.GetAttributeNode("name") == null)
          throw new ConfigurationException("'name' attribute not specified", parameter);
 
        string typeName = parameter.GetAttribute("type");
 
        Type paramType = Type.GetType(typeName);
 
        if (paramType == null)
          paramType = System.Reflection.Assembly.GetEntryAssembly().GetType(typeName, false, true);
 
        if (paramType == null)
          paramType = System.Reflection.Assembly.GetCallingAssembly().GetType(typeName, false, true);
 
        if (paramType == null)
          paramType = System.Reflection.Assembly.GetExecutingAssembly().GetType(typeName, false, true);
 
        if (paramType == null)
          paramType = System.Reflection.Assembly.GetExecutingAssembly().GetType(this.GetType().FullName + "+" + typeName, false, true);
 
        if (paramType == null)
          paramType = Type.GetType(typeName, false, true);
 
        if (paramType == null)
          throw new ConfigurationException("Parameter type not recognized", parameter);
 
        _Parameters[i++] = (CommandLineParameter)((CommandLineParameter)paramType.GetConstructor(System.Type.EmptyTypes).Invoke(null)).Create(this, null, parameter);
      }
 
      return this;
    }
 
    public class CommandLineException : Exception
    {
      private string _Parameter;
      public  string  Parameter { get { return _Parameter; } }
 
      public CommandLineException(string Message, string Parameter, Exception exx) : base(Message, exx) { _Parameter = Parameter; }
      public CommandLineException(string Message, string Parameter) : this(Message, Parameter, null) { }
    }
 
    public abstract class CommandLineParameter : System.Configuration.IConfigurationSectionHandler
    {
      protected string _Name;
      public    string  Name { get { return _Name; } }
 
      protected bool   _Required;
      public    bool    Required { get { return _Required; } }
 
      protected string _Description = null;
 
      public object Create(object Parent, object ConfigContext, System.Xml.XmlNode Section) 
      {
        _Name     = ((System.Xml.XmlElement)Section).GetAttribute("name");
        if (((System.Xml.XmlElement)Section).GetAttributeNode("required") != null)
          _Required = bool.Parse(((System.Xml.XmlElement)Section).GetAttribute("required"));
 
        System.Xml.XmlNode description = Section.SelectSingleNode("description");
        if (description != null)
          _Description = description.InnerText;
 
        this.Configure(Section);
        return this;
      }
 
      public virtual string Help { get { return _Description; } }
 
      protected abstract void Configure(System.Xml.XmlNode Section);
 
      public abstract void LoadCommandLineSegment(string Segment, ref object State, out bool ExpectMore, out bool Handled);
 
      public abstract bool Satisfied { get; }
    }
  }
}


Since this is just a framework, we need a couple examples of how to extend this. Plus it'd be nice to have a configuration example. To extend this, you'd need to start by implementing a CommandLineParameter class. That's actually pretty easy. You need to implement two functions and a property.

The property, Satisfied, is actually pretty easy. You return whether or not you consider yourself properly initialized. This is used after the command line has been parsed. Any required parameter that does not report itself as satisfied will throw an error.

The Configure() method is called when configuring and is passed the param element from the config file (more on that later). These nodes are plain XML and can be processed as you see fit.

The LoadCommandLineSegment() method does the bulk of your work. You will be passed each segment of the command line (in the Segment variable) which was not handled by a prior parameter. If this parameter is handled by your handler, you should set Handled to true so that no subsequent handlers will be called. If you expect more data to come immediately after this, set ExpectMore to true as well. You will have exclusive access to subsequent data until you set ExpectMore to false. Finally, should you need to keep track of any state, it is suggested that you do so using the State parameter. This will be passed back to you in an unaltered form and can be any object of your choice.

That's all there is to it. So here are a couple examples. I start with another abstract class to make my life easier. It just handles configuration of a key in the form /key. If a value follows, it is up to subsequent implementations to include it.

    public abstract class KeyedCommandLineParameter : CommandLineParameter
    {
      protected string _KeyName = null;
 
      protected override void Configure(System.Xml.XmlNode Section)
      {
        System.Xml.XmlElement parameter = (System.Xml.XmlElement)Section;
 
        if (parameter.GetAttributeNode("key") == null)
          throw new ConfigurationException("'key' attribute not specified", parameter);
 
        _KeyName = parameter.GetAttribute("key");
        if (!_KeyName.StartsWith("/"))
          _KeyName = "/" + _KeyName;
      }
 
      public override string Help
      {
        get
        {
          if (_Description != null)
            return string.Format("{0,-20} {1}", _KeyName, _Description);
          else
            return null;
        }
      }
    }
 


Pretty simple. Here are a pair of implementations of parameters. One covers boolean flags. The flag defaults to false unless the value is present. The other covers integer flags. They can have a default value (0 if none is specified) and the value is specified as a second parameter (i.e. /foo 15).

    public sealed class IntegerCommandLineParameter : KeyedCommandLineParameter
    {
      private int  _Value = 0;
      public  int   Value { get { return _Value; } }
 
      private bool _FoundValue = false;
 
      protected override void Configure(System.Xml.XmlNode Section)
      {
        base.Configure(Section);
 
        System.Xml.XmlElement parameter = (System.Xml.XmlElement)Section;
 
        try
        {
          if (parameter.GetAttributeNode("default") != null)
            _Value = int.Parse(parameter.GetAttribute("default"));
        }
        catch (Exception exx)
        {
          throw new ConfigurationException("'default' attribute not properly formatted", exx, Section);
        }
      }
 
      public override void LoadCommandLineSegment(string Segment, ref object State, out bool ExpectMore, out bool Handled)
      {
        ExpectMore = false;
 
        if (State == null)
        {
          if (string.Compare(_KeyName, Segment, true) == 0)
          {
            Handled = true;
            ExpectMore = true;
            State = new object();
          }
          else
            Handled = false;
        }
        else
        {
          try
          {
            _Value = int.Parse(Segment);
            _FoundValue = true;
            Handled = true;
          }
          catch (Exception exx)
          {
            throw new CommandLineException("Invalid Parameter Value", _Name, exx);
          }
        }
      }
 
      public override bool Satisfied
      {
        get
        {
          return _FoundValue;
        }
      }
 
      public override string ToString()
      {
        return String.Format("{0} - {1} ({2})", _Name, _Value, _KeyName);
      }
    }
 
    public sealed class BooleanCommandLineParameter : KeyedCommandLineParameter
    {
      private bool _Value = false;
      public  bool  Value { get { return _Value; } }
 
      public override void LoadCommandLineSegment(string Segment, ref object State, out bool ExpectMore, out bool Handled)
      {
        if (string.Compare(_KeyName, Segment, true) == 0)
        {
          Handled = true;
          _Value = true;
        }
        else
          Handled = false;
 
        ExpectMore = false;
      }
 
      public override string ToString()
      {
        return String.Format("{0} - {1} ({2})", _Name, _Value, _KeyName);
      }
 
      public override bool Satisfied { get { return true; } }
    }


Here is a sample config. This is pretty standard config framework. On each param node, you are expected to have a type and name attribute. You may also have a description child element (used when displaying Help). Anything else depends on your parameter implementations.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="system.configuration.commandline" type="System.Configuration.CommandLineSectionHandler, CommandLineParams"/> 
  </configSections>
  
  <system.configuration.commandline>
    <param type="BooleanCommandLineParameter" name="booltest"  key="foo">
    <param type="BooleanCommandLineParameter" name="booltest2" key="foob">
    <param type="IntegerCommandLineParameter" name="inttest"   key="bah">
    <param type="IntegerCommandLineParameter" name="inttest2"  key="bahb">
    <param type="IntegerCommandLineParameter" name="inttest3"  key="bahc" default="5">
      <description>This is a parameter</description>
    </param>
  </system.configuration.commandline>
</configuration>


Finally, it's nice to know how to do stuff with it. Try something like this:

      System.Configuration.CommandLineSectionHandler StartupConfig = (System.Configuration.CommandLineSectionHandler)System.Configuration.ConfigurationSettings.GetConfig("system.configuration.commandline");
 
      StartupConfig.LoadCommandLine(args);
 
      System.Console.WriteLine(StartupConfig.Help);
 
      foreach(System.Configuration.CommandLineSectionHandler.CommandLineParameter param in StartupConfig)
        System.Console.WriteLine(param.ToString());
 
      System.Console.WriteLine("inttest3: {0}\n", ((System.Configuration.CommandLineSectionHandler.IntegerCommandLineParameter)StartupConfig["inttest3"]).Value);


This loads up the config, passes in the command line arguments and processes the whole deal. Then it shows the help text followed by a list of each parameter and the associate value, then shows you the value of a parameter called "inttest3" (I used the config file listed above).

0 Comments:

Post a Comment | Hide

Monday, February 14, 2005

Work - Nothing to Do

Track/Stream: SOMA-FM - Groove Salad

Work is going pretty slow today. My project is slushed right now. Technically it's not frozen as I'm still tweaking the odd value here and there, but for all intents and purposes the existing code is untouchable. Later today I'll do a release candidate build.

That's not going to stop me from working ahead though. We're slapping a FIX front-end on an existing electonic trading platform. For launch, we're looking pretty good. The only bugs I get are from jerks nit-picking on my grammar (I said "TLTC on 7 Lot(s), Out on 3 Lot(s)" on purpose, instead of "TLTC on 7 Lot(s) Out of 10 Lot(s)". They mean the same thing, but mine is the industry-standard way).

So now I'm doing three things:

1.) Implementing version 1.1 functionality (Already done, but blocked by pre-processing directives)

2.) Reviewing how long it will take to add some new functionality to my last project (probably an hour of work, but I'll list 4 hours to cover my ass)

3.) Playing Dominos, surfing blogs and reading up on the lesser-known areas of C#

I expect to write some posts through the day about what I've learned.

0 Comments:

Post a Comment | Hide

Saturday, February 12, 2005

Snowboarding @ Butternut

Track/Stream: The Crystal Method - Trip Like I Do

It's been a long time since I've gotten to strap my board on and throw myself down a mountain. Lynda, Andrew (her roommate) and I jumped in her car last night and drove up to his folks' place in Connecticut (note the convenient link to the state, in case you don't know what Connecticut is). After a short night's sleep we headed out to the slopes.

We hit Butternut, a small resort in Massachusetts (again linked for your educational goodness). They touted 22 of 22 runs open (2 runs are the bunny trail, and 1 is for innertubes). Lynda and Andrew both took a class, which left me free to go to the top of the mountain. I took a few long relaxing runs. Unfortunately there wasn't enough cover to go for a tree run, but there were some interesting natural terrain features, so I had some fun. I had a couple accidents including being nailed in the back by a ski and landing hard on my hip, but nothing too bad.

Afterwards we went back to Andrew's parents' place, hung out for a couple hours (just long enough for me to be victorious in a game of scrabble with some beauties like clime, ova, and vectors (on a triple word score)), then drove back to the city. I pulled second driving shift, so after dinner at Burger King (yum) I brought us home.

Gas and Food: $40
Lift Tickets/Rentals: $100
Breaking my MP3 Player While Boarding: Pricele...... wait a minute! That thing cost me $300!

Damnit!

1 Comments:

Post a Comment | Hide