I just watched a talk by Linus Torvalds at Google about Git. One of the questions touched on one of Linus' motivations for Git. That is Merging. I want to talk about how Git merging dove-tails nicely with Ruby's testing tool RSpec.
Some source control managers (SCMs) make a big deal about "branching" being cheap. Linus points out that branching is not the problem, merging is the problem people deal with. Git makes merging easy by removing the number of conflicts the developer has to deal with. It does this two ways. First is algorithmic and the second is how Git changes your workflow.
Git allows for, and relies on, three way merging. CVS/SVN by contrast only does two way. Three way merging diffs the original file and each of the two conflicting versions of that file. Git can do so because it stores the whole files, not just a long string of diffs (ala CVS/SVN which I'll just call SVN from now on). Three way merges allow the merge algorithm to look at the context of the text being diffed. SVN can only look at line 245 and see it changed. Git can notice that the line didn't change, it mearly moved. Say you and the conflicting file inserted a text before the same line 245. So there is no conflict just code motion in the file. Three way diffs see this, two way diffs can't.
The second way Git deals with merge conflicts is not as obvious; it stems from the work flow. Specifically, branching is inherent in Git's design and merging is easier and better. So you branch often and merge often. More to the point you start your branch from the central "master" branch for your feature add; change & commit a bunch of times to that small branch; then pull or push your change back into "master". By repeating this branch-change-merge-push cycle early and often you have less opportunity for merge conflicts. Put another way, your branch exists for less time and syncs with the central master more often, resulting in less opportunity for two people to introduce genuine conflicts.
So alot of talk is generated about Git working in a fully distributed way. However, that ignores that the Git, encourages syncing up those distributed merges early and often.
So imagine you replace SVN with Git. First you don't have to do it to your whole tree at once. You can do it by subsystem. Also there is Git-SVN gateway tools to help do this. You can still have the central tree ala SVN, but you just branch off it and merge back more often. In SVN you are usually doing this anyways. Each SVN commits end up being after the feature is completed; much like the final merge of a Git branch, but without all the Git commits in the mean time. Or you create a longer lived development branch and merge that back as a monster merge.
I've explored other SVN branching/merging workflows but all they do push the pain to a different part of the process. A smart colleague of mine called it "squeezing the balloon". What you need to do is keep the master branch stable. That can be achieved by branching and merging smaller and faster. The SCM (or VCS if you prefer) makes all the difference.
What also helps is having a test suite you can rely on. First the test suite has to be aimed at the internal API level. Second, it has to be easy and fast to run. This is where the choice of Test framework dove tails with the SCM choice. "Early and Often" is the catch phrase for both.
Testing the API's "contract" is where you should aim your testing framework. As a side note: you are forced to state what that "contract" is which is a level of internal documentation that often gets forgotten. The contract is what each function takes as input and what the results should be; especially the edge cases. Edge cases are given a function "sum" adds all the elements of an array, what if the function is given an empty array or a nil as input. So that is the trivial case. Then there is the out-of-bounds case, like each element of an IP address (dot-quad) is between 0(inclusive) and 256(exclusive). Correctness should be tested if you can. Most of the time, correctness can't be tested with out recreating the logic of the function or testing pre-canned input and results. But that leads of who-tests-the-tester (my favorite quote: "Qui custodiet ipsos custodes?")
Another variation of this "contract" is how it applied to methods of a object. Methods have input and return results, but they may alter the objects state. Input and result have to be tested as above, edge case and out-of-bounds case. But internal state? One internal state to test is internal consistency. Again there are edge cases of initialized(trivial states) and known inconsistent states.
RSpec is a good ruby oriented tool-set built explicitly to test the contracts in your APIs. What are other API test frameworks for other languages is left as an exercise for the reader :)
I am exploring two new languages and a Distributed VCS. Go and Node.js. Go has Goroutines (sorta evented, sorta threaded) and Node.js is intrinsically event driven. Git is a VCS born of Linus Torvalds mind (tried Mercuria[hg] but git has won me and the majority over).
Saturday, July 23, 2011
Thursday, July 14, 2011
Little Idiom of Ruby I like
h = Hash.new { |h,k| h[k] = [] }
h['foo'] << "a"
h['bar'].push "b"
puts h.inspect
outputs {"foo"=>["a"], "bar"=>["b"]}. In other words, we declare a hash with a constructor that sets each new key to have a value of a empty array. Otherwise, we would have to test each hash key to see if it was already initialized to an array, if not initialized we'd set that hash key's value to an empty array. It's a common thing to do, but Ruby makes it easy and automagic.
I suppose in perl you can rely on auto vivification.
But as you can imagine the Ruby idiom can be generalized to more complicated initializations.
push @{$h{'foo'}}, "a";
TextMate clone for winbloze
For anyone who may care there is a TextMate act-a-like called E Text Editor. I supports TextMate bundles and key strokes. I haven't used it. But I imagine it must be manna from heaven if you are a TextMate user banished to the wilds of Microsoft-land.
Wednesday, July 13, 2011
iTerm2 Does Not Suck
Ringing endorsement eh?
Well I've been using iTerm2 for a while instead of the default Terminal. Don't confuse iTerm2 with iTerm. While, I am confused about that, I haven't spent anytime figuring out the diff.
The first problem with iTerm was the colors. It has a very good color palate (MacOSX builtin I presume) and a option in the Pref panel that will send you off to a page of Preset Palets. I was happy to find one that approximated the MacOSX Terminal colors I had come to like. With that color pallet installed I moved over to my next issue.
AntiqueWhite background w/ black foreground. On a PC running Linux AntiqueWhite out of rgb.txt was fine. I entered the same RGB codes for AntiqueWhite into Terminal Prefs and was happy. Entered the same codes into iTerm2 Prefs and not so easy to find. But selected the Emacs pallet and AntiqueWhite2 seemed to give me the happys.
I am transitioning from Emacs, screen. Even my screen command control character is C-o not the default C-a, because, duh, C-a is beginning of line in Emacs. But screen doesn't do top-bottom splits. After a friend suggested iTerm2 I gave it a look then went back to Terminal/screen.
The big change came when I was writing very wide log lines to the terminal. I needed a terminal with full screen width. Given screen wouldn't give me top-bottom splits, I tried iTerm2 again. The commands were easy to learn ⌘-t for new tabs; and ⌘-[ and ⌘-] to go back/forth between panes; and ⌘-⇧-[ and ⌘-⇧-] to got back/forth between tabs.
The scrolling is easy: just mouse scroll up/down in the window; no worries about the lack of scroll bar.
All it all, I've definitely moved from emacs/screen to TextMate/iTerm2 and I think I am more productive because of all the little things I gain. I just feel like all the key strokes programmed into the nerves of my hands are being wasted. I don't even remember alot of the emacs commands. I just pull up emacs, do the command, and look at what my hands do. Then I can say "oh yeah. That's C-space hilite region C-x r t blah blah blah.
NOTE: the unicode characters above, ⌘ and ⇧, may not display correctly on non-Mac OS's. I found them on this page
Well I've been using iTerm2 for a while instead of the default Terminal. Don't confuse iTerm2 with iTerm. While, I am confused about that, I haven't spent anytime figuring out the diff.
The first problem with iTerm was the colors. It has a very good color palate (MacOSX builtin I presume) and a option in the Pref panel that will send you off to a page of Preset Palets. I was happy to find one that approximated the MacOSX Terminal colors I had come to like. With that color pallet installed I moved over to my next issue.
AntiqueWhite background w/ black foreground. On a PC running Linux AntiqueWhite out of rgb.txt was fine. I entered the same RGB codes for AntiqueWhite into Terminal Prefs and was happy. Entered the same codes into iTerm2 Prefs and not so easy to find. But selected the Emacs pallet and AntiqueWhite2 seemed to give me the happys.
I am transitioning from Emacs, screen. Even my screen command control character is C-o not the default C-a, because, duh, C-a is beginning of line in Emacs. But screen doesn't do top-bottom splits. After a friend suggested iTerm2 I gave it a look then went back to Terminal/screen.
The big change came when I was writing very wide log lines to the terminal. I needed a terminal with full screen width. Given screen wouldn't give me top-bottom splits, I tried iTerm2 again. The commands were easy to learn ⌘-t for new tabs; and ⌘-[ and ⌘-] to go back/forth between panes; and ⌘-⇧-[ and ⌘-⇧-] to got back/forth between tabs.
The scrolling is easy: just mouse scroll up/down in the window; no worries about the lack of scroll bar.
All it all, I've definitely moved from emacs/screen to TextMate/iTerm2 and I think I am more productive because of all the little things I gain. I just feel like all the key strokes programmed into the nerves of my hands are being wasted. I don't even remember alot of the emacs commands. I just pull up emacs, do the command, and look at what my hands do. Then I can say "oh yeah. That's C-space hilite region C-x r t blah blah blah.
NOTE: the unicode characters above, ⌘ and ⇧, may not display correctly on non-Mac OS's. I found them on this page
Tuesday, June 28, 2011
Bye bye Emacs, Helloooo Sexy (TextMate)
If programming editors are a religion I am an Apostate.
While reading up on Ruby, I came across videos of people writing code real time. First, it is cool Ruby can do high level things in short programs. So short you can watch people coding real time. Second, more apropos, several different presenters were using this cool editor I'd never seen. I thought it was Vim with some crazy programming mode turned on. It completed statements and other coding constructs, speeding up the process of writing code.
This new editor was TextMate. It is a MacOSX app only. It has some simple bourne shell-like extension language. Or you can use any language you like. They come in "Bundles". Bundles exist for every language under the sun. Further Bundles exist for Version control systems. Checkin, checkout, update, branch, whatever. With windows to prompt for commit messages and the like.
The Git bundle allows you to switch branches real time. It even switches the files you have open in the editor. It has full colorization display windows for diffs and commit logs.
I have only scratch the surface of TextMate. You can start using it without having to buy into some IDE monstrosity like Eclipse. From what I can tell it rivals Eclipse or other IDEs for full Web Application development. Apparently it can run a full Web Application stack and support all the languages (Ruby/Python/Perl, HTML, CSS, and Javascript) side by side.
I haven't used it for so involved a dev environment. But I like how it allows you to start small and simple, then build up to the full stack development environment. From what I can tell this applied equally to (Configure, make, C/C++) or (Ant/Maven, Java, SWT) or (Rake, Ruby on Rails, Web) Application stacks.
I am still just playing with simple Project editing. My projects tend to be libraries and Server-side stuff anyways.
While reading up on Ruby, I came across videos of people writing code real time. First, it is cool Ruby can do high level things in short programs. So short you can watch people coding real time. Second, more apropos, several different presenters were using this cool editor I'd never seen. I thought it was Vim with some crazy programming mode turned on. It completed statements and other coding constructs, speeding up the process of writing code.
This new editor was TextMate. It is a MacOSX app only. It has some simple bourne shell-like extension language. Or you can use any language you like. They come in "Bundles". Bundles exist for every language under the sun. Further Bundles exist for Version control systems. Checkin, checkout, update, branch, whatever. With windows to prompt for commit messages and the like.
The Git bundle allows you to switch branches real time. It even switches the files you have open in the editor. It has full colorization display windows for diffs and commit logs.
I have only scratch the surface of TextMate. You can start using it without having to buy into some IDE monstrosity like Eclipse. From what I can tell it rivals Eclipse or other IDEs for full Web Application development. Apparently it can run a full Web Application stack and support all the languages (Ruby/Python/Perl, HTML, CSS, and Javascript) side by side.
I haven't used it for so involved a dev environment. But I like how it allows you to start small and simple, then build up to the full stack development environment. From what I can tell this applied equally to (Configure, make, C/C++) or (Ant/Maven, Java, SWT) or (Rake, Ruby on Rails, Web) Application stacks.
I am still just playing with simple Project editing. My projects tend to be libraries and Server-side stuff anyways.
Tuesday, June 21, 2011
I took a look at perl5...
and found Modern::Perl. I always put
I've always liked Perl. I found the blather about "line noise" and classes not compelling. Given the number of newbies using all this perl code, it can't be that impossible to read and write (though newbie code usually blows in any language). Classes are hard/complicated? The quantity and quality of CPAN code begs to differ.
I always thought that a switch was one of the features perl needed. An automatic line separator after each print statement is good. That it is short is even better. Two things come to to mind. One, Perl5 is alive and well. Second, what is left for Perl6?
To the second point, I answer, Grammers. I have looked at Grammers with wonder. Grammers provide a method to parse a full (programming) language. The key element that is hinted at is that each level of parsing provides a hook to attach code. So if people, say cpan authors, write a grammer for parsing C code and publishes it; then you can write code to use those hooks. The code is something like
If someone implemented Grammers in Perl5 there maybe no need for perl6.
'Nuff said.
use strict; use warnings; and such things in my code. use Modern::Perl; does more and is succinct. Apparently use 5.10; turns on say and the given ... when switch extension. There is a book about modern styled perl that is worthwhile for even experienced Perl programmers. It is the impetus of the Modern::Perl module. You can by the book or download an electronic version here.I've always liked Perl. I found the blather about "line noise" and classes not compelling. Given the number of newbies using all this perl code, it can't be that impossible to read and write (though newbie code usually blows in any language). Classes are hard/complicated? The quantity and quality of CPAN code begs to differ.
I always thought that a switch was one of the features perl needed. An automatic line separator after each print statement is good. That it is short is even better. Two things come to to mind. One, Perl5 is alive and well. Second, what is left for Perl6?
To the second point, I answer, Grammers. I have looked at Grammers with wonder. Grammers provide a method to parse a full (programming) language. The key element that is hinted at is that each level of parsing provides a hook to attach code. So if people, say cpan authors, write a grammer for parsing C code and publishes it; then you can write code to use those hooks. The code is something like
C::Grammar.parse($str, :$actions);.If someone implemented Grammers in Perl5 there maybe no need for perl6.
'Nuff said.
Friday, June 10, 2011
Just compiled rakudo perl6. Perl6 is UGLY!
Simple things like getting the last element of an array have gotten grotesque. Perl5:
Why such a change? I didn't look deeper. It is such a non-intuitive change to such a common idiom.
Another seemingly unnecessary change: inline comments. The code goes
Perl has a bad rep for being indistinguishable from line noise (or a cat walking on your keyboard). These two changes jumped out at me. They messed with the simple idiom for accessing the last n'th element of an array and added an unnecessary "inline comment" syntax that looks like more gobbleygook.
Supposedly, part of the design goals of perl6 was to make common things easier. So we have
I was looking forward to Grammers as a very powerful tool. Talk about a text munging chainsaw! But some of these other changes are making perl6 very un-perl. Or rather, making perl6 indulge in the worst parts of old perl.
I haven't been paying much attention to perl since 5.8.1 . I hope someone has backported some Grammer-like construct it that is the case, then screw perl6!
$arr[-1]. Perl6: @arr[*-1] ughhh! I don't mind the '@' sigil; that change makes sense. But '*' in the index *-1 doesn't make sense on the face of it.Why such a change? I didn't look deeper. It is such a non-intuitive change to such a common idiom.
Another seemingly unnecessary change: inline comments. The code goes
$x = 1 #`(add one) + 1;. Why would I want to do that? In the 2+ decades I have been coding Perl professionally, I have never felt the need for inline comments. How does that help? How doesn't that obfusicate code?Perl has a bad rep for being indistinguishable from line noise (or a cat walking on your keyboard). These two changes jumped out at me. They messed with the simple idiom for accessing the last n'th element of an array and added an unnecessary "inline comment" syntax that looks like more gobbleygook.
Supposedly, part of the design goals of perl6 was to make common things easier. So we have
$obj.method() instead of $obj->method(); ok fine. And we have '$' for scalars always; '@' for arrays; and '%' for hashes to denote type rather than context. But what is that star '*' doing in the index of the array.I was looking forward to Grammers as a very powerful tool. Talk about a text munging chainsaw! But some of these other changes are making perl6 very un-perl. Or rather, making perl6 indulge in the worst parts of old perl.
I haven't been paying much attention to perl since 5.8.1 . I hope someone has backported some Grammer-like construct it that is the case, then screw perl6!
Subscribe to:
Posts (Atom)