A lot can happen in a little over 2 years...
In my last post, I
had proposed an attempt to tackle the FizzBuzz problem. PowerShell was done, PHP was barely started but I never pointed
to it in a subsequent post or finished what I wanted. The project url has
completed and checked solutions for PHP and Node.js. I had mentioned
b. F#, Objective-C, CoffeeScript, C/C++, Go, Dart, and Haskell are the planned languages I've mostly touched in passing or know about.
,
as well as C#, Pascal, and Ruby but I may never get to them.
Shortly after that last post, I switched jobs from .NET to web development focusing on PHP with HTML, CSS, and Javascript. That one action shifted much of my focus from most of the languages in that list. With ES6 coming and recently finishing a CodeSchool course in CoffeeScript, the Javascript landscape is looking pretty awesome. Elixir and the Phoenix Framework have recently stood out as upcoming contenders for my mindshare as well.
My last post taught me that while I may know of a language, it doesn't mean I'll have a genuine desire to pursue it. It can also easily become difficult to want to pursue development outside of your day job. Staying current, however, is always worth pursuing. Tooling and efficiency around web development seems to have come a very long way.
To keep this post brief, I plan on making more updates as I feel a lot has changed for me in the past 2 years that I'd still love to share.
Due to a comment on Hacker News (original post here), I thought I would put my money where my mouth was, so to speak, and tackle this problem in a public repository.
My comment could likely be seen as dismissive or arrogant. I get that. My biggest problem is that because people still fail, this is the interview equivalent of patty cake: awkward, childish, and unrewarding (unless you're a 2 year old).
To be quite honest, I don't quite understand my disdain for the problem. It's simple enough that it can be solved a number of ways quickly and gets you to express at least the fundamentals of development in a particular language.
This exercise is an excellent opportunity for a number of things:
If you believe my time tracking is accurate, it should demonstrate at least some proficiency in languages I know and how quickly I can at least have a basic understanding of the ones I don't.
Note: I'm using https://rosettacode.org/wiki/FizzBuzz as a language guide only. If you see me follow a specific example, punch me in the nuts.
The best description of the problem can be found here, specifically (altered for this example):
Write a program that prints the numbers from 1 to 100. But for multiples of three print "Jazz" instead of the number and for the multiples of five print "Hands". For numbers which are multiples of both three and five print "JazzHands".
This brings up some excellent points. I'm definitely not above FizzBuzz or live coding but I still can't pinpoint why I have beef with this particular problem.
I honestly can't remember the last time I've actually tackled this problem so the potential to look really foolish, at least at the beginning, is pretty high.
Back in February of 2011, I posted a very rough alpha release of my first WP7 IRC app called dIRCa. I abandoned the project primarily due to the heavy reliance on Homebrew sockets and rewrote it from scratch using the wonderful IrcDotNet library. Not having to handle the core IRC quirks is a godsend and luckily it works rather flawlessly with 7.5+ (Mango and above).
I originally wrote a post back in 2011 to gather emails for the beta submission process but it never got published. I was also working diligently to release a competent v1.0 but my perfectionism got the best of me.
I've since release it as open source on Github. The project is abandoned so far as my HD7 phone is no longer consistently in use now that I've switched to the HTC 8x and Windows Phone 8.
The barriers to make it a Windows Phone 8/WinRT version are pretty high:
The original project received quite a bit of downloads for my first open source project (around 700 by this time) with the reason primarily being that a XAP was already built. On Github there are no releases but I look to remedy that very shortly.
The application is pretty functional but it is rather rough around the edges. For instance, when you first start it you're required to go to the settings screen as exiting initializes and starts the connections to the various networks. I intended this to be covered in a tutorial of sorts but that was something I was going to cover off last.
[I forgot to post this draft back in April 2010. Needless to say I no longer utilize the technique nor can really help now that it's purged from my memory]
I've cobbled together a poor-man's backup solution using PowerShell and robocopy in what I thought was a somewhat resilient solution. Robocopy turned out to be a poor choice based upon my needs and nitpicks but I wanted to outline why to save myself and others a little pain.
This URL describes the bug and relative fix: https://superuser.com/questions/48303/access-denied-error-with-robocopy-as-admin. While using /ZB and /B helps it wasn't solving the problem because the relevant ACLs weren't being created even as late as Windows 7.
robocopy has 3 (relevant) major versions: 2003 Resource Kit (the one I was using 010), Vista/RoboCopy GUI (026), and Windows 7. To make things more complicated, installing RoboCopy GUI on a 2003/XP machine will put robocopy under %windir%system32 which happens to enumerate after the 2003 Resource Kit path. This means you have to explicitly call system32robocopy or rename the resource kit version if you hope to keep the other resource kit tools.
I erroneously thought by adding users to the Backup Operators group, a requirement to use the /B switch, robocopy was creating local shadow copies. I might have been confusing it with HoboCopy and figured taking a shadow copy snapshot before a robocopy operation would fix the problem. Turns out taking all that time, determining you almost always need to be administrative, and XP's limited ability to easily expose a snapshot as a drive letter/share made this become an incredible deal breaker.
To combat the bug that started this investigation, I initially tried using version 026 of robocopy to no avail. I used every combination of /copyall, /copy:dats, /copy:dt or just /copy:d.
What really fixes the problem is to completely obliterate the destination folder(s) and start over. This would correctly build the relative ACL and prevent the access denied message but it would only be a matter of time until it happened again.
Note: Robocopy is an end-to-end solution whereas I have far more flexibility to shoot myself in the face with this PowerShell script and the Sync Framework in general.
*: This technique negates the solution completely because I'm creating these directories under the user context the script is run in.
Shadow copies aren't used so to run this in a limited user context I still need the user in the Backup Operators group. I will likely work up a solution using shadow copies on the server as I can rather painlessly manipulate them using the Create Method of the Win32_ShadowCopy Class. Sample Powershell v2 script using AlphaVSS behaves much better if you are not using Windows XP too.
I've started toying with the proper Dotfuscator project settings to give me a workable, yet relatively-secure-as-possible package for deploying to private beta testers and the Marketplace. A great starting point for this journey could be found here: https://weblogs.asp.net/bsimser/dotfuscator-deep-dive-with-wp7.
Before we start, my project includes a number of 3rd party controls like AppBarUtils, MVVMLight, Funq, and my favorite IrcDotNet (which is the source of this post). The instructions say to use your XAP file as input so we'll follow that. On the far right-hand side of the Input Files
toolbar is Transform XAML/BAML resources in all assemblies
. Click this to turn it off primarily to be thorough. I believe this affects MVVM because it tries to rename Xaml internals that are data bound. Follow the instructions on the Settings->Global Options
screen to set Disable Control Flow
and Disable Renaming
to No to enable them.
Now click the Build Project
toolbar button to build your project. If your XAP includes a signed assembly, you'll be greeted with the following message:
Warning: The strong named input assemblies (or assembly)
<TempDirectory>IrcDotNet.dll
were not resigned. You will need to sign these dotfuscated assemblies manually.
My first instinct was to go to the Settings->Signing
screen, and enable Re-sign Strong Named Assemblies
and point it to IrcDotNet.snk. If you do that you're met with a different message:
Signing Assemblies...
Running sn.exe /q /R
<ConfigDirectory>IrcDotNet.dll
<Location of>IrcDotNet.snk
Warning: Password protected Strong Name files are not supported sn returned 1. Build Error.
This is the end of the line as far as automation goes. The only recourse is to sign the assembly manually as the original warning states. If you do not resign this file before deployment, your app will not startup properly. Once code hits that signed assembly it simply will not function.
My first approach was to go to the Rename
and Control Flow
tabs and exclude every assembly other than my own. This produces the same result. Assemblies are reassembled regardless of whether or not any options are applied.
My preferred approach is to go to the Input
tab, right click on each 3rd party assembly and click Exclude assembly from package
. This has a lovely UI effect of removing everything from the screen and pausing while Dotfuscator works its magic. The added bonus? This happens every assembly. The bare minimum would be to only remove those signed assemblies but I took it all the way and removed all 3rd party dlls. These are all open source frameworks so obfuscating them isn't necessary.
Now click Build Project
again and the app starts! Inspecting the result in IL Spy gives me a runtime error on decompile, meaning control flow is on and teh IP iz protectordez. My app also uses localization and Smart Obfuscation
automatically disables renaming for my localization resources so no extra legwork is needed to exclude them.
In summary if you don't need to obfuscate 3rd party assemblies, simply exclude them from the Input
tab rather than trying to exclude them in the individual obfuscation tabs. Ilasm
is still ran on the assemblies which triggers the need to re-sign them.