Friday, October 06, 2006

Compiled vs Dynamic Laguages and the Code Feedback Loop

So I bit the bullet and installed Ruby on Rails.  I’ve been reading a lot about Ruby (mainly blogs) and decided that it’s about time to learn another language.  The Pragmatic Programmers believe that you should dedicate some time to learn a new language every year.

My first impressions are probably pretty common.  Ruby is not easy to jump into.  They have a lot of great information on the internet, but I found that things didn’t go as smoothly as I had hoped.  This is probably due to the fact that there are major changes between each version of ruby/rails, and there are old tutorials directed at older versions of Ruby or Rails.

The second hinderance I found was that, with Ruby (among other dynamic languages), you don’t get any intellisense.  Being brought up with Visual Studio made me spoiled, I suppose.  The fact is, with any dynamic language, such as Ruby, Python, or Javascript…  Intellisense is difficult to provide.  Type information often isn’t available until runtime.

This really annoyed me at first, and I was quick to dismiss dynamic languages. 

Intellisense really makes your learning experience much easier.  When I started in .NET, I had a few books, but mainly I just used Intellisense to navigate my way around the framework.  If you didn’t know how to send email with .NET, you could easily just type System.Web.Mail. and you’d see the relevant classes involved.  Intellisense is an extremely effective discoverability tool.  

Now that I am an experienced .NET developer, I know all of these things by heart.  There’s not much stopping me from writing my programs in Notepad2.  I don’t rely as heavily on Intellisense like I did before.  I still use Visual Studio, though, because having your compiler and debugger integrated with your editor is almost a necessity.

This isn’t the case with dynamic languages.  You write a program (often times in a single file with FAR fewer lines of code) and you run it.  That’s it.  There’s no compilation or startup time.  You get your results right there.  If you mispell a type or call a method on the wrong class of course you’ll get an error.  But you find this out sooner that your C# / Java program will compile.  If you can write 5 lines of code and push a button to see if it worked…  without waiting for a compiler or debugger, then your code-feedback-loop is MUCH tighter.  Agile principles thrive on having small feedback loops.  This is (in my opinion) the single largest reason why Agile is so effective.

The compiler is becoming less and less popular these days because it cannot protect your program from logic flaws.  It’s becoming much like the spell-check feature of word processors.  They can tell you that you mispelled the word definate definite, but a sentence like this one will pass spell-check just fine:  We will meat at the movie theater.  A compiler can only take you so far.  To verify your program works, you have to compile it, run it, navigate to the section, and test it.  In a dynamic language, half of these steps are removed, leaving you with a much tighter code-feedback-loop.

We all love intellisense (and I will welcome it for Ruby with open-arms), but don’t let that stop you from writing your next small program in a language like Python or Ruby.  It will give you another tool in your developer toolbox and make you a better programmer in *any* language.

 

Wednesday, September 27, 2006

I'm not dead

I’m just posting this to let my readers know that I am not dead

I’ve been eager to finish the articles on Domain Driven Design and NHibernate, however work has been very busy lately, combined with kids soccer, volleyball, cub scounts, and other activities….there’s not enough time in a day!

Ahh, and I’d also like to personally thank Aaron Murrell and Ayende Rahien for their hugely appreciated assistance in overcoming some very obscure issues.  Thanks guys!

Tuesday, September 05, 2006

Reason #462 Why I don't like VB.NET

Reason #462 Why I don't like VB.NET:

VB.NET attributes cannot have variable arguments.  What do I mean?

The following code does NOT work in VB.NET:

Public Class MyCustomAttribute

    Inherits Attribute

 

    Public Sub New(ByVal ParamArray vals() As String)

    End Sub

 

End Class

It compiles, but when you try to use this attribute on a member you’ll get an error:  “Attribute constructor argument is a 1-dimension array of string which is not Integral, float, etc…..”

In C# this works perfectly fine.  Why is this?

To provide a workaround for this issue I just accept a single pipe-delimited string and .Split it on the pipe to get my array.  A tad on the ugly side, but it works.

Now playing: Third Eye Open - Intolerance

Friday, September 01, 2006

A Journey with Domain Driven Design (and NHibernate) - Part 6

Welcome back!  In Part 5 we finished off with a table structure and the beginnings of NHibernate.  We’ll dive in deeper with NHibernate and mapping in this article.

(part 1 was Dugg, which was quite exciting to me!  It has also increased the traffic around here a little bit!  If you’re enjoying the series, why not Digg it some more?)

