Take a look at the code below and spot an error:
return insertData.Select(row => ExecuteInsert(cmd, insertColumns, row, onError)).ToList();
insertData.Select(row => ExecuteInsert(cmd, insertColumns, row, onError));
Got it? At first I didn’t. Debugged once but it ‘appeared’ to be ok so haven’t noticed the issue. Yet, insert did not happened, data did not reach database. Debugged once again – and quick glance over the code was enough to see it. Of course my code took
else path as I didn’t need results of insert for anything. And there is select, but it’s never used – ergo it’s never even triggered. That’s one of nice features of
linq – it will only run query if you actually need the result. But on the other hand – it is pretty easy to sometimes forget you’re not firing the query and it won’t do any of those function calls you set up in
ToList() at the end should fix the issue. Time to do some pull requests on Github!
Edit: and so I did – fixed, wrote some unit tests to make sure it will work in future and posted pull request on GitHub. This is my first contribution to Open source. And I hope it won’t be the last!
We are developers. Software engineers. We struggle everyday with our creations, trying to make them better, faster, more reliable. But we work mostly with text. Programming didn’t change much in that matter – give me a notepad (or better Vim) and compiler and I can rule the world. But can I?
8 months ago I started working at one company in very niche software. Well, it may be actually pretty popular and it made (and continues to make) a lot of money to company that wrote it – that one I’m sure of. I’m working with slightly outdated version. 2-3 versions behind but I’m not sure. So what I do is write scripts to support business logic. And I write them in some C-like language made specifically for this program. It comes with built in functions that help to work with table data (like sorting, calculating values, selecting subsets etc.). But that’s about it. No IDE support, no intellisense, heck, not even easily accessible compiler! I can write those scripts directly inside software running them but the editor there offers less functionality than Notepad (literally! Not even ctrl+a support).
So can I rock the world with notepad? Well, I’m sure making it go round. Scripts are running fine. But at what price?
- No TDD for me. No compiler, no external runtime environment – no way to run tests. Untested code leads to a lot of small issues in code (mine and others). And a lot of risk with each new feature, bugfix and refactor.
- No easy compilation means I write a lot of lines of code before I check if they are even correct. Mess up parameter here and there, skip semicolon somewhere, typing mistake in function call – all easy to fix, but when you have dozen of those mistakes in hundred or so lines of code it takes time to fix them. And time is money. You want to know how my compile “shortcut” looks like? Ctrl-a, Ctrl-c, Alt-Tab, Alt-e, Enter, Ctrl-v, Ctrl-s. Seriously.
- Deploy process is so hard to automate apparently that everyone tries to keep number of files low. 3k lines of code in single file? If you’re lucky. Usually you can easily hit 4k. And to share code, your file needs to be marked as
include file. And then it’s not able to run on its own. So most of the code gets copied and pasted around as fast solution for code share because no one bothers moving simple functions to shared libraries.
- I’ve got so used to
C# etc. that it hurts me when I need to create function header at top of the file because otherwise compiler will not recognize functions declared below place of usage. As a result we have long functions doing all kind of things since extracting function is so much trouble
- Language as a whole is so exotic that there is no tooling support for refactor or anything. I use C# color syntax since it’s the closest to script syntax
- One could at least have good debugger to work easily with issues. No way.
Turbo Pascal had better debugging tools and this was how many years ago? All code is thrown in one window, no distinction between files – so you have 10-20 thousand lines of code to work with. No watch – you need to select variable and click on a button to output it’s value to output window (it’s simple log window). Breakpoints are not even marked somehow readable – just by
B letter to the left, over line number. Current execution line is indicated by
=> characters – try finding it in 10 000 lines. You will make small change to script (say – change one character) and restart debugging – all your breakpoints are lost. There is even no step over functionality. You have to step into each function call or set breakpoint at next line and let the code run.
And I could get few more points probably. So to sum it up – code quality is very low, code duplication is very high, no easy way to fix it. Working in such conditions is very hard, everything takes way more time than it should in decent working environment. And developers time is money. Business have to struggle with issues, waiting long before fix finally makes it to production – this cost even more money. And we’re not talking about hundreds of dollars.
You could tell it’s our fault – we could work with this and still make good code. We could extract shared code, refactor it. Create custom tools etc. But that takes an effort – you need to work hard to get simple things done. Things that any other popular language these days have already worked out in many ways – just pick solution that suits you best! And we, as developers, are lazy. We want things to be easy. We want work in 21st century conditions.
And I’m right now at year ’95. Or maybe not even there…
I got an error saying that application tries to load
Npgsql, v. 188.8.131.52 but it can’t find it. Whoops, missing dll. Or that’s what I thought. Checked output folder and references in project – reference is there, it’s copied. So what’s the problem? Then I noticed the version does not match. I have referenced
184.108.40.206, cause that was the version other dependencies were build against. So where does this newer version loading code coming from?
Sadly it took me quite some time to figure it out. First I was thinking there is some mismatch in dependencies, that I’ve messed something up when rebuilding
Simple.Data.PostgreSql. Checked it, double checked it – all was perfectly fine. Then I used my favorite tool – search. There was just one line in whole solution referencing
<assemblyIdentity name="Npgsql" publicKeyToken="5d8b90d52f46fda7" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-220.127.116.11" newVersion="18.104.22.168" />
bindingRedirect – a way to tell that we should load newer library even if strongly named reference requires older version. What a bummer – how did it get there? I didn’t put it there myself, that’s for sure.
Then I remembered – first I installed
Npgsql from Nuget and I picked latest version. And installation from Nuget modified my
web.config file. But removing this dependency from Nuget did not remove config entry!
So lesson learned – Nuget is great tool, but pay attention to the changes it makes to your code or you may end up with some stupid errors. Easy to fix, but sometimes hard to pin point.
Today’s not a good day for my coding. I planned to do database design and data access logic using
Simple.Data and everything was going wrong. Outdated version of
Simple.Data.PostgreSql, had to download code from github manually. Thanks to Maciej Aniserowicz this project was recently updated to later version of
Simple.Data. But along the way I was stumbling upon one issue after another. I don’t like those days when tools are mostly in the way of getting work done and not helping at all.
My biggest complain today will be Visual Studio. Yes, it is big and slow. But it is also pretty damn good IDE. Add Resharper to it and sky is the limit. Well, on my fun projects I’m using Visual Studio Express mainly because it is for free. So no Resharper magic for me, no plugins, but it’s free – I don’t complain (too much). I have two versions installed: Visual Studio 2013 for Desktop and Visual Studio 2013 for Web. Today for the first time in quite a while I started desktop development version to build quick proof of concept console application. At some point I started getting exception from library. But I could not view it! Apparently exception assistant, this fancy floating window that appears when something went terribly wrong, was removed form VS2013 for Desktop. Why? I have no idea, but I am greatly disappointed. You can read about reported issue (and vote for a fix) here: Enable Exception Assistant option missing from VS2012 Express For Desktop
But then the main issue came and hit me when I least expected it. Imagine situation where you have main project
A which references project
B. Classic situation.
B further references few dll libraries:
B1, B2, B3. But it explicitly uses only
B1, rest is used through reflection or something. Now – I would expect, and I’m pretty sure that’s how it worked previously, that all three dlls will get copied to
A‘s output directory. Since I created reference I know it’s there for some reason and would like VS to respect it. However no, that won’t happen. Does not matter if you have
Copy Local set to true for all libraries – only
B1 will be deployed since it is the only one used. Took me way too much time to figure it out.
You can look at this issue here:
Visual Studio does not copy referenced assemblies through the reference hierarchy and vote for this to be fixed. VS team decided not to fix it since it has not enough votes. I don’t get the logic behind this – it seems to me like basic functionality is broken and they decide not to do anything about it.
Of course this issue is simple to work around – you can either reference the same libraries in
A project or create after-build task to copy them. It will work, but it is far from perfect – now there are two places you need to remember to modify if you will start messing with references. IDE should be there to help you, not to make it harder.
I have situation where it seemed useful to have data shared between two controllers. First controller is just a list of elements. Second is edit controller to adjust values of elements. I could have just loaded this single element back from server and it would be fine and probably pretty fast as well. But why, I have all the data I need just here. Why cannot I use it? Well – sure I can, I can go with shared variable, as was my initial idea:
Code is pretty straightforward: module definition with routing, two controllers: list one, that gets the data and edit one – which just picks the data from already downloaded values.
Have you coded for few months even, I bet you heard that global variables are no good. And sure they are, global state is always hard to manage. So can we do something with this? AngularJs have two great things that will help us solve this issue: incjector and factories. You can look through their documentation, but put simply: you can define some factories in module and then use parameters named like those factories and injector will automatically fill those parameters for you. Simple, classy, easy to code. Just look:
A bit more code there, but still easy to understand, don’t you think? We declare factory on module, named
contentProvider and then we use parameter with the same name in controller’s constructor – Angular will put the instance returned from factory there for us.
But wait, that won’t work – factory will return new value each time, right? Well, no – Angular is clever enough to limit instance just to one and reuse it each time. Our list will get the data and edit will have it ready when needed.
Can you see the issue here? The most obvious one, for me, is that if we tried going directly to
/edit/1 page for example it will fail – we skipped list page so the data was never downloaded. But I’m sure we can do something about that and it will be fairly easy. Angular will do its best to assist us.