Updates from October, 2010 Toggle Comment Threads | Keyboard Shortcuts

  • danielsaidi 11:18 pm on October 8, 2010 Permalink | Reply
    Tags: ,   

    Getting started with git and GitHub 

    As some of my hobby projects are coming together nicely, I have been wanting to host them on GitHub instead of Google Code for quite some time. Tonight, I decided to give it a try.

    First of, I visited the Git OS X download page and downloaded the latest release of git. Second, this help page was a real treat. It contains a lot of info. However, I soon found myself entering commands into the terminal without any understanding of what I was doing.

    Since I like to be in control, this naturally did not feel that good at all. However, my hobby projects eventually ended up on GitHub and I have a real incentive to master git.

     
  • danielsaidi 9:26 am on October 8, 2010 Permalink | Reply
    Tags: gac, nupack, package management   

    A quick NuPack walkthrough 

    Yesterday, I got myself a demonstration of NuPack – a free, open source developer focused package management system for the .NET platform. It looked awesome, so I qickly visited the web site, downloaded NuPack and installed it.

    This is how you do it. Brace yourself…it requires that you are 100% focused…ok?

    • Visit the NuPack web site.
    • Click the download button
    • Wait for the file to download (important!)
    • Double click on the downloaded file
    • Open any .NET solution of yours…or create a new one
    • Right-click references – voilá…a new “Add Package Reference” exists!

    I hope that you can understand the irony – this is really a walk in the park. This is what you’ll see:

    The Add Package Reference context menu item

    The Add Package Reference context menu item

     

    When you click “Add Package Reference”, a new window opens, where you can search for packages:

    The Add Package Reference Window

    The Add Package Reference Window

     

    In the image above, I have searched for log4net, which is a nice log tool for .NET. If I click the “Install” button, the package is downloaded and added to the project:

    The reference is added to References

    The reference is added to References

    …and if we look in the solution folder structure, it has created a new “packages” folder, which contains the downloaded package:

    A "packages" folder is added

    A “packages” folder is added

    Well, that’s it! If you need to use log4net in another project in the solution, just add a reference to the downloaded package. Simple, huh?

    A liiiiiitle note is that I noticed that the added reference points to the GAC:

    Strange behavior - the GAC is used as reference

    Strange behavior – the GAC is used as reference

     

    I do not know about you, but I’d rather refer to the physical .dll file. But hey, NuPack has downloaded it for me, so I can just remove the reference and re-add it and everything is sunshine and dancing clouds!

    Conclusion? Well…NuPack has rocked my world!

     
  • danielsaidi 8:45 pm on October 7, 2010 Permalink | Reply
    Tags: assembly metrics, constraints, , instability, metrics, , review, type metrics   

    Getting started with NDepend 

    So, after quite some time, I have finally got my thumb out and added an NDepend project to my new .NET Extensions 2.0 solution, in order to get some analyzing done before releasing it.

    The first thing that hit me was how easy it was to attach a new NDepend project to my solution. I just had to:

    1. Install Visual NDepend
    2. Open my .NET Extensions solution
    3. Under the new “NDepend” main menu item, select “Attach new NDepend project to solution”
    4. Select all projects of interested (I chose all of them)
    5. Press the OK button and pray to god.

    Once NDepend is attached to your solution, the menu will change and look like this:

    The NDepend menu

    The NDepend menu

    …but before that, it will perform a first-time analysis of all projects that it is set to handle. This is done automatically, so just bind NDepend to your solution, and it will perform the analysis…

    …after which Firefox (or, naturally, your default browser of choice) will come to life and display a complete analysis summary, which is generated in a folder called NDependOut:

    The generated NDependOut folder

    The generated NDependOut folder

     

    So, what the report has to say?

    Report sections

    The report is divided into certain sections, of which more (to me) are more interesing than others.

    The various sections of the NDepend report

    The various sections of the NDepend report

     

    Application metrics

    Well…first of all, a complete textual summary of application metrics is presented:

    The NDepend Application Metrics summary

    The NDepend Application Metrics summary

     

    Now, this summary contains a couple of interesting metrics.

    Note, for instance, the comment ratio (51%). I have always taken pride in commenting my code, but lately, I have focused on writing readable code instead 🙂  However, I have decided to overdo the commenting in this project, since it must be understandable for users that only get their hands on the DLL.

    Since .NET Extensions is mainly an extension project, I think that this summary is quite what I expected…even if I maybe could do with a bit more interfaces. Note that not much is going un “under the hood” – almost everything is public (in some cases for unit test purposes, which I will change #beginner-error).

    Also, since I am of the belief that one should NEVER work directly towards an object’s fields, I am happy that I have no public fields at all  🙂

    The last row (cut of) displays the method/function with the worst cyclomatic complexity:

    The worst CC in the solution

    The worst CC in the solution

    However, when I analyze the method with the Visual Studio analyzer, it says that the method has a CC of 13! Turns out that 25 is the ILCC (Intermediate Language Code Complexity) – the resulting CC. However, I will write a new blog post later on, in which I’ll use this information to improve the GetHtml() method. Stay tuned 🙂

     

    Assembly metrics + abstraction/stability summary

    After the interesting application metrics summary come some assembly metrics (also quite interesting) as well as information about for the stability of the different assemblies.

    First of all, everything is presented a textual grid:

    The NDepend Assembly metrics table

    The NDepend Assembly metrics table

    This information is then displayed in various graphical components, such as the Visual NDepend view (in Visual Studio, you can use NDepend to navigate through this view)…

    The Visual NDepend View

    The Visual NDepend View

    …as well as the Abstractness vs. Instability view…

    The Abstractness vs. Instability view

    The Abstractness vs. Instability view

     

    Now, let’s stop for a moment and discuss this graph. The word “instability” first made me feel like I had written the worst piece of junk there is, but I think that the word is quite misleading.

    As I’ve mentioned, the analyzed solution consists of a lot of extension and helper classes, which almost never are independent – they mostly depend on other base classes, since that is their purpose. If I have understood the term “instability” correctly, this is exactly what it means. The solution is instable since it depends on a lot of other components…

    …but for this kind of solution, it is hard to have it any other way. After reflecting over the graph a bit, and enjoying the green color (except for the so far empty build project), I understood what view intends to display.

     

    Dependencies, build order etc.

    This part of the report is probably a lot more interesting if you intend to delve into a solution of which development you have not been a part of earlier on.

    However, for this particular situation, this part of the report really did not give me anything that I did not already know.

     

    Amazing final part – constraints

    Finally, NDepend displayes an amazing part where the code is evaluated according to all existing constraints.

    For instance…

     

    One of the vast number of constraint summaries

    One of the vast number of constraint summaries

     

    …this part displays a constraint that selects all functions that:

    • Has more than 30 lines of code OR
    • Has more than 200 IL instructions OR
    • Has a cyclomatic complexity over 20 OR
    • Has an IL cyclomatic complexity over 50 OR
    • Has an IL nesting depth that is larger than 4 OR
    • Has more than 5 parameters OR
    • Has more than 8 variables OR
    • Has more than 6 overloads

    For instance, the first item in the list – Split() – is there because it has more than8 variables.

    Some of the default constraints are perhaps a bit harse, but most of them are really useful. Just having a look at these constraints and at how your code applies to them gives you a deeper understanding of how you (or your team) writes code.

     

    Type metrics

    Finally, comes an exhausting, thorough grid with ALL the information you can imagine about every single type in the solution.

    Type metrics

    Type metrics

    The “worst” cells in each category are highlighted, which makes it really easy to get an overview of the entire framework…although the information is quite massive.

     

    Conclusion

    Well, only having connected an NDepend project to my solution, I have barely scratched the surface of what NDepend can offer. To be able to extract this much info by just pressing a button, is quite impressive.

    I wrote this blog post yesterday, and have rewritten large parts of it today. During that time span, my stance towards it has shifted a bit.

    Yesterday, since I then did not understand parts of the report, I was under the impression that your own hobby project is not the best context in which to use NDepend…and that it comes to better use when working in a role (e.g. tech lead / lead developer) that require you be able to quickly extract data about the systems for which you are responsible. In such a context, NDepend is greaaat.

    However, after getting some time to “feel” how NDepend “feels” for me as a developer, I have started to see benefits even for a solution such as this extensions solution. As I will show in a future blog post, I can use the information I extract from NDepend to detect the parts of my framework that are “worst”…and makes it easy to adjust them, re-analyze them and see how my implementation grows better.

    It is a bit like comparing my iPhone with my iPad. ReSharper was like my phone – as soon as I started using it, I could not live without it. NDepend, on the other hand, is much like the iPad. At first, I really could not see the use, but after som time, it finds right into your day-to-day life and…after a while…becomes natural.

    I will scratch myself further down into NDepend. Stay tunes.

     
    • danielsaidi 9:11 pm on October 7, 2010 Permalink | Reply

      As you can see, this theme sucks for wide content…and code. Any advices??

    • Mattias 10:31 pm on October 7, 2010 Permalink | Reply

      The mobile theme on my iPhone doesn’t make it better. 😉

    • Mattias 6:59 am on October 8, 2010 Permalink | Reply

      Have you tried google.com? 😉

    • danielsaidi 8:06 am on October 8, 2010 Permalink | Reply

      Nooooo, but I often get letmegooglethatforyou.com links from my friends and collegoues 😉 Hmmm…maybe it’s worth paying those dollars to WordPress to unlock the custom CSS feature. 😛

  • danielsaidi 11:38 am on October 7, 2010 Permalink | Reply
    Tags: jqgrid, , onselectrow   

    onSelectRow fix for jqGrid 

    I just love the jqGrid jQuery plugin. If you haven’t tried it out yet, perhaps you should?

    Still, if you look up the online demos that describe how to edit a row, you may discover that the onSelectRow method used in the demos is not quite perfect. After editing a row, you must select a new one before you can edit the first one again.

    I replaced the original onSelectRow method…

    onSelectRow: function(id) {
       if (id && id!==lastsel) {
          jQuery('#rowed3').jqGrid('restoreRow',lastsel)
          jQuery('#rowed3').jqGrid('editRow',id,true);
          lastsel=id;
       }
    }

    …with this one…

    onSelectRow: function(id) {
       if (id) {
          if (id !== lastsel) {
             articleGrid.jqGrid('restoreRow', lastsel);
             articleGrid.jqGrid('editRow', id, true);
             lastsel = id;
          } else {
             articleGrid.jqGrid('restoreRow', lastsel);
             lastsel = "";
          }
       }
    }

    …and now, the grid behaves a lot more like I want it to.

     
  • danielsaidi 10:49 pm on October 5, 2010 Permalink | Reply
    Tags: ,   

    A really simple PHP Controller class 

    I have written a reaaaally simple Controller class to my hobby project, Wigbi. Even though it is SO basic, it will help immensely when developing MVC-based PHP web applications.

    The class has three properties – name(…), action(…) and viewData(…) – and one single method – addView(…). I will try it out in a couple of projects and see if it is good enough.

    Here is the code:

    <?php
    class Controller
    {    
     /**#@+
     * @ignore
     */
     private static $_currentViewData;
     private static $_action = "";
     private static $_name = "";
     private static $_viewData = array();
     /**#@-*/
    
     /**
      * Get/set the name of the current action.
      *
      * @access    public
      *
      * @param    string    $value    Optional set value.
      * @return   string              The name of the current action.
      */
     public function action($value = "")
     {
        if(func_num_args() != 0)
           Controller::$_action = func_get_arg(0);
        if (Controller::$_action)
           return Controller::$_action;
        if (!array_key_exists("action", $_GET))
           return "";
        return $_GET["action"];
     }
    
     /**
      * Get/set the name of the controller.
      *
      * @access    public
      *
      * @param     string    $value    Optional set value.
      * @return    string              The name of the controller.
      */
     public function name($value = "")
     {
        if(func_num_args() != 0)
           Controller::$_name = func_get_arg(0);
        if (Controller::$_name)
           return Controller::$_name;
        if (!array_key_exists("controller", $_GET))
           return "";
        return $_GET["controller"];
     }
    
     /**
      * Get/set view data.
      *
      * @access    public
      *
      * @param        string    $key        Optional key value, otherwise current, view specific data.
      * @param        string    $value    Optional set value.
      * @return    string                     The view data value.
      */
     public function viewData($key = "", $value = "")
     {
        if (func_num_args() == 0)
           return Controller::$_currentViewData;
        if (func_num_args() == 2)
           Controller::$_viewData[$key] = $value;
        return array_key_exists($key, Controller::$_viewData)
           ? Controller::$_viewData[$key]
           : null;
     }
    
     /**
      * Add a view to the page.
      *
      * If ~/ is used in the view path, Wigbi will auto-parse it to the
      * application root path.
      *
      * @access    public
      * @static
      *
      * @param    string    $viewPath    The path to the view file.
      * @param    string    $viewData    Optional view data; default null.
      */
     public static function addView($viewPath, $viewData = null)
     {
        Controller::$_currentViewData = $viewData;
    
        $viewPath = str_replace("~/", Wigbi::serverRoot(), $viewPath);
        require $viewPath;
    
        Controller::$_currentViewData = null;
     }
    }
    ?>

    In the application root, I place an .htaccess file with the following content:

    Options -Indexes
    Options +FollowSymLinks
    RewriteEngine On
    
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    
    RewriteRule ^([a-zA-Z0-9_\-]+)/?$                   controllers/$1Controller.php?controller=$1                        [NC]
    RewriteRule ^([a-zA-Z0-9_\-]+)/([a-zA-Z0-9_\-]+)$   controllers/$1Controller.php?controller=$1&action=$2    [NC]
     
c
Compose new post
j
Next post/Next comment
k
Previous post/Previous comment
r
Reply
e
Edit
o
Show/Hide comments
t
Go to top
l
Go to login
h
Show/Hide help
shift + esc
Cancel