Ayende @ Rahien

It's a girl

Certifications: Part II

So I did 70-316 exam a few hours ago, and I am not really happy about it.

It included questions about setup/deployment, security, localization as well as many questions about using datasets and accessing data. I think there was a single question that I could say related to WinForms: how to stop resizing a form.

Two questions I really dislike:

  • I had to answer with " SET NOCOUNT OFF " - I don't know what it has to do with a Windows based applications, to tell you the truth.
  • Another "memorize the API / Find the difference question". The answers were something along the lines of:
    • foreach(SqlError err in myExp.Errors)
    • foreach(Exception ex in myEmp.Errors)

On the other hand, it does seem more relevant to the windows world, where you don't just use System.Windows.Forms.

After talking to Howard, I decided to take the 70-528 to see what the new certification model has to offer.

TestDriven.Net 2.0 is out, and it is exciting!

Zero Friction Unit Testing has always been TestDrive.Net strongest point, but with this new release, it bring it to a whole new level.

I feel that some of the new features are made for me, take this one for instnace:

(Image from clipboard).png

That one was a personal request of mine, and I am going to really worn this botton.

There is now integration with a host of new frameworks, from TypeMock to Zanebug. But this isn't something that make me happy. What does make me Happy is this, Reflector integration:

(Image from clipboard).png (Image from clipboard).png

Do you see the value that this is going to bring? Just being able to (so very easily) setup breakpoints in any code that I want is a good idea, and being able to go from 3rd party call ot its source at the press of a key is really impressive. This is going to be a shortcut key the moment I can decide which functionality I need the least (Ctrl+X, Ctrl+C, Ctrl+V).

Orand has all the details about using this.

Great work, Jamie.

User Group Lecture : Summary

Justin was sick and couldn't make it, but Roy filled in for him with a lecture about Regexes. My lecture was the second one, and I think it went very well. I managed to show everything that I planned to (although not all that I wanted), and actually got to the last slide on time, which was a major worry for me.

Things to improve:

  • This is supposed to be an entry level user group - but I feel that I had answered too many questions at a higher level than may have been appropriate. This was probably because those were good questions, but I probably should have saved
  • It is probably not a good idea to show the SQL code from NHibernate when the dialect is set to SQL 2005 - when you start to use paging scray stuff with CTE are starting to happen, which just confuses people.
  • I noticed mid way that I sometimes get stuck in the middle of explaining a complex concept. This is because to understand the concept you need to understand a whole lot of stuff behind it, which I simply can't explain in a short time frame. As a result, there were several cases where I started a sentence, paused with an "Ah..." and then had to bail out by saying it is too complex.



Published at

Yesterday Stats

  • One Class
    • 2,333 Lines of code
    • 89 Lines of code in a single property
    • 125 Lines of code in a single method
    • 30# Cyclomic Complexity in the afore mentioned method
  • One Enterpise Document
    • Metric Ton of bullshit
  • Zero SQL in my project


Bringing it all together: Even More Magic,

So, I had done a couple of fairly cool stuff recently, but it is all in seperated pieces, let us try to bring them together and see what we get, shall we?

ProjectionQuery<User> query =

       new ProjectionQuery<User>(Where.User.Name.Like("Ayende", MatchMode.Start),

                                 ProjectBy.User.Name && ProjectBy.User.Email);

foreach (object[] objects in query.Execute())


       Console.WriteLine("Name: {0}, Email: {1}", objects[0], objects[1]);


That is nice, isn't it? Again, we can use the strongly typed version to be type safe and avoid the use of arrays as DTO:

ProjectionQuery<User, NameAndEmail> query2 =new ProjectionQuery<User, NameAndEmail>(

       Where.User.Name.Like("Ayende", MatchMode.Start),

       ProjectBy.User.Name && ProjectBy.User.Email);

foreach (NameAndEmail nameAndEmail in query2.Execute())


       Console.WriteLine("Name: {0}, Email: {1}", nameAndEmail.Name, nameAndEmail.Email);


And yes, this is filed under Linq as well.

C# != C++ : Sometimes I need a reminder

Apperantly mixing implicit operators and params array is not something that you should do. The C# Compiler refuse to understand that it can first implictly convert to the type and then satisfy the params array decleration.

Sometimes it is not worth getting up in the morning. That ruined a beautiful API.

Projections Support In Active Record

