Oren Eini

CEO of RavenDB

a NoSQL Open Source Document Database

Get in touch with me:

[email protected] +972 52-548-6969

Posts: 7,527
|
Comments: 51,162
Privacy Policy · Terms
filter by tags archive
time to read 2 min | 293 words

I am one of those fellows that tend to run on the trunk.

What does it mean?  It means that I am using the latest version of the source for my projects. So, I am on the trunk for Boo, NHibernate and Castle (which can be tricky, since Castle isn't on NHibernate trunk).

This has significant advantages for an active OSS project, NHibernate's trunk has the multi criteria support, MonoRail's trunk has the testing support, and since stuff is moving in response to the needs of the users, it is evolving fast. Sean Chambers was impressed by how fast this can happen in many cases. (In others, it is a slower process, but still mostly visible.)

There are some disadvantages, people (recently it was mostly me, sadly) can break the trunk, or commit functionality that breaks your code. In general, I have not found this to be the case for the projects that I am working on. A lot of the committers are running on the trunk as well, and there is a big pressure to make sure that the trunk is stable (ready to ship) because I, at least, do ship from it.

The major disadvantage here, from my point of view, is using a piece of code that is still under development or review. The recent case was Criteria cloning in NHibernate, which has gone through some modifications to get to its current form. Personally, I don't find it onerous to do so, and those are usually rare.

The big advantage is that you get continiously improvements. I does reviews of the changes every now again (now limited to scanning the logs and looking at what has changed) and it keep amaze me how much good stuff is going in there.

time to read 1 min | 125 words

Alex has caught me red handed, opps, I went home last night and dropped to bed, doing only the necessary minor email preventance. I actually have something prepared that I want to post, but I just couldn't find the strength to finish it. (Later today, I promise.)

(Yeah, I got the joke)

This month I am at 114 posts (likely more when today is finished), which translate to ~3-4 posts a day, every day.

Do people actually read them? I have an unusual "is it worth a post" standard, and it is likely that I am producing noise.

I have been thinking about doing some delay posting, so you will get a post every time interval, rather than whenever I feel like posting. Thoughts?

time to read 1 min | 92 words

Jamie Cansdale has just published the email corrspondance between him and Microsoft about TestDriven.Net on the Express SKU. Among other things, this has led to him losing him MVP status, pulling the TD.Net express, and more than a bit of angst. The clause that they are using is: "You may not work around any technical limitations in the software."

I strongly suggest reading the entire set of emails, and considerring that the clause they choose to use, that includes everything that they don't like, from key shortcuts to VS Macros.

time to read 2 min | 252 words

In an eerily similar timing, Fowler manages to hit a lot of the stuff that I am feeling, and he is doing it much better than I could.

This paragraph has certainly hit a note:

The attitude to open-source is a large part of this problem. When Java appeared there were yawning gaps in its portfolio, and worse some dreadful standard tools in its API (visions of Entity Beans spring to mind). Those gaps and bad ideas were fixed by the open-source community. Ant gave us a build tool, EJB was displaced by Spring and Hibernate. .NET has also got its gaps, and again the open source community has stepped up to fill them. Yet Microsoft refuses to collaborate with these efforts, even seems to go out of its way to undermine them. I was particularly sickened by Microsoft's reaction to NUnit - an excellent XUnit testing tool, elements of whose design were lauded by Anders Hejlsberg at OOPSLA. Microsoft ended not just bringing out a competitive library, but deliberately making it incompatible. That's not the kind of reaction that encourages people to invest their time in the platform.

That is one of the more frustratinng points in working in the Microsoft space, Microsoft is actively competing against its own community, and that diminishes the entire community (and Microsoft as well).

time to read 15 min | 2858 words

Okay, here is another exampe of using Cecil, but I think that you can figure out what I think about having to deal with raw IL.

Feel free to figure out what this does, and why I would be interested in such a thing. BTW, in Boo to Boo, that sort of thing so painless. Having to deal with the raw IL takes all the fun out of it.

I know about Cecil.FlowControl, but as far as I can find, this is mostly (only?) for reading assemblies. I am looking for a way to have a reasonable AST over cecil. This is not scalable no matter how you cast it.

import Mono.Cecil

import Mono.Cecil.Cil

class DisposableAttribute(Attribute):

      def Process(t as TypeDefinition):

            disposed = FieldDefinition("___was_disposed",t.Module.Import(bool), FieldAttributes.Private)

            t.Fields.Add(disposed)

            t.Interfaces.Add( t.Module.Import(typeof(IDisposable)))

           

            for method as MethodDefinition in t.Methods:

                  cil = method.Body.CilWorker

                  ins = method.Body.Instructions[0];

                 

                  if method.Name=="Dispose":

                        cil.InsertBefore(ins,cil.Create(OpCodes.Ldarg_0))

                        cil.InsertBefore(ins,cil.Create(OpCodes.Ldc_I4_0))

                        cil.InsertBefore(ins,cil.Create(OpCodes.Stfld, disposed))

                        continue

                 

                  wasDisposedLoc = VariableDefinition(t.Module.Import(bool))

                  method.Body.Variables.Add( wasDisposedLoc )

                 

                  cil.InsertBefore(ins,cil.Create(OpCodes.Ldarg_0))

                  cil.InsertBefore(ins,cil.Create(OpCodes.Ldfld,disposed))

                  cil.InsertBefore(ins,cil.Create(OpCodes.Ldc_I4_0))

                  cil.InsertBefore(ins,cil.Create(OpCodes.Ceq))

                  cil.InsertBefore(ins,cil.Create(OpCodes.Stloc_0))

                  cil.InsertBefore(ins,cil.Create(OpCodes.Ldloc_0))

                  cil.InsertBefore(ins, cil.Create(OpCodes.Brtrue_S,ins))

                  cil.InsertBefore(ins,cil.Create(OpCodes.Ldstr, t.FullName))

                  cil.InsertBefore(ins,cil.Create(OpCodes.Newobj,
                                      t.Module.Import(typeof(ObjectDisposedException).GetConstructors()[0]) ))

                  cil.InsertBefore(ins,cil.Create(OpCodes.Throw))

Chris, compiler!

time to read 10 min | 1937 words

No, it is not a rant against some non OSS tool.

When I was at DevTeach, I talked with a few people that mentioned that their compnay has an... aversion to OSS and they wanted a way around that. Beind technical minded and a "rules, what rules?" types of guy, I suggested that they would take an OSS project (assuming the license allows it), and just rename the namespaces.

This is a possible approach, but it may be too much work in many cases. I suggested post compile weaving, and people looked at me as if I have grown two heads ( I didn't, I checked ). I just now remember this conversation, and wrote this little script with Boo and Mono.Cecil, which would take an existing assembly and rename everything from an old value to a new one.

Usage:

booi AsmReplace.boo Castle.ActiveRecord.dll Castle Tower

Now enjoy your Tower.ActiveRecord.dll :-)

import Mono.Cecil

import System.IO

 

if argv.Length != 3:

       print "Usage: booi AsmReplace.boo <dll/exe file> <OldNameSpace> <NewNameSpace>"

       return

 

if not File.Exists(argv[0]):

       print argv[0] +" does not exists!"

       return

 

filename = argv[0]

oldNamespace = argv[1]

newNamespace = argv[2]

 

myLibrary = AssemblyFactory.GetAssembly (filename);

myLibrary.Name.Name = myLibrary.Name.Name.Replace(oldNamespace , newNamespace )

 

for module as ModuleDefinition in myLibrary.Modules:

       module.Name = module.Name.Replace(oldNamespace , newNamespace )

       for type as TypeDefinition in module.Types:

              type.Namespace = type.Namespace.Replace(oldNamespace , newNamespace )

 

AssemblyFactory.SaveAssembly(myLibrary, Path.GetFileName(filename.Replace(oldNamespace , newNamespace ) ) )

Oh, and written in notepad on the command line while I waited for #Develop to be installed on a new machine.

time to read 3 min | 455 words

Okay, I mentioned that I am working on fairly complex piece of query code, something that is completely off the charts, even for me. As such, I have completely test driven that. How do I Unit Test a complex query? By using in memory database (in this case, SQLite). NHibernate makes it very easy to switch databases, and I never gave it much thought after making it work for the first time.

Until today, where it was time to do an additional tweak to my query. It worked perfectly on the tests, running against SQLite, but failed when running the application against SQL Server. Here is the query that demonstrate the problem:

select address from Address address, City city left join fetch address.Street
             where city.Name = address.City

The generated query looked like:

select [fields list] from Addresses addresses0_, Cities cities1_ left outer join Streets street2_ on addresses0_.Street = street2_.Id  
            where...

This fails which unknown "addresses0_.Street" error, I run into the problem before, and I looks like a bug in SQL Server, or a nasty (appernatly undocumented) surprise.

This was my critical query, I had to run it. In desperation, I opened NHibernate source, and started debugging into it, in order to see how the query is being composed. Haven't looked very closlely at this area in a while, and things have changed somewhat, but I had that sinking feeling that it was one of those really big changes that I am really not ready to make close to the time that I want to go home.

Then I did something that I was sure would fail, I changed the query to:

select address from Address address left join fetch address.Street , City city
             where city.Name = address.City

It worked, produced SQL that would make SQL Server happy, SQLite was able to process this SQL without any issues either. Problem solved, and will hopefully remain in memory for the next time that I need it.

Oh, and if you didn't notice, today was a jumpy day. I am going to do some deep end stuff to relax.

time to read 3 min | 414 words

Chris, this looks like it can take a long time :-) Keep it up, I enjoy the debate.