Currently we can initialize our SessionFactory which reads the configuration file and loads our domain model assembly.  This step is where NHibernate will parse our mapping files (once we add them).

So let’s take a step back and ask the question that’s probably on your minds already: how do we get our classes mapped to the database using NHibernate?  We have to provide a mapping file.  An NHibernate mapping file is an xml file that specifies how your object fields and properties map to database columns.  There are a few ways you can load mapping files into NHibernate, but the easiest I have found is to add them as part of your domain model class library as embedded resources (details below).   I emphasize embedded resources because if you just add the XML files without specifying they will not be recognized automatically by our SessionFactory initialization.

A number of people have asked me to display more source code, and in this article you’ll see the domain model in more detail.  At the end of this article I will post the code that we’ve created so far.

If you are a little scared about writing these mapping files and would rather use a tool to generate it for you that is certainly possible.  Ayende Rahien’s NHibernate Query Analyzer can help with this.  I have found, however, that in order to fully understand how to effectively map your objects, you should write the mapping by hand.  Don’t fret, there is hope with the manual method.  The hope?  Intellisense.  To get nhibernate mapping intellisense in Visual Studio 2005 you can copy the schema file (nhibernate-mapping-2.0.xsd) to C:\Program Files\Microsoft Visual Studio 8\Xml\Schemas.

Now that we have intellisense for our mapping files, we can start creating our mappings.  I choose to have a single mapping file per class, so that they don’t get too cluttered.  There is nothing to stop you from defining your entire object model in a single mapping file, but I avoid this approach.

CropperCapture[26]Starting off with the Person class, we create add a new XML file to our domain model project called Person.hbm.xml.  NHibernate will search our assembly for embedded resources named *.hbm.xml.  If this is mispelled or the file is not marked as an embedded resource the mapping will not be found and NHibernate won’t recognize the object.

 CropperCapture[28]
In these screen shots you can see that I have added the mapping file next to my objects and I right-clicked and selected properties.  Then under the properties pane I clicked on Build Action and changed the value from Compile to Embedded Resource.CropperCapture[27]


 

Let’s take a side-by-side look at our Person class with our People database table.  This will be  a simple mapping because the class contains no complex associations with other classes.

Side-by-side compare3

Here you can see that we simple relate each property in our class to a column in the table.  Address, in this example, is called a component.  What this means is that Address has no table of its own;  all of the address properties are mapped to the containing object’s table.  We say that Address is a component of Person.  I chose to represent it this way in the object model to delineate the model and separate concerns.  It is a common occurrence for the database, however, to not employ unnecessary joins for simple associations such as this one (for performance reasons).

We start by opening our (now blank) Person.hbm.xml file.  In order to tell Visual Studio that we want intellisense for this file, we have to create the document element (the root) called <hibernate-mapping>.  We tell it which schema to use, and then intellisense kicks in.  Also in this root element the assembly and namespace are defined.  This saves us from typing it every time in the mapping file.  For example, within this mapping file, Person will refer to the strongly typed Flux88.Videocracy.DomainModel.Person, Flux88.DomainModel.Person (see?  less typing!).

*note:  I have changed the Phone number properties to be plain-jane strings instead of the Phone Number class that you may have seen earlier.  While this is a good addition, it complicates the mapping a tad too much right at first, so I removed it in favor of a simple mapping for now.

<?xml version="1.0" encoding="utf-8" ?>

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0"

                  assembly="Flux88.Videocracy.DomainModel"

                  namespace="Flux88.Videocracy.DomainModel">

 

</hibernate-mapping>

The next element in this mapping will be our class:

<?xml version="1.0" encoding="utf-8" ?>

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0"

                  namespace="Flux88.Videocracy.DomainModel"

                  assembly="Flux88.Videocracy.DomainModel">

 

  <class name="Person" table="People">

 

    <id name="Id" access="nosetter.camelcase-underscore"

          column="PersonId" type="Int32">

      <generator class="identity" />

    </id>

 

  </class>

 

</hibernate-mapping>

I have emboldened the new text.  The name property here tells NHibernate that we are mapping our Person class, from the assembly/namespace defined above.  The table attribute tells NHibernate which table this class maps to.  There are a few other advanced attributes that we may define, but these will suffice for this mapping. 