Ken, this post if for you...

So, I have been a busy implementing crazy generics stuff and I can show you this:

public class ProjectionQuery<ARType> : ProjectionQuery<ARType, object[]>

Neat class, isn't it?

Please not that this is not the same class that I shows here, that class has been renamed ScalarProjectionQuery, since it better fits its duy.

What can you do with it? Well, things like this:

ProjectionQuery<Blog> proj = new ProjectionQuery<Blog>(
Projections.Property("Name"), Projections.Property("Author"));

IList<object[]> results = proj.Execute();

Assert.AreEqual(blog.Name, results[0][0]);

Assert.AreEqual(blog.Author, results[0][1]);

Now you have got a list or arrays, which contains just the Name and Author from the Blog entity. This used to be much harder and involved writing HQL code (which can be a bummer, since I insist on putting all the HQL code in the mapping files, and not concatenating HQL).

It still has a major issue for me, and that is the fact that I need to work with untyped arrays, not fun, and I simple hate to work with numeric indices. Therefor, let us try this version:

public class ProjectionQuery<ARType, TResultItem> : IActiveRecordQuery

What does this allows me to do? Well, you can write the above snippet of code as:

ProjectionQuery<Blog, KeyValuePair<string, string>> proj = new ProjectionQuery<Blog, KeyValuePair<string, string>>(

               Projections.Property("Name"), Projections.Property("Author"));

IList<KeyValuePair<string, string>> results = proj.Execute();  

Assert.AreEqual(blog.Name, results[0].Key);

Assert.AreEqual(blog.Author, results[0].Value);

Notice that we suddenly have a strongly typed (if generic) way of accessing the information. In fact, in this case, a small, dedicated, class is what I would use. So I could do this:

ProjectionQuery<Blog, NameAndAuthor> proj = new ProjectionQuery<Blog, NameAndAuthor>(

                           Projections.Property("Name"), Projections.Property("Author"));

IList<NameAndAuthor> results = proj.Execute();

Assert.AreEqual(blog.Name, results[0].Name);

Assert.AreEqual(blog.Author, results[0].Author);

Much, much, nicer, in my opinion. :-)

And yes, there is more suprises in the pipeline :-)

NHibernate Query Generator 1.7

Well, it is certainly an interesting release. This release contains very little code of mine, mainly minor adaptations of two wonderful patches that were sent to me.

  • The first by Bas Jansen - which added inheritance detection from the mapping files.
  • The second by Adam Tybor - which added support for projections and group by.

Me, I just fixed a stupid bug by yours truly that would refuse to recognize exe as valid assemies, and put those two patches together.

Together, they make quite an addition to NQG. Especially when combined with some thing that can really understand projections... which is soon to come.

You can get it here.

Generic Specialization

It is not often that I am arriving to work and the first application that I open is Visual Studio, and I can't get it to open fast enough. Today was such a day, mostly because I got an Eureka moment. It is not often that I get those, so I really want to try it out.

Check out the following code:

public class Aggregator<T> : Aggregator<T, List<T>>



public class Aggregator<T, TCollection>

     where TCollection : ICollection<T>, new()


     private ICollection<T> collection = new TCollection();


Can you tell why I am excited? Because this means that I have static generic specialization (I already have dynamic generic specialization, thanks to Windsor) back!

Notice that for all intents and purposes, I can either use Aggerator<T>, or use the more generic version of Aggerator<T, TCollection>, which allows me to pass my own ICollection<T> implementation.

This is actually compiler supported Inversion Of Control!

Now, of course that I can do this using ctor parameter, but this puts the burden on the client code, and couples the base implementation to the defaults. This approach keeps the base implementation frees from any default whatsoever.

I intend to make use of this soon, so I'll post about the results.

Bug Tracking, Round II

I got a ton of suggestion to my Bug Tracking? question. As I mentioned, I don't want to use BugZilla, and JIRA is out of the immediate price range that I have in mind - I really want it to be free :-) And although anything without per-user cost is good, JIRA is expensive, although it certainly worth the price.

I tried Gemini, but I managed to hit two seperate bugs in the space of an hour, one of them a show stopper, and it didn't have an integration with Active Directory, which means that I need to handle more passowrd (bad thing in general). Leaving that aside for now, because I really liked the UI and it uses NHibernate.

