A C4SC Series: DSL Development in .NET with C#

11.16.2011 00:12 by kbeckman | Comments

For those of you that follow C4SC, you know by now that I’ve recently been working a contract absent of anything Microsoft and the .NET development platform. I’ve been working entirely in Ruby for about 7 months now and have been consistently acquiring a new set of skills to make me a more well-rounded developer. It has actually turned out to be one of the most educational opportunities I’ve had in my 10-year career in software development. This type of opportunity is extremely rare – so while I’m here (however much longer it lasts), I’m trying to absorb as much as my brain will allow. Here are some of my recent educational highlights:

  • A new perspective on the agile process including the tools that promote agile development (sorry folks, no TFS here).
  • Good working knowledge of the Ruby language as well as a better understanding of how the open source community fuels rapid software development.
  • Newfound appreciation for the MVC pattern (more specifically its implementation in Rails) and how it can make web development enjoyable again.
  • A solid foundation for jumping into JRuby on the Java platform. In the near future, I plan to explore my options with JRuby in Android application development.
  • A new appreciation for domain specific languages (DSLs) and how readable your code can be without the need for comments.

Looks like the result of one of those liberal arts college curriculums, right?

 

Over the next several posts, I will be further exploring the last bullet point from above – a new appreciation for DSLs. It wasn’t always an appreciation… During the first few months learning Ruby and all of the open source gems used in our projects, I experienced a mental overload of domain specific language. EVERYTHING seemed to have it’s own DSL… I’m learning a new language and it turns out that almost every gem has it’s own internal DSL. WTF! That went on for a couple of months or so and then things started to coalesce into understanding. As with anything in software development, I’ll probably never know or learn as much as I want to, but at least now the blank stares into code are gone.

 

So now I will be porting some of the things I’ve learned back to the .NET platform by developing a DSL for working with dates and times throughout a series of C4SC posts. I got the idea when some of my recent Rails work involved some heavy usage of the Date helper methods in the Rails ActiveSupport library. I couldn’t believe how English-like the code read and how easy it was to understand with the absence of comments. I soon felt the need for something like this in .NET…

 

Following is a tentative set of topics that I plan on covering throughout the series. I will update this list if any of the topics change, are reordered or if more are added. I will also include the links to the actual posts as I complete them. Throughout this process, I intend for the codebase to be very fluid and to change significantly. You can follow along on my public C4SC GitHub repository for the latest updates in their entirety.

This is going to be fun and educational – I hope you enjoy!

VirtualBox: Getting Around an Absence of Domain

11.06.2011 00:56 by kbeckman | Comments

UPDATE: The contents of this post are a hack for static IP addresses… I’ve posted a better way here.

 

A while back, I wrote about the benefits of using cross-platform tools (when available) for software development. The Bottom Line: it allows developers to more easily make the transition to other platforms and new languages. The practice enables developers to use tools they are already familiar with without having to assume the overhead of learning a completely new set of tools along with the new platform or language. So in the spirit of drinking my own Kool-Aid, I’ve recently made the transition from VMWare Fusion to VirtualBox to power my back end SQL Server VM required for our Rails project. Following are the setup details in case anyone else out there is looking to do the same…

 

A Little Development Environment Background…

My current client is a typical large enterprise with almost all-things Microsoft. Recently, things have changed a bit with our R&D team because we’ve introduced Ruby / Rails development on Mac Book Pro laptops running OSX Snow Leopard. As is the case with many slow-to-adopt IT departments, our Mac Book development machines are either not required or are not allowed to participate in the corporate domain. It seems to me to be either a fear of the unknown or an unwillingness to support something outside of the status quo – I think that answer will change depending on who ask. Reasons aside, local development must mimic the production environment as close as possible to catch any configuration surprises early in the development process.

 

Step 1: Server Internet Connectivity

Internet connectivity is the easy part… Unless you use some weird, custom setup during your VM build-out, VirtualBox will add a default NAT network adapter to ensure the VM has an active Internet connection. No need for further configuration here.

 