The first child of our <class> element is the <id> element.  This tells NHibernate what our primary key is.  You can specify a single field or multiple fields (composite-id) and define their type as well.  Here you see that the name attribute refers to our Id property of the Person class.  We do not want consumers of our objects to be able to set arbitrary values in the primary key, so this is a read only property.  As such it does not have a setter, but NHibernate needs to know how it will set the value (otherwise how could it get there?).  We give NHibernate a hint by specifying a predefined access strategy in the access attribute.  nosetter.camelcase-underscore is the access strategy that we will employ.  (This means that since our property is named Id, the private field must be named _id).  There are other access strategies so if you prefer naming such as m_id you can deal with that as well.  We specify the type of our Id property (specifically Ant, which is an NHibernate Type that matches our int).

The last thing you’ll notice is that <id> has a <generator> child element.  This tells NHibernate that we are using MS SQL Identity as our primary key generator.  NHibernate also understands Oracle sequence, hilo, guids and other primary key generators.  (I was happy to learn there is also a neat generator class for guid.comb, which is a sort of “ordered” guid conceived by Jimmy Nilsson – if you are using Guids as primary keys, you should consider this.)

One of the reasons for specifying a generated primary key like this is so that NHibernate easily knows whether or not your object is a brand new object that needs to be inserted or a previously fetched object that might by updated or deleted.  Using a guid, identity, hilo, or sequence we get the benefit of just calling Session.SaveOrUpdate(myObject) and NHibernate knows whether to generate an insert or update behind-the-scenes.

Here’s the rest of the Person class mapping file:

<?xml version="1.0" encoding="utf-8" ?>

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0"

                  namespace="Flux88.Videocracy.DomainModel"

                  assembly="Flux88.Videocracy.DomainModel">

 

  <class name="Person" table="People">

 

    <id name="Id" access="nosetter.camelcase-underscore"

          column="PersonId" type="Int32">

      <generator class="identity" />

    </id>

 

    <property name="FirstName" type="String" length="100" column="firstName"

      not-null="true" />

    <property name="LastName" type="String" length="100" column="lastName"

      not-null="true" />

    <property name="HomePhone" type="String" length="50" column="primaryPhone"

      not-null="true" />

    <property name="AltPhone" type="String" length="50" column="altPhone" />

    <property name="DateOfBirth" type="DateTime" column="dateOfBirth"

      not-null="true" />

 

    <component name="Address" class="Address">

      <property name="Line1" type="String" length="100" column="addressLine1"

          not-null="true" />

      <property name="Line2" type="String" length="100" column="addressLine2" />

      <property name="City" type="String" length="100" column="city" />

      <property name="State" type="String" length="50" column="state" />

      <property name="Zip" type="String" length="50" column="zip" />

    </component>

 

  </class>

 

</hibernate-mapping>

Here you can see that the properties are defined, along with their type (and length for strings) as well as their database column name.  The Address component is nested within this mapping and defined with the <component> element.

With me so far?

So basically that’s it.  We have a Person object and it is completely persistable.  You tell NHibernate how to persist your object and you get all of the CRUD operations for free.  You can create a new Person, fill out some properties, and then call Session.SaveOrUpdate(person) to save the person.  Or you can call Session.Load(typeof(Person), personId) to fetch an existing person from the database.  You can also query for Person objects, but we’ll get into that later.  The point is, with NHibernate we are avoiding writing the mundane task of repetitive SQL commands and stored procedures.

Let’s prove that this works with tests.

 The simplest way of seeing if our mapping is working or not is to actually hit the database.  The simplest way to do this is to do a List operation, (basically SELECT * FROM table).  If NHibernate doesn’t recognize your type the test will fail.  If your mapping doesn’t map to valid columns or class properties, the test will fail.  It’s slightly larger in scope than the Unit Tests, but this is actually an integration test, so it’s okay to test a broader scope.

[TestFixture]

public class PersonTester

{

    private int GetPersonCount()

    {

        return Convert.ToInt32(

            DatabaseHelper.ExecuteQuery("SELECT COUNT(*) FROM People"));

    }

 

    [Test]

    public void TestCanListPeople()

    {

        using (NHibernate.ISession session = SessionSource.Current.GetSession())

        {

            IList people = session.CreateCriteria(typeof(Person)).List();

 

 

            Assert.IsNotNull(people, "Person list should not be null.");

            Assert.AreEqual(GetPersonCount(), people.Count,

                "Person list didn't have the right number of elements");

        }

    }

}

This tests gets a list of all of the Person records in the database (currently zero, but that won’t matter).  It compares the count of this list to a SELECT COUNT(*) FROM People, using a helper class.  One thing to note is that I am making this test scale with the database.  It should always return the correct number of people.

I run the test and….

CropperCapture[33]