I then started trying Trac, which was a bit hard to install on Windows, but I managed. The UI is really nice, and I love the SVN integration. It took me a couple of minutes to set it up with mod_python and Active Directory integration, so I don't need to remember yet another password. I'm not crazy about the command line interface to admin the project, but it has a reasonable CLI UI, so it is not that bad. I tried the web admin plugin, but it didn't work that well (kept erasing all the settings). One thing that bugs me :-) is that I can't seem to figure out how to set a default component / ticket type / version.

Thanks for everyone who gave a suggestion to the previous post. I think that we will try that out for a while and see how it goes.


Published at

Amusing error

I got this error trying to build the mod_python extention:

error: The .NET Framework SDK needs to be installed before building extensions for Python.

I am not sure what to say about this...


Published at

Great Interview Question

I'm constantly on the look up for good questions to ask in interviews, mainly because "describe the page life-cycle" gets boring and I would like to get away from the page lifecycle myself. The problem with finding good questions is that it has to expose as much knowledge from the candidate, while keeping the answer short and possible to answer within the time limits of an interview.

Here is one that I just thought of:

Given an Employee class, create a collection that accepts employees but doesn't allow duplicate employees to be entered. You are free to use any of the classes in the .Net framework.

Basically, build a set class. This is a good question in my opinion because it tests a wide range of knowledge, in a short question, which can be implemented in about 10 minutes. The question test the following:

  • Basic data structure / efficencies knowledge - if they decide to use ArrayList and compare each time, that would cost in both time to develop and performance
  • Thinking toward reuse - if they implement this from scratch (starting from building growable arrays and moving forward), that means that they either have a problem with knowing the building blocks of the framework or they suffer from NIH.
  • Understanding basic idioms of the framework - implementing IEnumerable will make the collection usable for foreach(), for instnace.
  • Understanding how low level stuff works - can they explain what reference equality vs. value equality is, can the explain how the Dictionary works?

It then leads to another question:

In certain circumstances, I wasnt to be able to able to allow no employees with duplicate names, how would you extend the collection to support this?

And this question tests how they can extend an existing class, and whatever they can come up with something that fits into the .Net idioms cleanly. Adding a boolean to check for an employee name is not a good way to do this.

Here is what I would consider an excellent implementation (not great, because it doesn't implement ICollection<T>):

public class EmployeesSet : IEnumerable<Employee>


       Dictionary<Employee, object> internalDic;


       public EmployeesSet()


              internalDic = new Dictionary<Employee, object>();



       public EmployeesSet(IEqualityComparer<Employee> comparer)


              internalDic=new Dictionary<Employee, object>(comparer);



       public void Add(Employee item)






       public bool Contains(Employee item)


              return internalDic.ContainsKey(item);



       public bool Remove(Employee item)


              return internalDic.Remove(item);



       public int Count


              get { return internalDic.Count; }



       public IEnumerator<Employee> GetEnumerator()


              return internalDic.Keys.GetEnumerator();



       IEnumerator IEnumerable.GetEnumerator()


              return internalDic.Keys.GetEnumerator();




Published at

War Stories: Check the stupid stuff, too

Mission Critical application, running quitely in production, suddenly stopped working. No warning, not errors. The application is still up, still running, but for all intent and purposes, it is not operational. I get a call that basically says: "Fix it!"

The main interface to this application (windows service) is a huge amount of logs that is being outputed. The target for the logs is the same SQL Server database that the application is using. Any error in this application should be logged and some errors should go directly to the administrators (and me).

But, the application is not doing its job, and worse, it doesn't write anything to the logs. This is a heavily multi-threaded application, so the first thing that I thought of was a deadlock, but restarting the application didn't help. I am on the phone with the sys-admin, going over the application configuration, trying to figure why it doesn't even log its startup event (which is singled threaded, so no chance for deadlocks).

I give up and drive there. Restarting the service doesn't help, and no logs are written, even thought the cofniguration seems just fine. The first thing that I do is taking a look at the logs table. But it currently has about 500,000 records, so queries take longer than instantenous. I get annoyed and try to add an index for the main search criterias. It errors. I double-check my syntax and tries again. It errors.

This time I read the error. It says that it doesn't have enough space to create the index. I didn't think that it is that large an index, but now I operate on a hunch. I tries to insert a row to the database (row size: 40bytes or so). The database refuses, says that it doesn't have enough space.

They had a rigorous backup procedure that kept backups on the same disks as the database files and never purged them. Once I cleared some of the old backups, the application immediately resume normal processing.

Total time trying to fix the issue: ~3 hours.

Total time fixing the issues since arrival: ~10 minutes.


Published at

Querying collections in NHibernate

I got some interesting replies to my post about what not to do with ORM. I got several comments back, and the major one was how to do a query about an entity collections with using string concantation, which I said was a code smell.

Specifically, the most interesting challange was presented by Josh Robb, and it goes like this:

    m:n Author
    1:m Posts
        n:m Categories
        1:m Comments

Find all Posts where:

Blog.Author = 'josh' and Categories includes 'Nhibernate'  and a Comment.Author = 'ayende'.

This being a part of a search screen where you can searc h by mulitply criteria, which are change dynamically. This is interesting because is spans just about any interesting assoication type that exists. So I set up to figure out how to do this.

My first step was to try to understand what I want NHibernate to do, so I started by writing the SQL for the above query:





    [dbo].[Posts] post

INNER JOIN [dbo].[Blogs] blog

    ON post.post_blogid = blog.blog_id

INNER JOIN [dbo].[UsersBlogs] user2blog

    ON blog.blog_id = user2blog.blog_id

INNER JOIN [dbo].[Users] author

    ON author.user_id = user2blog.user_id


    author.user_name = 'josh' AND


                [dbo].[Categories] category

             INNER JOIN [dbo].[PostsCategories] post2category

                ON post2category.category_id = category.category_id


                category.name = 'NHibernate' AND

                post2category.post_id = post.post_id ) AND


                [dbo].[Comments] comment

             INNER JOIN [dbo].[Users] commenter

                ON comment.user_id = commenter.user_id


                comment.comment_postid = post.post_id AND

                commenter.user_name = 'Ayende' )a