NAT adapter

Virtual Machine Settings: NAT Network Adapter

 

Step 2: Pseudo-Static IP Setup to Replace NetBIOS

As I mentioned earlier in this post, our development machines are not part of the corporate domain. The same is true with our development VMs even though they are Windows servers. Joining a server or development machine to the corporate domain is the only way I know of to be able to assign it a static IP address. It’s also the only way I know of to use NetBIOS to connect to the machine using it’s assigned machine name rather than using a static IP address.

 

Absence of a corporate domain is obviously a problem here… To work around it, we need some VirtualBox customization. I found a solution in adding a second VM network adapter: a Host-Only Network Adapter. It is possible to setup your own local domain using the Windows Server 2008 R2 DNS Server Role. But for a single-server environment, I didn’t want the hassle of setting up and maintaining my own local domain. So I set up the Host-Only adapter to use DHCP. You’ll see from the screenshots below that my DHCP settings provide for a relatively wide range of IP address settings, but the nice thing about VirtualBox’s DHCP server is that it will always assign the first sequentially available IP address to every VM you bring online. In other words, my single VM instance always gets the IP address listed in my DHCP server’s “Lower Address Bound” setting. Bingo! I always get the following IP address for my SQL Server VM: 192.198.56.2.

 

To change VirtualBox’s DHCP server settings, go to “Preferences” in the application settings. From the “Network” tab, use the edit button (screwdriver icon) to modify the network settings for the host-only network.

 

preferences

VirtualBox Host-Only Network Listing

 

The DHCP Server will probably not be enabled by default, so be sure to configure it accordingly.

 

network adapter settings          dhcp server settings

VirtualBox Host-Only Network Adapter and DHCP Server Settings

 

Now you’re done with the VirtualBox server settings. The last part of the configuration is to add a second host-only network adapter to the SQL Server VM. After adding the second network adapter, be sure to assign it to the same virtual network that was configured for DHCP access. If you’ve only configured a single VirtualBox host-only network, you don’t need to worry about assignment as it will default correctly.

 

Host-Only adapter

Virtual Machine Settings: Host-Only Network Adapter

 

Problem Solved!

And that’s it. You’re now ready for server and database connectivity via IP address resolution. Below is a screenshot of the VM’s IP configuration. Notice the dual network adapters.

 

ipconfig

Virtual Machine IP Configuration

 

References

Issue: RubyMine Debugging (Debugger.Start is not called yet.)

10.11.2011 08:39 by kbeckman | Comments

Every once in a while, a little bit of collective thought during the “impediments” portion of the daily scrum yields some immediate results…

 

Overview

A portion of our development team uses RubyMine as the primary source code editor / IDE for Ruby development. Our team lead (the other guy) is more of a purist and boasts a status of VIM Power User never leaving the Terminal window. Recently, RubyMine’s debugging capabilities just stopped working on both of our active Rails projects. More specifically, every time we attempted to use RubyMine’s debugger to launch a single spec or cuke with breakpoints set, the entire test file failed. Even tests that should have passed failed to execute while everything worked perfectly from the command line. The stack trace revealed nothing more than a cryptic error like the one below. I shortened it a bit to include only the important items. Pay special attention to “RuntimeError: Debugger.start is not yet called.”

/Users/kbeckman/.rvm/rubies/ruby-1.9.2-p180/bin/ruby -e at_exit{sleep(1)};$stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift) /Users/kbeckman/.rvm/gems/ruby-1.9.2-p180@Project/gems/ruby-debug-ide-0.4.17.beta5/bin/rdebug-ide --port 49226 -- /Users/kbeckman/.rvm/gems/ruby-1.9.2-p180@Project/bin/rspec /Users/kbeckman/Sites/Project/spec/models/post_spec.rb --require teamcity/spec/runner/formatter/teamcity/formatter --format Spec::Runner::Formatter::TeamcityFormatter
Testing started at 10:20 PM ...
Fast Debugger (ruby-debug-ide 0.4.17.beta5, ruby-debug-base 0.11.28) listens on 127.0.0.1:49226
/Users/kbeckman/.rvm/gems/ruby-1.9.2-p180@Project/gems/ruby-debug-base19-0.11.24/lib/ruby_debug.bundle: warning: already initialized constant VERSION