What?  Our new test passed, but why did CanInitializeSessionSource fail?  Upon a quick inspection, I realize that I have broken a core rule of unit testing:  Each test should run independently of other tests.  The order of test execution should not affect the outcome of the test.  This code:

[Test]

public void CanInitializeSessionSource()

{

    Assert.IsFalse(SessionSource.Current.IsInitialized);

    SessionSource.Current.Initialize();

 

    Assert.IsTrue(SessionSource.Current.IsInitialized);

}

…is assuming that the current Session Source is not initialized.  If another test that uses the SessionSource executes before us (like what happened above) then this Assertion fails.  What we have to do is set our pre-condition explicitly:

[Test]

public void CanInitializeSessionSource()

{

    //make sure we start in a known state

    SessionSource.Current.Close();

 

    Assert.IsFalse(SessionSource.Current.IsInitialized);

    SessionSource.Current.Initialize();

 

    Assert.IsTrue(SessionSource.Current.IsInitialized);

}

This test fails because the .Close() method doesn’t exist yet.  Here is the implementation that passes the test:

 

//SessionSource.cs

 

/// <summary>

/// Closes the current session factory.  The next call

/// to initialize or GetSession will re-initialize the SessionSource

/// </summary>

public void Close()

{

    if (_factory == null)

        return;

     

    _factory.Close();

    _initialized = false;

}

 

And we’re back to all green again.

 

Next we can test to see if we can save a Person object.  To test this we actually have to save it and verify that each property is equal to what it was saved as.  I find this is easier to do by breaking a small rule:  if we write the load functionality and reuse it to help Assert that our Save works, we can cut a few corners.  I welcome any suggestions of a more elegant way of achieving this without resorting to a database query + column/property comparison which is tedious and boring.

 

Starting with the Load, we insert a person record into the database and verify that we can load it properly.  I have written a simple helper class that will assist us with these database operations.  A really quick and dirty convert-dictionary-to-insert statement is a tad on the ugly side, but this isn’t production code and it serves our purpose nicely.  So we insert a test Person record into the database, then we load it and verify that it returns ok.

 

Before I show you this test, keep in mind that since we are inserting data into a (probably) development database, we don’t want this junk data to stick around.  We will be running these tests over and over again, and each time it should clean up nicely.  We can accomplish this easily by using transactions (more on this later).

 

[Test]

public void TestCanLoadAPerson()

{

    TransactionScope tx = new TransactionScope();

 

    try

    {

        //first we need to insert a person               

        Dictionary<string, object> dictionary = new Dictionary<string, object>();

        dictionary.Add("firstName", "Fred");

        dictionary.Add("lastName", "Flinstone");

        dictionary.Add("dateOfBirth", new DateTime(1925, 10, 5));

        dictionary.Add("primaryPhone", "111-222-3333");

        dictionary.Add("altPhone", "444-555-6666");

        dictionary.Add("addressLine1", "123 Rocky Lane");

        dictionary.Add("addressLine2", "#555");

        dictionary.Add("city", "Bedrock");

        dictionary.Add("state", "ZZ");

        dictionary.Add("zip", "12345");

 

        int personId = _datasource.ExecuteDictionaryToInsertCommand(dictionary, "People");

 

        //try and fetch that person

        using (ISession session = SessionSource.Current.GetSession())

        {

 

            Person fred = (Person)session.Load(typeof(Person), personId);

 

            //assert that fred is who we think he is

            Assert.IsNotNull(fred, "Person should not be null");

            Assert.AreEqual(personId, fred.Id, "Id was different");

            Assert.AreEqual("Fred", fred.FirstName, "First Name was different");

            Assert.AreEqual("Flinstone", fred.LastName, "Last Name was different");

            Assert.AreEqual(dictionary["dateOfBirth"], fred.DateOfBirth, "Date of Birth was different");

            Assert.AreEqual("111-222-3333", fred.HomePhone);

            Assert.AreEqual("444-555-6666", fred.AltPhone);

            Assert.AreEqual("123 Rocky Lane", fred.Address.Line1);

            Assert.AreEqual("#555", fred.Address.Line2);

 

        }

    }

    finally

    {

        //cleanup               

        datasource.Dispose();

        tx.Dispose();

    }

}

 