Complex, isn't it? There may be better ways to do this, but that is the most straight forward way I could think of.  Here is the query in HQL:

select post from Post post, User user

where  user.UserName = 'Josh'

and    user in elements(post.Blog.Users)

and    exists (from  Category category

               where post in elements(category.Posts)

               and   category.Name = 'NHibernate')

and    exists (from  Comment comment

               where comment.Post = post

               and   comment.Commenter.UserName = 'Ayende')

It generate nearly the same SQL that I wrote by hand, but uses tetha joins instead of ansi joins (I am not sure why, but the end result is the same).

Just a reminder, this isn't just a single query, this is something that that needs to be built dynamically, and we wish to handle this without using string concantation. In general, this means using the Criteria API. The first problem is that NHibernate's Criteria API doesn't allow you to query collections. This is very bad when you consider that this query is all about collections.

Strings are bad, I said so myself, so I put decided to add this to NHibernate (add is too strong a word, I went to Hibernate's source, found the relevant piece of code, and ported that). Now NHibernate can execute queries like section 15.8 in this page. All fine and dandy, until you get to the point where you need to query many-to-many assoications. You can't do that using the Criteria API in NHibernate (nor in Hibernate, as far as I can tell).

Many to many assoications are a funny beast, since you need to join through a second table to get the real value. I played a bit trying to implement support for that, but I wasn't successfull in the time frame that I could dedicate to it.

But, as the politician said, "This is a great question, but let me answer this one instead.", let us see what happens when we don't have many to many collections, shall we? The model is this, I change the assoication from Blogs to users to be a many to one, so a blog can now belong to a single author and remove categories.

    m:1 Author
    1:m Posts
        1:m Comments

The query then becomes get all posts where:

Blog.Author = 'josh' and Post Title includes 'Nhibernate'  and a Comment.Author = 'ayende'.

That being the case, we can use the following code the create the query (again, SVN trunk only, I am afraid):

DetachedCriteria theComment = DetachedCriteria.For(typeof(Comment))




              .Add(Expression.Expression.Eq("Name", "Ayende"));


IList list = s.CreateCriteria(typeof(Post), "post")

       .Add(Expression.Expression.Like("PostTitle", "NHibernate",MatchMode.Anywhere))


              .Add(Expression.Expression.Eq("Name", "Josh"))



To conclude, at the moment NHibernate doesn't support queries over memebers of many to many collections using the criteria API (at the moment). But it does offer a good way to handle queries over memebers of collections in nearly all other cases.

So, allow me to retract my words a bit, if you have dynamic queries and you need to handle many-to-many assoication, HQL is your only choice. Nevertheless, I would strongly suggest to encapsulate this in an OO layer that would generate HQL under the cover, rather than build the HQL dynamically in the UI layer.

How to get started with NHibernate?

A lot of my posts about NHibernate assume a certain level of familarity with the library and what it can do. For someone who doesn't know NHibernate, I believe that it so much nonesense...

Anyway, this post is intended to give some information about kick-starting your NHibernate development.

The classic articles about NHibernate, at least for me, are the Server Side .Net ones, here and here, by Justin Gehtland.

There is, of course, the online manual, but that is for reference, not to get how to use it. The Officual Quick Start Guide will take you from "NHibernate, huh?" to wielding the NHibernate magic in a short time, but will skip the background. A great resource is this page, which aggregate a lot of this stuff.

There are two example applications for NHibreante: This one by Scott Bellware and this by Paul Wilson. While Cuyahoga is using NHibernate (and my site run on Cuyahoga), I wouldn't recommend it to a beginner, it is definately a very advance application.

Ben Scheirman has a good series of posts about this, actually is it not so much about NHibernate per se, but how to structure your project to make it easier to work with (in general, and with NHibernate):

Benjamin has a lot to say about NHibernate. And Nikola has a very nice introductory post ot it here.

The Hibernate In Action book is wonderful, but many are holding back because they don't want to read a "java" book. I know of at least one (good) NHibernate books that is going to be coming out soon, but until it does, Hibernate In Action remains the best resource to learning about NHibernate.


Published at

Refactor: My.Presentations From Internal To Public

It seems to me that I started to accomolate quite a few presentations, and in the spirit of not keeping stuff internal if I can make it public, I decided to publish them.

Here you can find all the public ones.

They are of varying quality, and are mostly used by me to keep me on track and not digress to interesting (but irrelevant) topics in mid talk.

Not suprisingly, most of them are about OR/M, specifically, Active Record and NHibernate. All the ones that start with "NHibernate " are from a course I gave on NHibernate nearly six months ago. The one about Active Record is from an internal presentation that I gave at work (not the one that I am going to give on Monday). There is also an Inversion of Control presentation that I never really had a chance to give for some reason, which I am particulary proud of.

Have fun, and if you intend to use this, I would like to get a link to any recording / video made.

My Jobs Site

Well, not exactly, but if you go to http://jobs.ayende.com you will find a customized version of Hidden Networks jobs, just for me.

Thanks for Alex for doing all the hard work... 



Published at

Messed up site...

[Via Eber Irigoyen] [Via Javi Moya's blog]

1. Highlight the text below
2. Ctrl+C
3. Alt+D (Ctrl+L in opera) (or just go to the address bar)
4. Ctrl+V
5. [Enter]


javascript:scroll(0,0); R=0; x1=.1; y1=.05; x2=.25; y2=.24; x3=1.6; y3=.24; x4=300; y4=200; x5=300; y5=200; DI=document.getElementsByTagName("img"); DIL=DI.length; function A(){for(i=0; i-DIL; i++){DIS=DI[ i ].style; DIS.position='absolute'; DIS.left=(Math.sin(R*x1+i*x2+x3)*x4+x5)+"px" DIS.top=(Math.cos(R*y1+i*y2+y3)*y4+y5)+"px"}R++}setInterval('A()',5); void(0);

Here is how my site looks like after doing this.

(Image from clipboard).png

Bug Tracking?

Any recommendation about a good bug tracking system? 

I really don't want to pay per user, that is for sure. So FogBugz is out, and JIRA is expensive to start with (although it is pretty amazing bug tracker). Trac looks really interesting, but I get too many errors that I am not sure how to solve when I try to use it (entirely my fault, I know), and it looks to me like it is a tool that really requires some learning.

I would rather that it would open source and wouldn't require a day or two to install on windows (e.g: bugzilla). Preferably with a nice UI.



Published at

Correction: MonoRail vs. WebForms

Ken Egozi reminded me that my issue is not with ASP.Net itself, but rather with the WebForms implementation. As someone who had done quite a bit of work with the internals of ASP.Net, I have nothing but respect to the way it is architected and impelmented, This is truly a really great platform. (Except the entire System.Web.Cache API, which is completely internal, and therefor very bad in my eyes).

Update: I forgot to mention another point about Ken's post/comment. He suggested a view engine in C# / VB.Net. Unfortantely, this is not easily possible. To be a little more correct, it is not possible without a lot of really hard work. Neither language is extensible in any meaningful way, which would lead to building a view engine that it mainly parsing strings to create the object model. Possible, certainly. This is what aspx pages are, after all, but not fun to do at all.

Ben Scheirman commented on my post with some interesting observations.

About encouraging postbacks:

I don't see this as a problem. As long as you're aware of areas where you'll benefit from user friendly urls and back-button-friendly navigation I think you can avoid areas where it sucks.

I have issues with technologies where I have the easy-way and the real-world-way approaches. I don't want to benefit from friendly URL and have to do something to enable the back-button. Both of them are core parts of the web. It should be painful to not use them, not the other way around.

About view state bloat, complexity, MIA, etc:

Sometimes this can be a blessing. When choosing persistence strategies for page state, you have a lot of options. That's a good thing!

The problem here is that the ViewState model encourages its use (and its bloat), an ASP.Net page may be composed from several hundreds of controls, and each of them has at least several properties in the ViewState, mostly those are completely not needed. "Page State" is not what the name of the columns in the grid was, but that get saved as well, for example.

ViewState itself is a very good idea, actually. I can certainly see a generic way of persisting data as a valuable assest, the problem with this is what I define as data, and worse, that the moment you start using it you are limited to the postback model, see the point above for details.

I am really just defending ASP.NET because I enjoy it immensely. It is a breath of fresh air from my days with ColdFusion, PHP, and ASP.

Actually, I have been known to say more than once that I would just as soon do it in ASP classic, since it would be so much simpler to understand what is going on and the #%@# page wouldn't decide to make to move the data from one control to another randomaly. ASP Classic had a lot of issues with the way it is implemented, yes, but as far as the model that you are working with in the real one. ( I am assuming that you kept the COM for BAL and ASP for UI, of course, which no one did. )

I commented on making simple things complex and on the MCP exam today. Well, here is the (correct) answer on how to get the data from a text box inside a grid:


Published at

To Google...

The Google Blog managed to piss a lot of people with their request to not use Google as a verb. The reason being the Xerox and Kleenex precedents.

I don't like the tone of their post, and I think that they are already too late. In the DNR Bulgaria show, one of the guests (can't recall who) said something to the effect of: "You can't put the exception stack on live.com and get the details."

This sentence was met with resounding shock on the part of the audiance (and me), as people to to figure out what he was meaning. Replace "live.com" with google and you get what he meant. (After anyone got that, hilarity enused... by the way).

Stand back, I am Certified!

(Image from clipboard).png

I just took 070-315 MCP test. Frankly, I was appalled by the level of questions that they had there. I speak here as both a technical guy and as a teacher. I used to be responsible for teaching and educating, and I am familiar with the concepts of good tests.

If I was handed this test for evaluation, even without the technical knowledge to judge the questions, I would have failed it. And question that has the following as answers is fatally flawed...

A) products.Merge(otherProducts, true);
B) products.Merge(otherProducts, false);

And that is leaving aside my own feeling about my own feeling about the whole DataSet / DataTable issue. Asking about the specifics of API in this manner is simply wrong. Especially when it is a boolean parameter. What are they testing, exactly?

Another question had the following query:

"select * from Users where UserId = " + userId

And the correct answer was something along the lines of:


I have so many issues with both question and answer that I don't know even where to begin. Given that I wouldn't hire anyone who tried to give me this code as an answer to a question, I have a lot of issues with this being a question.

Just a few notes:

  • Concatenating strings to create queries.
  • Not using parameterized queries.
  • Using raw numeric indexers to get the data from the query
  • Relying on the DB orderring of the columns.

I never had that much respect for certifications in the first place, but this is really pushing it. If this is the level of the tests, I am going to start putting job ads that says: "Not certified by Microsoft - BIG Plus."

Why I hate taking dependency on other people code...

When I need to write stuff like this one:



  This is because the get_Result can be null or undefined and this

  is considered a false value.


  return Messages.get_result() == true;

The sad part is that it took nearly an hour to figure out why this happened.

The really sad part is that I would waste my time trying to explain to the developers who wrote this code why this is not a good idea.

Published at