RuntimeError: Debugger.start is not called yet.
/Users/kbeckman/.rvm/gems/ruby-1.9.2-p180@Project/gems/ruby-debug19-0.11.6/cli/ruby-debug/processor.rb:130:in `breakpoints'
/Users/kbeckman/.rvm/gems/ruby-1.9.2-p180@Project/gems/ruby-debug19-0.11.6/cli/ruby-debug/processor.rb:130:in `at_breakpoint'
(eval):5:in `block in at_breakpoint'
<internal:prelude>:10:in `synchronize'
(eval):3:in `at_breakpoint'
/Users/kbeckman/.rvm/gems/ruby-1.9.2-p180@Project/gems/ruby-debug-base19-0.11.24/lib/ruby-debug-base.rb:42:in `at_breakpoint'
/Users/kbeckman/Sites/Project/spec/models/post_spec.rb:6:in `block (2 levels) in <top (required)>'
/Users/kbeckman/.rvm/gems/ruby-1.9.2-p180@Project/gems/rspec-core-2.3.1/lib/rspec/core/hooks.rb:29:in `instance_eval'
/Users/kbeckman/.rvm/gems/ruby-1.9.2-p180@Project/gems/rspec-core-2.3.1/lib/rspec/core/hooks.rb:29:in `run_in'
/Users/kbeckman/.rvm/gems/ruby-1.9.2-p180@Project/gems/rspec-core-2.3.1/lib/rspec/core/hooks.rb:64:in `run_all!'
/Users/kbeckman/.rvm/gems/ruby-1.9.2-p180@Project/gems/rspec-core-2.3.1/lib/rspec/core/hooks.rb:112:in `run_hook!'
/Users/kbeckman/.rvm/gems/ruby-1.9.2-p180@Project/gems/rspec-core-2.3.1/lib/rspec/core/example_group.rb:176:in `eval_before_alls'
/Users/kbeckman/.rvm/gems/ruby-1.9.2-p180@Project/gems/rspec-core-2.3.1/lib/rspec/core/example_group.rb:230:in `run'
/Users/kbeckman/.rvm/gems/ruby-1.9.2-p180@Project/gems/rspec-core-2.3.1/lib/rspec/core/command_line.rb:27:in `block (2 levels) in run'
/Users/kbeckman/.rvm/gems/ruby-1.9.2-p180@Project/gems/rspec-core-2.3.1/lib/rspec/core/command_line.rb:27:in `map'
/Users/kbeckman/.rvm/gems/ruby-1.9.2-p180@Project/gems/rspec-core-2.3.1/lib/rspec/core/command_line.rb:27:in `block in run'
/Users/kbeckman/.rvm/gems/ruby-1.9.2-p180@Project/gems/rspec-core-2.3.1/lib/rspec/core/reporter.rb:12:in `report'
/Users/kbeckman/.rvm/gems/ruby-1.9.2-p180@Project/gems/rspec-core-2.3.1/lib/rspec/core/command_line.rb:24:in `run'
/Users/kbeckman/.rvm/gems/ruby-1.9.2-p180@Project/gems/rspec-core-2.3.1/lib/rspec/core/runner.rb:55:in `run_in_process'
/Users/kbeckman/.rvm/gems/ruby-1.9.2-p180@Project/gems/rspec-core-2.3.1/lib/rspec/core/runner.rb:46:in `run'
/Users/kbeckman/.rvm/gems/ruby-1.9.2-p180@Project/gems/rspec-core-2.3.1/lib/rspec/core/runner.rb:10:in `block in autorun'
/Users/kbeckman/.rvm/gems/ruby-1.9.2-p180@Project/gems/ruby-debug-ide-0.4.17.beta5/lib/ruby-debug-ide.rb:112:in `debug_load'
/Users/kbeckman/.rvm/gems/ruby-1.9.2-p180@Project/gems/ruby-debug-ide-0.4.17.beta5/lib/ruby-debug-ide.rb:112:in `debug_program'
/Users/kbeckman/.rvm/gems/ruby-1.9.2-p180@Project/gems/ruby-debug-ide-0.4.17.beta5/bin/rdebug-ide:87:in `<top (required)>'
-e:1:in `load'
-e:1:in `<main>'