Chris responded to my tools post, where he said:

Those [doing low level stuff in order to learn how things work] are all neat acedemic exercises and help make us better programmers because they give us deeper understanding, but when do we do that stuff in a real workplace? When was the last time I wrote a compiler? Not since I was an undergraduate.

I disagree with this statement, leaving aside the fact that I am dealing with compiler stuff on a routine basis (NHQG, Brail, Dynamic Proxy, NHibernate - all have some aspect of compilers in them)*, I think that learning something by going to the lowest level of abstraction that can be had is the best way to really learn something, and this is regardless of whatever you are doing it on the academia or at work.

I should qualify that with saying that I am also a lazy person by nature, therefor I would tend to learn just enough to get myself out of problem. The problem is that I appear to be a contrary person as well, so I run into a lot of problems :-) I am trying to learn WPF for the last two months, can't find the stregnth to go through an excellent book when I already know the basics. (XAML has routing events and dependencies properties, everything else is lazy learned).

That is usually a reflection of the precentage of time that I need to devote to something, usually, and I am not doing a lot (any) WPF.

Also:

Ever watch Star Trek? Recall how the captain just has to “ask” the computer to do complicated stuff, and behind the scenes I’m sure its doing some programming…

I seem to recall several episodes where the computer took things too literally, and things got really bad. Do you feel that you would like to be the person on call to debug this?

