I know the answer (it's 42)

A blog on coding, .NET, .NET Compact Framework and life in general....

August, 2006

Posts
  • I know the answer (it's 42)

    Use Team Build to make Tea

    • 0 Comments

    Why not? If someone can use MsBuild task to make coffee while the build is in progress, using Team Build for remotely making tea is trivial. Just take that task and modify it to make tea and plug it into Team Build.

    Fire your build on your home build machine and start driving home. By the time you reach home, your steaming cup of darjeeling tea will be ready for you.

  • I know the answer (it's 42)

    FlagsAttribute could've done a bit more

    • 5 Comments

    Definition of FlagsAttribute on MSDN sez "Indicates that an enumeration can be treated as a bit field; that is, a set of flags". It further goes on to indicate "Bit fields can be combined using a bitwise OR operation, whereas enumerated constants cannot".

    Enums are generally used in situations where mutually exclusive elements are required. However, an enum can be decorated with this FlagsAttribute to indicate that they are bit flags and can also be combined (ORed, ANDed) so that it can also be used in situations where combination of elements are also valid.

    When I first encountered this FlagsAttribute I assumed (devs do that a lot :) ) that the values generated for these enums are no longer incremented by 1 but are bit incremented.

    [Flags]

    enum MyFlagEnum

    {

    None,

    First ,

    Second,

    Third,

    Fourth

    }

    So in the case of the above enum I expected that None=0, First=1, Second=2, Third = 4, Fourth=8. Only if this assumption is true we can have bit flags work correctly. Otherwise First|Second will become equal to Third and hence would be indistinguisable from Third.

    However, much later I learnt with surprise that this is not true... Even if the attribute is used enum members are just incremented by one. So that Third is 3 and not 4 and Fourth is 4 and not 8.

    This can have surprising consequences as demonstrated by the code below

    using System;

    using System.Collections.Generic;

    using System.Text;

    namespace FlagAttribute

    {

    [Flags]

    enum MyFlagEnum

    {

    None,

    First ,

    Second,

    Third,

    Fourth

    }

    class Program

    {

    static void Main(string[] args)

    {

    foreach (MyFlagEnum myEnum in
    Enum.GetValues(typeof(MyFlagEnum)))

    {

    Console.WriteLine("{0,-10} => {1}", myEnum,
    myEnum.ToString(
    "D"));

    }

    Console.WriteLine((MyFlagEnum.First | MyFlagEnum.Second)
    ==
    MyFlagEnum.Third);

    Console.WriteLine(MyFlagEnum.First | MyFlagEnum.Second);

    Console.WriteLine(MyFlagEnum.Second | MyFlagEnum.Fourth);

    }

    }

    }

    None       => 0
    First      => 1
    Second     => 2
    Third      => 3
    Fourth     => 4
    True
    Third
    Second, Fourth

    The problem here is that the value of First|Second is 3 and hence there is no way to distinguish it from MyFlagEnum.Third. However in case of  Second|Fourth the value is 6 and hence the sytem correctly printed it to Second, Fourth.

    This can be corrected only by manually giving correct values to the enum members as...

    [Flags]

    enum MyFlagEnum

    {

    None = 0,

    First = 1,

    Second = 2,

    Third = 4,

    Fourth = 8

    }

    So what did we gain from the FlagsAttribute, not much I guess...

  • I know the answer (it's 42)

    C#: When indexers no longer remain cool

    • 7 Comments

    Manish was using a library for some image manipulation and hit upon a class which uses indexer. Indexer allows a class/struct to be indexed in the same way as an array. This is typically used by classes that encapsulates some other collection and wants to expose that collection using this technique. Lets first see how a class implements an indexer

    class MyClass

    {

    private int[] arr = new int[100];

    public int this[int index] // Indexer declaration

    {

    get {

    if (index >= 0 && index < 100)

    return arr[index];

    else

    return 0;

    }

    set {

    if (index >= 0 && index < 100)

    arr[index] = value;

    }

    }

    };

    MyClass mc = new MyClass();

    mc[0] = 10;

    mc[1] = 20;

    Console.WriteLine(mc[0]);

    Console.WriteLine(mc[1]);

    Funny thing was that the class implementor simply forgot to expose the length as a property so that in code we can use it for interating through the class as follows

    class MyClass

    {

    private int[] arr = new int[100];

    public int this[int index] // Indexer declaration

    {

    get { ... }

    set { ... }
    }

    public int Length

    {

    get { return arr.Length; }

    }

    };

    MyClass mc = new MyClass();

    mc[0] = 10;

    mc[1] = 20;

    for(int i = 0; i < mc.Length; i ++)

    Console.WriteLine(mc[i]);

    }

    Without the length property being exposed in some means, its totally impossible to index into the class meaningfully.

    Moral of the story: If you have a class that uses indexer, expose the length or max value of the index as well....

  • I know the answer (it's 42)

    C# Anonymous methods, lambda expressions and Ruby

    • 4 Comments

    In my last post I had discussed about anonymous methods.

    I had used the following code snippet to show how anonymous methods can be used to print out a List<string>

    List<string> nameList = new List<string>();

    nameList.Add("Abhinaba");

    nameList.Add("Kaushik");

    nameList.Add("Samrat");

    nameList.ForEach(
    delegate (string str) { Debug.Print(str);});

    jeswin's comment on that post was "the ugliness is really apparent at the callsite ... Once we see lambdas and automatic type inference in C# 3.0, a lot of people will start using it. With LINQ, at least this is as concise as Ruby. "

    He hit my sweet spot about Ruby and how languages like C# are poaching into its domain. Lets see how I'd code this is Ruby

    $nameList = [ "abhinaba", "kaushik", "samrat" ]
    $nameList.each { |str| puts str }
    

    This is concise and intuitive as for each element run this block of code. But with C#3.0 (LINQ) coming up, this can also be done as concisely with the usage of lambda expressions. The following code is valid C# 3.0

    List<string> nameList = new List<string>{ "abhinaba", "samrat", "kaushik" };

    nameList.ForEach(str => Console.WriteLine(str));

    So the ugly delegates and explicit type parameters have gone away. This is concise but is it really understandable by C#'s target audience?

    One more interesting thing about the code is the first line where I was able to initialize the collection by directly passing the elements using the C# 3.0 Collection Initializer.

    However, I am not a great fan of adding language features like this in C#. Every language has a style and a target audience and I don't think dynamic/functional programming concepts creeping into C# is a healthy trend.

  • I know the answer (it's 42)

    Do programmers really use Anonymous methods

    • 8 Comments

    Anonymous methods provides a  elegant way to inline callback functions (delegates). Anonymous methods typically work in the situation where you don't have significant amount of code in the callback and hence don't want to take the trouble of defining a function for it. It makes maintenance a lot easier as you don't have to jump to the definition to see what the function does.

    However, do people really use it? In my day-to-day coding I rarely use them. Because I rarely have callbacks that do small things that make it a good candidate for anonymous method. In my mind anonymous methods find use in the following scenarios

    1. Event handlers
    2. Delegates that need state
    3. Function generators (for using in functional programming style coding)
    4. In Predicates/Actions/Converter delegates

    However most of the event-handlers I use are UI event handlers and they are inserted by the designer which does not create anonymous methods. I don't want to get into the trouble of manually changing them. Delegates that need state are also large functions and hence not a good candidate. In production code I would rarely use a function generator so that's out too.

    The last one is generally a good candidate. Consider the following code that finds an element in a collection and then prints out the entire collection (List<>

    List<string> nameList = new List<string>();

    nameList.Add("Abhinaba");

    nameList.Add("Kaushik");

    nameList.Add("Samrat");


    string
    searchName = "Abhinaba";


    // find using a Predicate<T>

    bool found = nameList.Exists(

    delegate(string name)

    {

    return name == searchName;

    });


    // Iterate using Action<T>

    nameList.ForEach(delegate (string str) { Debug.Print(str);});

    Especially the last usage in ForEach brings out the elegance you can achieve using anonymous method. But still I'd guess that the usage of anonymous method will be very limited in production code.

  • I know the answer (it's 42)

    Stylistic differences in using

    • 4 Comments

    There are two ways in which you can use using directive as outlined below

    Style 1

    using System;

    using System.Collections.Generic;

    using System.Text;

    namespace MyNameSpace

    {

    // ...

    }

    Style 2

    namespace MyNameSpace

    {

    using System;

    using System.Collections.Generic;

    using System.Text;

    // ...

    }

    With respect to scoping both the styles have the same effect on all the code inside the MyNameSpace.

    Microsoft tools seem to differ in which style is preferred. Style-1 is used by the source template in the CSharp projects, so if you create a new project the files generated will use the first style. However, in case you use CodeDom to generate code in C#, it uses the second style (note in VB.NET it uses the first style).

    Stylecop also fails the first style with the note that Using directives must be inside of a namespace element.

    I am using CodeDom to generate some code and I tried to figure out the benefits of the 2nd style as the code is generated in that format. I found out the following benefits

    1. Lowers the chances of namespace pollution in case the source file has more than one namespace declaration in it
    2. Reduces the size of the drop down in intellisense
    3. Conflict detection in aliasing

    Jay Thaler pointed me out the last one. The example goes as follows

    using System;

    using Uri = System.Uri;

    namespace MyNamespace

    {

    public class MyClass

    {

    public void DoIt()

    {

    new Uri();

    }

    }

    public class Uri

    {

    }

    }

    In this code the class Uri will silently override the Uri alias. However, compilation of the following will fail with error CS0576: Namespace 'MyNamespace' contains a definition conflicting with alias 'Uri'

    namespace MyNamespace

    {

    using System;

    using Uri = System.Uri;

    public class MyClass

    {

    public void DoIt()

    {

    new Uri();

    }

    }

    public class Uri

    {

    }

    }

     

     

  • I know the answer (it's 42)

    Ahlen, Kasumai, Amole, Ezender, Wiñamek - ClustrMaps for tracking blog hits

    • 0 Comments

    I first noticed it on Rob Caron's blog. Provided by http://clustrmaps.com/, it's a map of the world with red dots on it indicating hits to that blog from various countries.

    The idea is simple, you need to embed a html snippet into your blog and this snippet refers to an image. The browsers tries to get the image from ClustrMaps and that server tracks the browsers IP to detect which country it belongs to.

    I got interested and inserted this in my blog couple of days back. What I found was very interesting. As expected United States and European countries where high in the hit-list. But I also saw countries which I have never heard before or exotic places I have read about but never thought someone would read my blogs from. Some of them are

    • Africa: Senegal, Nigeria, Namibia, South Africa, Egypt, Morocco, Tunisia, Iran
    • Asia: Oman, UAE, Iran, Pakistan, Celebes Island Indonesia, Siberia-Russia
    • Iceland
    • Americas: Columbia, Peru, Argentina, Venezuela, Ecuador, Caribbean Island-Jamaica

    I had thought readership in China would be much higher but looks like I guessed wrong. I think it's be due to language differences. It's time I learnt Mandarin :)

    For people inquisitve about the title; they are "hello" in different languages.

  • I know the answer (it's 42)

    Team Build Ticker: parting gift

    • 21 Comments

    I had blogged earlier about the BuildTicker tool which sits on the system tray and notifies of builds happening on the server. I have received many requests to get this tool. So here it goes. Get the executable from here and the sources from here. Since I am no longer working on the TFS team you can consider this as my parting gift :)

    Disclaimer

    1. This tool was never formally tested. However it is being used by me everyday.
    2. It comes with no support. In case you hit issues report it in this blog and I'll try to resolve it here.

    Features

    1. Does not need TF client to run
    2. Runs from System Tray
    3. Can monitor multiple TF servers and Build Types
    4. Shows pop-ups to notify of builds
    5. Tray animation to indicate successful/failed builds
    6. Integrated to the TF web-ui and you can click it to bring up a Team Build web-report
    7. Auto start(after restarts)

    Known Issues

    1. First time you run it, it starts silently in the tray without bringing up the configure dialog.
    2. The pop-up takes away focus (can be majorly irritating when you are typing in some window). However the good news is that after the pop-up closes in a second or two the focus is restored.
    3. The application needs to be restarted sometimes when you change the TF and Build Types it is supposed to monitor
    4. Doesn't maintain the list of builds it has captured till date.

    How to use

    1. Unzip to a folder and run the executable
    2. Right click on the Build Ticker icon in the tray and choose Open Build Ticker
    3. Choose Server and enter your server and  build type details
    4. Close the dialog. Sometimes it might be required to restart the application at this point
    5. Start getting notifications

    However, I'd recommend that you use the Rss Feed generator and point a windows authentication capable feed-reader like RssBandit to it.

  • I know the answer (it's 42)

    Ruby.NET

    • 5 Comments

    I had blogged earlier about Gardens Point Ruby.NET. After I read Don Box writing about it, I decided to give it a try.

    I tried compiling some Ruby code. I failed to get the retry code to run. It kept giving "Unable to cast object of type 'Ruby.Object' to type 'Ruby.Class'" error.

    I tried to compile other code like the webserver and line number and also closure code. Most of them compiled and worked. However wherever I had references to ruby library classes it failed to run due to lack of support. Since any piece of code that accomplishes something significant is bound to use some of these libraries it'll be difficult to truly check out Ruby.NET until it supports these libraries. However if calling .NET BCL libraries becomes possible it'll open a Pandora's box!!!

    Overall I was fairly impressed with it. Especially a look into the generated exe using Reflector made my brain hurt. I'm sure it'd have been immensely difficult to fit a dynamic language like Ruby into a static-typed CLR. Facts like ruby methods can be dynamically added and removed from classes and that a class can be arbitrarily spread across files with no inter-connection between them complicates the whole thing.

    The ability to call .NET framework from the Ruby code should've been enabled. With that the true power of Ruby.NET would have come out. Or did I fail to figure out how that can be done??

  • I know the answer (it's 42)

    Front license plates are not required in NC and many other states in the US

    • 1 Comments

    While this can be very common and insignificant information for most people in US and specifically those from the 19 states that doesn't officially need a front license plate, it caught us by surprise. 

    We (me another colleague Neeraja) went to Microsoft Raleigh (in NC) for some work. Early morning we got down at the airport and reached Avis car rental. We were given the car number and so we headed towards the parking lot. The first car didn't have a number plate and so we went to the next and the next and the next. Puzzled we went to the attendant and told him none of the cars have number plates. He explained and we went to the back of the car and finally found the one we were looking for!!

    Its another thing that Neeraja felt that the car, a Chevy HHR was the ugliest looking car she had ever got into. I kind off liked it though. However, we can vouch for one of the claims they're making on the web-site the hidden rear cargo compartment. We didn't see it, so it must've been well hidden.

  • I know the answer (it's 42)

    Null pointer access in C++

    • 4 Comments

    Language implementation quirks can lead to interesting things. Lets say I have the following C++ code.

    class MyClass

    {

    int i;

    public:

    void foo()

    {

    cout << "Hello" << endl;

    //i = 5;

    }

    };

     

    int main(int argc, char* argv[])

    {

    MyClass *mc;

    mc->foo();

    return 0;

    }

    What is the outcome of this piece of code? Since we haven't allocated mc and accessing foo via an unassigned pointer most people expect a crash. However on most compilers this is garaunteed to print "Hello" with out any crash.

    What is important to note here is that since foo is not a virtual method the lookup doesn't go through the vtable and hence mc->foo() call is compiled here as MyClass::foo(null)through appropriate mangled name). As long as foo doesn't access any of the instance member of MyClass the null this pointer remains unused. If the commented line is foo is uncommented we get a crash.

    If the foo method is made virtual then lookup goes thrugh the vtable and the application crashes.

Page 1 of 1 (11 items)