2 examples, 2 failures, 0 passed

Finished in 0.002311 seconds

Process finished with exit code 0

 

Investigation

Back to the “impediments” portion of the daily scrum… This issue was brought to everyone’s attention and we chatted about it for a couple of minutes. Since he wasn’t using RubyMine, our team lead was the only developer not having any issues with debugging. We soon discovered a few days ago he added a require statement for the ruby-debug gem in our RSpec spec_helper.rb file. Bingo!

 

Resolution

It turns out that RubyMine automatically adds its own reference to the ruby-debug gem during its debugging process. With the new reference in our spec_helper.rb file, all RubyMine users had a dual reference (RubyMine’s version and to our project version in the RVM gemset). The runtime was unable to determine which gem version to use for debugging. With the issue discovered, the solution is easy. Adding a conditional statement in spec_helper.rb to ignore the ruby-debug reference (for RubyMine users only) solves the problem.

 

Step 1 – Set a Mac Environment Variable Indicating RubyMine Usage

Here’s a link to a System Preferences plug-in allowing you edit system environment variables via a GUI dialog. Or you can follow the steps in this post to manually edit your environment variables file. For documentation’s sake, here’s what my .MacOSX/environment.plist file looks like.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>USE_RUBYMINE</key>
    <string>TRUE</string>
</dict>
</plist>

 

Step 2 – Update spec_helper.rb to Conditionally Add the ruby-debug Gem

require 'rubygems'
require 'spork'
require 'webmock/rspec'
unless ENV["USE_RUBYMINE"] == "TRUE"
  require 'ruby-debug'
end

CSS: Cross-Browser Hacks

09.27.2011 07:13 by kbeckman | Comments

A couple weeks ago, I found myself neck-deep in some nasty rendering issues involving Internet Explorer. Finding hacks around IE’s rendering issues is nothing new for anyone who has written a single line of markup targeted for the web. This time was the first time though that I’ve had to dig so deep to get around IE. Below is a list of tricks that I used to overcome and support our poor corporate users constrained by late-adopter IT departments.

 

I’ve also included a few links for further reading. My favorite is a link from Cats Who Code that explains some nifty tricks for completely crashing IE6! Seriously, if you’re still using IE6, your corporate or personal technology strategy is WRONG.


IE7

Use either an asterisk [*] or a period [.] character within the normal style definition to trigger a style specific for IE7…

.some-style-definition {
    margin-left: -965px;
    *margin-left: -900px; /* IE7 */
}
.some-style-definition {
    margin-left: -965px;
    .margin-left: -900px; /* IE7 */
}

IE8

Wrap IE8 specific styles (or repeat a style definition that doesn’t work for IE8) inside a [@media \0screen] block…

@media \0screen { 
    ie8-specific-style {
        .margin-left: -965px; 
    }
}

 

IE9

Use the [:root] prefix with a [\9] terminator for IE9 specific styles…

:root .ie9-specific-style { margin-left: –965px\9; }

 

Firefox

…and in rare instances. Use a [@-moz-document url-prefix()] block for Firefox specific style definitions…

@-moz-document url-prefix() {
    firefox-specific-style {
        margin-left: -965px;
    { 
}

 

References