* Yes, I do know that I am probably not a representive sample of the developer population. I was already told to REPENT.

time to read 1 min | 191 words

I just had left work with a potential big issue left open (big defined as - "we may need to re-write the entire UI layer"), I was very pissed off, to say the least. I had a problem with the ASP.Net Session not working in Ajax call back. I just made a significant architecture change that require that I would store some information in the ASP.Net session, and I didn't feel like having to either re-write it or the UI layer.

Googling wasn't really helpful, which only made me angier. At that point, I got sick of it and went home, thinking very bad thoughts about some @#$#@%%. On the ride home, I suddenly had the answer. The issue was only happening when I made a CascadingDropDown call to the server, everything else was behaving normally. CascadingDropDown is using a WebService to get the data from the server. Now I can't think of a good reason that a Web Service should have an ASP.Net session by default.

The moment I knew what the underlying problem was, it was seconds to find what the solution was, until then, it was nearly impossible.

time to read 2 min | 251 words

Chris Holmes commented on my thinking for tools, but I think that he missed a crucial distinction that I made (but not clear enough).

If you require a tool in order to work effectively with something, this is an issue. By requiring a tool I mean something beyond VS + R#, which are the bare minimum stuff that you need to be effective in C# (it does says something on C#, doesn't it?). The Entity Framework Designer is a good example for something where I think that the dependence on the tools indicate a problem. I have been corrected about requiring the SCSF to work effectively with the CAB, which was good to hear.

Tools can make you more effective, but I think that you should always learn without them. Case in point, I am currently teaching people about .Net (I'll have a seperate post about it soon, I promise) and teaching them stuff like NHibernate or Active Record would be actively harmful for them at this stage, when they don't understand the basics of ADO.Net completely yet. In my opinion, it is always a good idea to know what the tool is doing, why, and where its shortcomings are.

Oh, and about the program in notepad thing, I don't program C# in notepad (usually), but I have written fully fledged applications in Boo from notepad and the command line. Boo makes it easy & painless to do so, and it is a pleasure (and painless) to work with it.

FUTURE POSTS

  1. RavenDB Performance: 15% improvement in one line - 15 hours from now

There are posts all the way to Dec 02, 2024

RECENT SERIES

  1. RavenDB Cloud (2):
    26 Nov 2024 - Auto scaling
  2. Challenge (75):
    01 Jul 2024 - Efficient snapshotable state
  3. Recording (14):
    19 Jun 2024 - Building a Database Engine in C# & .NET
  4. re (33):
    28 May 2024 - Secure Drop protocol
  5. Meta Blog (2):
    23 Jan 2024 - I'm a JS Developer now
View all series

Syndication

Main feed Feed Stats
Comments feed   Comments Feed Stats
}