Wow, that’s a long test.  But it’s explicit and easy to follow.  One thing I’d like to point out here is that we are combining standard ADO.NET (the _datasource call above) with NHibernate’s ISession.  It’s difficult to get these 2 to share a single transaction, so I’m using .NET 2.0’s TransactionScope which makes it easy to have a shared transactiont that works on any level.  The downside to this is that it’s 1) slow and 2) requires configuration and enabled services, which sometimes makes it a no-go, depending on your environment.  In other tests I’ll be able to just use NHibernate transactions and everything will be easier.  (YMMV).

 

In writing this test I exposed 2 or 3 different bugs with my mapping (which were then fixed).  This is a benefit of writing the tests along with the code.  If you wait until you have a UI to test all of this manually, you will have waited too long and will have to re-visit all of this code and remember exactly what it does and how to fix little issues.  Our feedback loop is very tight here, and that helps us stay on track and be efficient.  Ok, so this test is passing…. what next?

 

Before this article gets too long (too late?) I want to show one last thing.  We’ll write a CanSavePerson test.  Since we have our load already working, we’ll bend a rule and build on that:

 

[Test]

public void CanSavePerson()

{

    using (ISession session = SessionSource.Current.GetSession())

    {

        using (ITransaction tx = session.BeginTransaction())

        {

            //create a person

            Person p = new Person("Bruce", "Wayne");

            p.DateOfBirth = new DateTime(1972, 6, 2);

            p.HomePhone = "12345678";

            p.AltPhone = "987675123";

            p.Address.Line1 = "123 Bruce Manor";                   

            p.Address.State = "GT";

            p.Address.City = "Gotham";

            p.Address.Zip = "99999";

 

            //save the person

            session.Save(p);

 

            Assert.IsTrue(p.Id != 0, "Save should give p it's primary key");

 

            Person pVerify = (Person)session.Load(typeof(Person), p.Id);

            Assert.AreEqual(p, pVerify, "They weren't the same");

        }

    }

}

Here we create a new person object, save it to the database, then call our Load method (which we know works because of the previous test (TDD Purists won’t like this, but I haven’t seen an effective way to test this quickly).  Our Person objects (and subsequently, our Address objects) need to overrides the .Equals() method for the last assert to work.  As Rocky Lhotka says, let’s be good .NET citizens and override these methods in each of our objects.  Lastly, take notice that I’m using NHibernate’s transactions which get rolled back at the end of the test.  These don’t share the baggage of TransactionScope objects in the previous test.

This time we were able to create a mapping file for the Person object.  We learned to make sure and set it as an embedded resource so it is recognized by NHibernate.  Finally we learned some basic mapping concepts and backed them up with tests.

Next time we’ll introdude a few more objects and learn to map the relationships with NHibernate.

As promised, here is the current source code.  It contains all of the code written up to this article.  Comments and questions are encouraged.

 If you want to run the tests, you’ll need the NUnit Gui or the TestDriven.NET plugin for visual studio.

Thursday, August 24, 2006

A Year Gone By

..and a short break from the technical posts…

I can hardly believe it’s been a year (today) since my mom passed away.  We have gone through a lot to come to terms with the fact that she is not with us anymore.  Luckily we were (and are) surrounded by loving and supportive family and friends that help us through our hard times.  For that I am truly thankful.

Sometimes I feel like I wish I could cry more about losing her, and other times tears just hit me – mostly when I’m alone, driving and listening to music– when I am reminded of her.  It feels good to cry about it every once in a while.  It reminds me that I am human and that she still holds a large place in my heart.

My fiance, Silvia (who just started a blog herself) posted a touching memoir and scrapbook page on her blog.  Reading her comments makes me remember the good times we all had together, and not so much on the pain in the end.

I posted this link last year as well, but I want to post it again for my new readers to consider making a small donation to the Ovarian Cancer Research Fund.

Now playing: A Perfect Circle - Gravity

I got my Coding Horror Sticker Today

Today I received my free Coding Horror Sticker in the mail from Jeff Atwood. Thanks Jeff!

IMAGE_033

He even hand-wrote the envelope!  350 of them ?!?!

 

Wednesday, August 23, 2006

The Partial function in MochiKit

MochiKit is awesome.  I’ve only begun to scratch the surface of the power in this framework.

During my demo I had a hard time explaining what the partial function does.  I have never been a Python developer, so MochiKit’s influence is foreign to me.  I do appreciate the simplicity of the syntax.

Partial is aptly named.  It is basically a partial function call, wrapped in an object.  Why would you want this, I hear you say?  Consider the following:

// $('ctrlid') is MochiKits alias of document.getElementById('ctrlid')

 

$('txtbox').onchange = filterText('some input'); //wrong!  the function will be called immediately!

 

$('txtbox').onchange = function() //need an inline function wrapper to make the function call

            {               

                filterText('some input');

            }       

$('txtbox').onchange = partial(filterText, 'some input'); //partial separates the function from the argument(s)

 

In this example, the top line is setting the onchange event handler of a textbox to a function call.  But Javascript doesn’t know that you want a function pointer here, it looks like you want to call the method and return something.  So the solution that you can do is write a single function that wraps the function call that you want to make.  This can be done inline like I do above.  Partial comes in and cleans up those 3 lines and pushes them into 1 line. 

Next take a look at this:

 function startsWith(character, target)

 {

    //searches target for character, if found... returns true

 }

 

 var startsWithCapitalB = partial(startsWith, 'B');

 

 alert(startsWithCapitalB('Ben')); //true

 alert(startsWithCapitalB('Henry')); //false

Here you see where partial gets its name.  You can partially apply a function with partial and get a function variable returned!

Partial is incredibly powerful when applied with other functional programming methods like map.

Now playing: Modest Mouse - Black Cadillacs

A Journey with Domain Driven Design (and NHibernate) - Part 5

In Part 5 of our Journey with Domain Driven Design & NHibernate, we introduce the database structure to support our objects. We also configure NHibernate and build a helper class to assist in the usage of NHibernate.

Presentation on Next-Gen Web Techniques

Thanks to all who attended my presentation on Next Generation Web Development Techniques at SARK.  We talked about web layout with CSS (and not tables), Javascript, MochiKit, and AJAX.

It was my first attempt at speaking, and I feel that it went pretty well.  If you attended, I’d love to hear your feedback here.  I did hear from a couple people that a talk on just CSS for layout would be popular.  I’d definitely consider this.

As promised, I have uploaded the complete files from the demos here for you to download.

File Attachment: next gen web techniques - complete.zip (678 KB)

 Links mentioned in the presentation:

Thursday, August 17, 2006

Making DIVs stay next to each other

A colleague came to me with a very simple issue yesterday.  He had a table surrounding the area he was working on, and he wanted to have 2 DIVs side-by-side, one of them containing a table.

Here’s what he had:

<table>
 <tr>
  <td>
  
   <div style="padding: 2px; margin: 2px; border: #ccc; background-color:#eee;">
    here's the first div
   </div>

   <div style="padding: 2px; margin: 2px; border: #ccc; background-color:#eee;">
    ..and here's the 2nd
    <table border=1>
     <tr>
      <td>with a table</td>
     </td>
    </table>
   </div>
  </td>
 </tr>
</table>

...which looks like:

here's the first div
..and here's the 2nd
with a table

 

He tried a number of things that didn’t work.  Here’s the solution:

DIVs are block level elements that stretch to 100% of the width of the parent container.  So to get them to sit next to each other you first need to give them some room to do so.  Set the width so that they will both fit (be sure to account for border + margin as well).

The next thing to do is set the DIVs to float:left;  This will make them push up next to each other until there is no more room, then they will wrap.

Here it is in action:

 <table>
 <tr>
  <td width="300">
   
   <div style="margin:2px; padding:2px; border: solid 1px #bbb; background-color: #eee; float: left; width: 75px;">
    here's the 1st div
   </div>

   <div style="margin:2px; padding:2px; border: solid 1px #bbb; background-color: #eee; float: left; width: 75px;">
    ..and here's the 2nd
    <table border=1>
     <tr><td>with a table</td></tr>
    </table>
   </div>
  </td>
 </tr>
</table>

here's the 1st div
..and here's the 2nd
with a table

 

Understanding how floating works is an important part of effective CSS web design.  I may consider some more of these simple examples if they are of help to my readers.

Newshutch is my friend

For my RSS Feeds I had previously used RssReader.  I used it because I wanted a windows application that would notify me of new posts and not be too obtrusive.  RssReader is pretty nice, but the interface needs quite a bit of polishing.  I also disliked not having a distributed opml or something so that I could access all of my feeds on another computer.

I have since crossed over and succumbd to web-based RSS Feed readers.  I’ve tried Google Reader, Newsgator, Bloglines, and others… but I didn’t like any of them.

My new friend for RSS feeds is Newshutch.  Incredbily simplistic, but functional.  The interface doesn’t get in my way and the nice use of Ajax means that I can leave the window open and it will automatically get my feeds for me.  As I read an entry, I can click 1 button and have that entry fade away and the ones below it to float to the top.  This fits nicely with the way I like to read blog posts, so this one is most-likely here to stay.