http://nvie.com/ nvie.com 2012-02-01T23:00:00Z Vincent Driessen http://nvie.com/about tag:nvie.com,2012-02-02:/posts/introducing-times/ Introducing Times 2012-02-01T23:00:00Z 2012-02-01T23:00:00Z <p>Lately I&#x2019;ve been getting sick of working with datetimes and timezones in Python. The standard library offers many different conversion routines, but does not prescribe a best practice way to deal with them. Luckily, Armin Ronacher did in his article <a href="http://lucumr.pocoo.org/2011/7/15/eppur-si-muove/">Dealing with Timezones in Python</a>.</p> <p>The summary is to never ever work with local datetimes. When a local datetime is input, immediately convert it to universal time and only ever store or calculate with those. Only when <em>presenting</em> datetimes to the end user, convert them to local time again.</p> <p>This seems simple enough, alright. But to actually <em>do</em> it in Python, you still have to think about how to implement it correctly. Every. Single. Time. <code>pytz</code> does help a bit here, but it still isn&#x2019;t trivial. It should be.</p> <p>Meet <a href="https://github.com/nvie/times"><code>Times</code></a>, a very small Python library to deal with conversions from universal to local timezones and vice versa. It&#x2019;s focused on simplicity and opinionated about what is good practice.</p> <h3>Example use</h3> <p>Imagine you&#x2019;re building a web app that allows your users to set an alarm. Say that someone in the Netherlands sets an alarm to 9:30 am. You can use <code>times</code> to simplify this:</p> <pre><code class="language-pycon"> &gt;&gt;&gt; import times &gt;&gt;&gt; import datetime &gt;&gt;&gt; &gt;&gt;&gt; local_time = datetime.datetime(2012, 2, 3, 9, 30, 0) &gt;&gt;&gt; universal_time = times.to_universal(local_time, 'Europe/Amsterdam') &gt;&gt;&gt; universal_time datetime.datetime(2012, 2, 3, 8, 30) </code></pre> <p>Now, this <code>universal_time</code> variable is safe to store or calculate with.</p> <p>Once you want to show this date to the user again, simply format it for the given timezone:</p> <pre><code class="language-pycon"> &gt;&gt;&gt; times.format(universal_time, 'Europe/Amsterdam') '2012-02-03 09:30:00+0100' </code></pre> <p>If your app allows users to share alerts, it is just as easy to present the alert date to an end user in New Zealand as well:</p> <pre><code class="language-pycon"> &gt;&gt;&gt; times.format(universal_time, 'Pacific/Auckland') '2012-02-03 21:30:00+1300' </code></pre> <h3>Current time</h3> <p>If you ever need to record the current time, you can use</p> <pre><code class="language-pycon"> &gt;&gt;&gt; times.now() datetime.datetime(2012, 2, 2, 16, 4, 40, 283090) </code></pre> <p>Which is actually just an alias to <code>datetime.datetime.utcnow()</code>.</p> <h3>Installing</h3> <p><code>Times</code> is on PyPI (<a href="http://pypi.python.org/pypi/times">link</a>), so just <code>pip install times</code> to use it.</p> <p>Of course, you can <a href="http://github.com/nvie/times">fork me on GitHub</a>.</p> <p>As usual, <code>Times</code> is licensed under the liberal terms of the <span class="caps">BSD</span> license.</p> <p>Lately I&#8217;ve been getting sick of working with datetimes and timezones in Python. The standard library offers many different conversion routines, but does not prescribe a best practice way to deal with them. Luckily, Armin Ronacher did in his article <a href="http://lucumr.pocoo.org/2011/7/15/eppur-si-muove/">Dealing with Timezones in Python</a>.</p> tag:nvie.com,2011-10-06:/posts/thanks-steve/ Thank you, Steve 2011-10-05T22:00:00Z 2011-10-05T22:00:00Z <p>This night, I woke up to the news that <a href="http://www.apple.com/stevejobs/">Steve Jobs passed away</a>. I did not expect to be this touched by the news, although it was to be expected.</p> <p><img src="http://nvie.com/img/2011/10/steve.jpg" class="center shadow" alt=""></p> <p>Steve Jobs has revolutionized the industry several times, each time showing customers what is possible, <em>before</em> customers could even dream about it.</p> <p>He sold personal computers to households, applied the graphical user interface and the mouse to those, and then, in 2007, he saw a future for touch interfaces that fit in your pockets. Not only did he <em>dream</em>, he was able to actually <em>build</em> them. Each of these have set the standard in the industry. It is incredible how a single man was able to sketch this vision, inspire people to move mountains, and to reach these goals with Apple.</p> <h2>Reshaping the world</h2> <p>It is illustrative that the news of Steve&#x2019;s death had not even made it to our news paper this morning, but was read by millions of people on their iPhones instead.</p> <p>Obama used beautiful words to express his impact on mankind:</p> <blockquote> <p>&#x201C;Brave enough to think differently, bold enough to believe he could change the world, and talented enough to do it.&#x201D;</p> </blockquote> <p>Any person that ever touched an Apple device knows it breathes the dedication and craftsmanship that has been put into them, and it is an awesome feeling. Our kids will take this for granted, but we are still aware of where we came from.</p> <h2>Impact on developers</h2> <p>But Steve has also been able to make developers around the world more aware of their impact to users. That you should push hard to leave out unnecessary details. That it is important to pay attention to detail. That <em>building</em> software might be hard, but <em>using</em> software shouldn&#x2019;t.</p> <p>It is his heritage that every creative person on earth will feel Steve looking over his shoulder to push him just a little bit further at each detail. It will result in better products everywhere.</p> <p>The ripple Steve caused in our industry will at least ripple on for a few decades throughout new products and technologies and will be the basis for how our children communicate, are educated, and perceive life.</p> <p>What changed today is that we need to figure it out by ourselves, without his vision. That is scary, but we might just be old enough now ;)</p> <p>Thanks for teaching us.</p> <p>This night, I woke up to the news that <a href="http://www.apple.com/stevejobs/">Steve Jobs passed away</a>. I did not expect to be this touched by the news, although it was to be expected.</p> tag:nvie.com,2011-10-05:/posts/chords-lyrics/ Chords + Lyrics 2011-10-04T22:00:00Z 2011-10-21T22:00:00Z <p>It&#x2019;s been quite a while since I took the time to update this blog. Many things have happened in the meanwhile, though. The most important happening for me is that I launched an iPad app and I founded a company called <a href="http://www.3rdcloud.com">3rd Cloud</a> last week.</p> <h2>Hello, Chords + Lyrics!</h2> <p>An annoying problem amateur musicians might be familiar with is that chords or tablature websites all look very differently, format their song data in various formats, and oftentimes are just plain ugly. Oh, and they&#x2019;re generally paved with ads, too. So to scratch our own itches, I teamed up with <a href="http://twitter.com/jr00n">@jr00n</a> from <a href="http://www.studiowolff.nl">StudioWolff</a> to create <a href="http://www.chordsandlyricsapp.com">Chords + Lyrics</a>.</p> <p>Chords + Lyrics is a simple music manager for your iPad that allows you to easily import songs and lyrics from your favorite chords website (that means: <em>any</em> website&#x2014;it recognizes the chords semantically):</p> <p><img src="http://nvie.com/img/2011/10/showcase3.png" class="center" alt=""></p> <p>Once imported, the chords become editable objects in the form of bubbles, which makes it easy for you to edit or finetune the imported songs. A carefully selected choice of fonts is used to create a readable and uniform look and feel for your song&#x2019;s chords and lyrics:</p> <p><img src="http://nvie.com/img/2011/10/showcase1.png" class="center" alt=""></p> <p>Furthermore, once the editing is done, you can simply take Chords + Lyrics on stage with your band or solo performance and leave your stack of sheet music at home. When the device is rotated into landscape orientation, the user interface transforms into a big music stand that arranges the songs of choice as a stack of virtual music sheets in the order of your playlist:</p> <p><img src="http://nvie.com/img/2011/10/showcase4.png" class="center" alt=""></p> <p>You can get a sneak peak of the app by watching this video:</p> <p><iframe width="560" height="420" src="http://www.youtube.com/embed/pG51bemU0ok?rel=0&amp;hd=1" frameborder="0"></iframe></p> <p>The app is sold at $5.99. Check us out in the <a href="http://itunes.apple.com/us/app/chords-lyrics/id462295346?ls=1&amp;mt=8">App Store</a>.</p> <p><a href="http://itunes.apple.com/us/app/chords-lyrics/id462295346?ls=1&amp;mt=8"><img src="http://nvie.com/img/2011/10/appstore_badge.png" class="center" alt=""></a></p> <h2>The Role of Appsterdam</h2> <p>Jeroen and I met during <a href="http://www.iosdevcamp.org/">iOS Dev Camp</a> last March and immediately were excited with the idea for Chords + Lyrics. We even received the <em>Most Likely to Succeed</em> award from <a href="http://twitter.com/dom">Dom Sogolla</a> and <a href="http://twitter.com/bmf">Mike Lee</a> at the end of those two days, which got us even more excited about the project.</p> <p>We started hacking away at it in our spare time for the next few months. While at the same time, by some kind of lucky coincidence, the same Mike Lee started building an awesome developer community for app developers: <a href="http://www.appsterdam.rs">Appsterdam</a>.</p> <p><img src="http://nvie.com/img/2011/10/appsterdam.png" class="center shadow" alt=""></p> <p>Many of our thanks therefore go out to all of the Appsterdammers, in particular Mike and <a href="http://twitter.com/judykitteh">Judy</a>, for inspiring us at the moments we got stuck and for the helpful pieces of advice we got from them. Without the Appsterdam community, the project may have never seen the light of day, or be much less awesome.</p> <p>Let this be the first of many apps!</p> <p>It&#8217;s been quite a while since I took the time to update this blog. Many things have happened in the meanwhile, though. The most important happening for me is that I launched an iPad app and I founded a company called <a href="http://www.3rdcloud.com">3rd Cloud</a> last week.</p> tag:nvie.com,2011-01-27:/posts/a-git-flow-screencast/ A git-flow screencast 2011-01-26T23:00:00Z 2011-05-24T22:00:00Z <p>Mr. <a href="http://www.davebock.com/">Dave Bock</a> of Code Sherpa&#x2019;s put together a nice screencast demonstrating a few of the most important git-flow features on their <a href="http://www.codesherpas.com/portfolio/publications">publications</a> page.</p> <p><a href="http://codesherpas.com/screencasts/on_the_path_gitflow.mov"><img src="http://nvie.com/img/2011/01/screencast_still.png" class="center" alt=""></a></p> <p>Many thanks to Dave for creating this!</p> <p>Dave Bock created a nice video on using git-flow.</p> tag:nvie.com,2010-11-16:/posts/python-vs-ruby-survey/ Survey: Python vs Ruby Test Ecosystems 2010-11-15T23:00:00Z 2010-11-15T23:00:00Z <p><strong>tl;dr</strong> Please help out and take <a href="http://goo.gl/j0blw">the survey</a>. It only takes one or two minutes.</p> <p>In my spare time, I love to read up on many different topics that are happening in the modern world of software development. On many occasions, the initiatives that I find most interesting are happening in the Python and Ruby communities.</p> <p><img src="http://nvie.com/img/2010/11/py-vs-ruby.png" class="center" alt=""></p> <p>I immediately have to admit that I&#x2019;m not too actively involved in the Ruby community yet. It is a language that I don&#x2019;t have much &#x201C;handson experience&#x201D; with. Although I think the Ruby community is a bit more chaotic than Python&#x2019;s, I also believe that more exciting things are happening there. Ruby definitely got the more snazzy and sexier appeal of the two, but I also think it&#x2019;s the more naive brother of the two that gets in trouble in its teen years (think drugs and jail).</p> <h2>Lovable and Loathsome Language Features</h2> <p>I have always found it really hard to express what I dislike about Ruby. In my college years, I really enjoyed functional programming and I absolutely adore the influences Ruby got from that world. Solving programming problems with the typical Ruby language constructs like blocks is very satisfying and feels really elegant. Next to that, Ruby makes a gorgeous language for creating DSLs.</p> <p>Yet, the &#x201C;black magic&#x201D; and the implicit behaviour that also accompany Ruby give me the eerie feeling that I&#x2019;m not in control.</p> <p>When I stumbled upon this video by Gary Bernhardt: <a href="http://vimeo.com/9471538">Python vs Ruby: A Battle to The Death</a>, all the pieces of the puzzle fell together for me. In this talk, Gary puts to words what my feelings about the two languages are to a great extent. Result: I love both and I hate both.</p> <h2>Uncovering Test Ecosystems</h2> <p>Especially the conclusions Gary draws about RSpec being a superiour specification language is something I share. There simply is no good equivalent of RSpec for Python. In fact, it&#x2019;s impossible to ever create one in Python, due to Python&#x2019;s inability to inject methods into <code>object</code> and its lack of blocks, and therefore, its lack of <span class="caps">DSL</span> capabilities. (Oh yes, there <a href="http://darcs.idyll.org/~t/projects/pinocchio/doc/#spec-generate-test-description-from-test-class-method-names">have</a> <a href="http://bitbucket.org/garybernhardt/mote/">been</a> <a href="https://gist.github.com/327596">attempts</a>. None of them are as good as the real thing.)</p> <p>This made me think. Does Ruby have a more mature testing culture? If I browse around interesting projects on Github, for example, I always get the feeling that the Ruby projects have better tests and better coverage than the Python ones (sorry, no scientific proof here). <span class="small lite">&lt;bait&gt;Maybe they have to <em>because</em> of the magic in Ruby? ;)&lt;/bait&gt;</span> But most importantly, the Ruby culture seem to <em>care more</em> (or at least have higher awareness) about actually testing their code at all.</p> <p>At the same time, I get the feeling that the Ruby culture has <em>less</em> testing tools available. Maybe this is because I simply don&#x2019;t know the Ruby community as well as I know Python&#x2019;s, but maybe there has been a lot more consensus and standardisation already.</p> <h2>Only one way to find out</h2> <p>This made me curious, so I decided to pull up a <a href="http://goo.gl/j0blw">quick survey</a>. I hereby invite all Python and Ruby developers out there to participate in it. Please help spread the word on Twitter to get as many participants as possible. The more answers received, the stronger the map of available and popular tools will be. I&#x2019;ve also included a few questions on the use of continuous build and integration systems. After taking the survey you can see the results so far.</p> <p>I&#x2019;ll make sure to blog about any interesting conclusions that can be drawn from the numbers that I will gather with this.</p> <p>In this post I call out for participation in <a href="http://goo.gl/j0blw">a survey</a> that I quickly put together this evening to get a better overview of the most-used unit testing, spec and code coverage tools for both Python and Ruby.</p> <p>Suffice to say that I will blog about any interesting results or conclusions that I will draw from this survey.</p> tag:nvie.com,2010-09-14:/posts/how-i-boosted-my-vim/ How I boosted my Vim 2010-09-13T22:00:00Z 2010-09-22T22:00:00Z <p>A few weeks ago, I felt inspired by articles from <a href="http://jeffkreeftmeijer.com/2010/stumbling-into-vim/">Jeff Kreeftmeijer</a> and <a href="http://lucumr.pocoo.org/2010/7/29/sharing-vim-tricks">Armin Ronacher</a>. I took some time to configure and fine-tune my Vim environment. A lot of new stuff made it into my <code>.vimrc</code> file and my <code>.vim</code> directory. This blog post is a summary describing what I&#x2019;ve added and how I use it in my daily work.</p> <p>Before doing anything else, make sure you have the following line in your <code>.vimrc</code> file:</p> <pre><code class="language-vim"> " This must be first, because it changes other options as side effect set nocompatible </code></pre> <h2 id="pathogen">Step 0: make the customization process easier</h2> <p>Before starting configuring, it&#x2019;s useful to install <a href="http://www.vim.org/scripts/script.php?script_id=2332">pathogen</a>. Plugins in Vim are files that you drop in subdirectories of your <code>.vim/</code> directory. Many plugins exist of only a single file that should be dropped in <code>.vim/plugin</code>, but some exist of multiple files. For example, they come with documentation, or ship syntax files. In those cases, files need to be dropped into <code>.vim/doc</code> and <code>.vim/syntax</code>. This makes it difficult to remove the plugin afterwards. After installing pathogen, you can simply unzip a plugin distribution into <code>.vim/bundle/myplugin</code>, under which the required subdirectories are created. Removing the plugin, then, is as simple as removing the <code>myplugin</code> directory.</p> <p>So, download <code>pathogen.vim</code>, move it into the <code>.vim/autoload</code> directory (create it if necessary) and add the following lines to your <code>.vimrc</code>, to activate it:</p> <pre><code class="language-vim"> " Use pathogen to easily modify the runtime path to include all " plugins under the ~/.vim/bundle directory call pathogen#helptags() call pathogen#runtime_append_all_bundles() </code></pre> <p>Next, I&#x2019;ve remapped the leader key to <code>,</code> (comma) instead of the default <code>\</code> (backslash), just because I like it better. Since in Vim&#x2019;s default configuration, almost every key is already mapped to a command, there needs to be some sort of standard &#x201C;free&#x201D; key where you can place custom mappings under. This is called the &#x201C;mapleader&#x201D;, and can be defined like this:</p> <pre><code class="language-vim"> " change the mapleader from \ to , let mapleader="," </code></pre> <p>Once that is done, this is a little tweak that is a time-saver while you&#x2019;re building up your <code>.vimrc</code>. Here, we start using the leader key:</p> <pre><code class="language-vim"> " Quickly edit/reload the vimrc file nmap &lt;silent&gt; &lt;leader&gt;ev :e $MYVIMRC&lt;CR&gt; nmap &lt;silent&gt; &lt;leader&gt;sv :so $MYVIMRC&lt;CR&gt; </code></pre> <p>This effectively maps the <code>,ev</code> and <code>,sv</code> keys to edit/reload <code>.vimrc</code>. (I got this from <a href="http://derekwyatt.org/">Derek Wyatt</a>&#x2019;s <code>.vimrc</code> file.)</p> <h2>Change Vim behaviour</h2> <p>One particularly useful setting is <code>hidden</code>. Its name isn&#x2019;t too descriptive, though. It <em>hides</em> buffers instead of <em>closing</em> them. This means that you can have unwritten changes to a file and open a new file using <code>:e</code>, without being forced to write or undo your changes first. Also, undo buffers and marks are preserved while the buffer is open. This is an absolute must-have.</p> <pre><code class="language-vim"> set hidden </code></pre> <p>These are some of the most basic settings that you probably want to enable, too:</p> <pre><code class="language-vim"> set nowrap " don't wrap lines set tabstop=4 " a tab is four spaces set backspace=indent,eol,start " allow backspacing over everything in insert mode set autoindent " always set autoindenting on set copyindent " copy the previous indentation on autoindenting set number " always show line numbers set shiftwidth=4 " number of spaces to use for autoindenting set shiftround " use multiple of shiftwidth when indenting with '&lt;' and '&gt;' set showmatch " set show matching parenthesis set ignorecase " ignore case when searching set smartcase " ignore case if search pattern is all lowercase, " case-sensitive otherwise set smarttab " insert tabs on the start of a line according to " shiftwidth, not tabstop set hlsearch " highlight search terms set incsearch " show search matches as you type </code></pre> <p>There is a lot more goodness in my <a href="http://github.com/nvie/vimrc/raw/master/vimrc"><code>.vimrc</code></a> file, which is put in there with a lot of love. I&#x2019;ve commented most of it, too. Feel free to poke around in it.</p> <p>Also, I like Vim to have a large undo buffer, a large history of commands, ignore some file extensions when completing names by pressing Tab, and be silent about invalid cursor moves and other errors.</p> <pre><code class="language-vim"> set history=1000 " remember more commands and search history set undolevels=1000 " use many muchos levels of undo set wildignore=*.swp,*.bak,*.pyc,*.class set title " change the terminal's title set visualbell " don't beep set noerrorbells " don't beep </code></pre> <p>Oh, and man&#x2026; never ever let Vim write a backup file! They did that in the 70&#x2019;s. Use <a href="http://git-scm.com/">modern</a> ways for tracking your changes, for God&#x2019;s sake.</p> <pre><code class="language-vim"> set nobackup set noswapfile </code></pre> <p><ins>There have been some passionate responses about this in comments, so a warning may be appropriate here. If you care about recovering after a Vim or terminal emulator crash, or you often load huge files into memory, do <strong>not</strong> disable the swapfile. I personally save/commit so <a href="http://jeffkreeftmeijer.com/2010/git-your-act-together/#commit-all-the-fucking-time">often</a> that the swap file adds nothing. Sometimes I conciously kill a terminal forcefully, and I only find the swap file recovery process annoying.</ins></p> <h2>Use file type plugins</h2> <p>Vim can detect file types (by their extension, or by peeking inside the file). This enabled Vim to load plugins, settings or key mappings that are only useful in the context of specific file types. For example, a Python syntax checker plugin only makes sense in a Python file. Finally, indenting intelligence is enabled based on the syntax rules for the file type.</p> <pre><code class="language-vim"> filetype plugin indent on </code></pre> <p>To set some file type specific settings, you can now use the following:</p> <pre><code class="language-vim"> autocmd filetype python set expandtab </code></pre> <p>To remain compatible with older versions of Vim that do not have the <code>autocmd</code> functions, always wrap those functions inside a block like this:</p> <pre><code class="language-vim"> if has('autocmd') ... endif </code></pre> <h2>Enable syntax highlighting</h2> <p>Somewhat related to the file type plugins is the syntax highlighting of different types of source files. Vim uses syntax definitions to highlight source code. Syntax definitions simply declare where a function name starts, which pieces are commented out and what are keywords. To color them, Vim uses colorschemes. You can load custom color schemes by placing them in <code>.vim/colors</code>, then load them using the <code>colorscheme</code> command. You have to try what you like most. I like <a href="http://hcalves.deviantart.com/art/Mustang-Vim-Colorscheme-98974484">mustang</a> a lot.</p> <pre><code class="language-vim"> if &amp;t_Co &gt;= 256 || has("gui_running") colorscheme mustang endif if &amp;t_Co &gt; 2 || has("gui_running") " switch syntax highlighting on, when the terminal has colors syntax on endif </code></pre> <p>In this case, mustang is only loaded if the terminal emulator Vim runs in supports at least 256 colors (or if you use the <span class="caps">GUI</span> version of Vim).</p> <p><strong>Hint</strong>: if you&#x2019;re using a terminal emulator that can show 256 colors, try setting <code>TERM=xterm-256color</code> in your terminal configuration or in your shell&#x2019;s .rc file.</p> <h2>Change editing behaviour</h2> <p>When you write a lot of code, you probably want to obey certain style rules. In some programming languages (like Python), whitespace is important, so you may not just swap tabs for spaces and even the number of spaces is important.</p> <p>Vim can highlight whitespaces for you in a convenient way:</p> <pre><code class="language-vim"> set list set listchars=tab:&gt;.,trail:.,extends:#,nbsp:. </code></pre> <p>This line will make Vim set out tab characters, trailing whitespace and invisible spaces visually, and additionally use the <code>#</code> sign at the end of lines to mark lines that extend off-screen. For more info, see <code>:h listchars</code>.</p> <p>In some files, like <span class="caps">HTML</span> and <span class="caps">XML</span> files, tabs are fine and showing them is really annoying, you can disable them easily using an <code>autocmd</code> declaration:</p> <pre><code class="language-vim"> autocmd filetype html,xml set listchars-=tab:&gt;. </code></pre> <p>One caveat when setting <code>listchars</code>: if nothing happens, you have probably not enabled <code>list</code>, so try <code>:set list</code>, too.</p> <h3>Pasting large amounts of text into Vim</h3> <p>Every Vim user likes to enable auto-indenting of source code, so Vim can intelligently position you cursor on the next line as you type. This has one big ugly consequence however: when you paste text into your terminal-based Vim with a right mouse click, Vim cannot know it is coming from a paste. To Vim, it looks like text entered by someone who can type incredibly fast :) Since Vim thinks this is regular key strokes, it applies all auto-indenting and auto-expansion of defined abbreviations to the input, resulting in often cascading indents of paragraphs.</p> <p>There is an easy option to prevent this, however. You can temporarily switch to &#x201C;paste mode&#x201D;, simply by setting the following option:</p> <pre><code class="language-vim"> set pastetoggle=&lt;F2&gt; </code></pre> <p>Then, when in insert mode, ready to paste, if you press <code>&lt;F2&gt;</code>, Vim will switch to paste mode, disabling all kinds of smartness and just pasting a whole buffer of text. Then, you can disable paste mode again with another press of <code>&lt;F2&gt;</code>. Nice and simple. Compare paste mode disabled vs enabled:</p> <p class="autoalign"><img src="http://nvie.com/img/2010/08/ugly-paste.png" alt=""> <img src="http://nvie.com/img/2010/08/better-paste.png" alt=""></p> <p><ins>Another great trick I read in a <a href="http://www.reddit.com/r/programming/comments/ddbuc/how_i_boosted_my_vim/c0zelsm">reddit comment</a> is to use <code>&lt;C-r&gt;+</code> to paste right from the OS paste board. Of course, this only works when running Vim locally (i.e. not over an <span class="caps">SSH</span> connection).</ins></p> <h3>Enable the mouse</h3> <p>While using the mouse is considered a deadly sin among Vim users, there <em>are</em> a few features about the mouse that can really come to your advantage. Most notably&#x2014;scrolling. In fact, it&#x2019;s the only thing I use it for.</p> <p>Also, if you are a rookie Vim user, setting this value will make your Vim experience definitively feel more natural.</p> <p>To enable the mouse, use:</p> <pre><code class="language-vim"> set mouse=a </code></pre> <p>However, this comes at one big disadvantage: when you run Vim inside a terminal, the terminal itself cannot control your mouse anymore. Therefore, you cannot select text anymore with the terminal (to copy it to the system clipboard, for example).</p> <p>To be able to have the best of both worlds, I wrote this simple Vim plugin: <a href="http://github.com/nvie/vim-togglemouse">vim-togglemouse</a>. It maps <code>&lt;F12&gt;</code> to toggle your mouse &#x201C;focus&#x201D; between Vim and the terminal.</p> <p>Small plugins like these are really useful, yet have the additional benefit of lowering the barrier of learning the Vim scripting language. At the core, this plugin exists of only one simple function:</p> <pre><code class="language-vim"> fun! s:ToggleMouse() if !exists("s:old_mouse") let s:old_mouse = "a" endif if &amp;mouse == "" let &amp;mouse = s:old_mouse echo "Mouse is for Vim (" . &amp;mouse . ")" else let s:old_mouse = &amp;mouse let &amp;mouse="" echo "Mouse is for terminal" endif endfunction </code></pre> <h3>Get efficient: shortcut mappings</h3> <p>The following trick is a really small one, but a super-efficient one, since it strips off two full keystrokes from almost every Vim command:</p> <pre><code class="language-vim"> nnoremap ; : </code></pre> <p>For example, to save a file, you type <code>:w</code> normally, which means:</p> <ol> <li>Press and hold Shift</li> <li>Press <code>;</code> </li> <li>Release the Shift key</li> <li>Press <code>w</code> </li> <li>Press Return</li> </ol> <p>This trick strips off steps 1 and 3 for <strong>each</strong> Vim command. It takes some times for your muscle memory to get used to this new <code>;w</code> command, but once you use it, you don&#x2019;t want to go back!</p> <p>I also find this key binding very useful, since I like to reformat paragraph text often. Just set your cursor inside a paragraph and press <code>Q</code> (or select a visual block and press <code>Q</code>).</p> <pre><code class="language-vim"> " Use Q for formatting the current paragraph (or selection) vmap Q gq nmap Q gqap </code></pre> <p>If you are still getting used to Vim and want to force yourself to stop using the arrow keys, add this:</p> <pre><code class="language-vim"> map &lt;up&gt; &lt;nop&gt; map &lt;down&gt; &lt;nop&gt; map &lt;left&gt; &lt;nop&gt; map &lt;right&gt; &lt;nop&gt; </code></pre> <p>If you like long lines with line wrapping enabled, this solves the problem that pressing down jumpes your cursor &#x201C;over&#x201D; the current line to the next line. It changes behaviour so that it jumps to the next row in the editor (much more natural):</p> <pre><code class="language-vim"> nnoremap j gj nnoremap k gk </code></pre> <p>When you start to use Vim more professionally, you want to work with multiple windows open. Navigating requires you to press <code>C-w</code> first, then a navigation command (h, j, k, l). This makes it easier to navigate focus through windows:</p> <pre><code class="language-vim"> " Easy window navigation map &lt;C-h&gt; &lt;C-w&gt;h map &lt;C-j&gt; &lt;C-w&gt;j map &lt;C-k&gt; &lt;C-w&gt;k map &lt;C-l&gt; &lt;C-w&gt;l </code></pre> <p>Tired of clearing highlighted searches by searching for &#x201C;ldsfhjkhgakjks&#x201D;? Use this:</p> <pre><code class="language-vim"> nmap &lt;silent&gt; ,/ :nohlsearch&lt;CR&gt; </code></pre> <p><ins>I used to have it mapped to <code>:let @/=""&lt;CR&gt;</code>, but some users kindly pointed out that it is better to use <code>:nohlsearch</code>, because it keeps the search history intact.</ins></p> <p>It clears the search buffer when you press <code>,/</code></p> <p>Finally, a trick by <a href="http://forrst.com/posts/Use_w_to_sudo_write_a_file_with_Vim-uAN">Steve Losh</a> for when you forgot to <code>sudo</code> before editing a file that requires root privileges (typically <code>/etc/hosts</code>). This lets you use <code>w!!</code> to do that <strong>after</strong> you opened the file already:</p> <pre><code class="language-vim"> cmap w!! w !sudo tee % &gt;/dev/null </code></pre> <h2>Use plugins</h2> <p>Ah, finally. Arrived at the magical stuff that is Vim plugins. This is a listing of the Vim plugins I depend on most and that really offer added value when you work with Vim every day.</p> <p><img src="http://nvie.com/img/2010/08/textmate.png" class="right" alt=""></p> <p>Almost any person I know who owns a Mac has at least tried or purchased the <a href="http://macromates.com/">TextMate</a> editor. It is a great programmer&#x2019;s editor that has a lot of nice features, but of course, lacks Vim-style navigation :)</p> <p><ins>Some of its features have inspired Vim plugin developers to clone the awesomeness. TextMate&#x2019;s best two features (super-quick file opening and snippets) have been &#x201C;ported&#x201D; to Vim plugins.</ins></p> <h3 id="command-t"> <ins>Command-T: TextMate-style file opening</ins> <del>NERDTree explorer</del> </h3> <p><!-- Old NERDTree explorer stuff {{{ --> <div class="del"></div> <p>The NERDTree plugin is an absolute must for almost any Vim user. For those who don&#x2019;t know it yet, NERDTree is a visual file browser that allows you to quickly open files by navigating onto it and pressing Return.</p> <p>You can open the NERDTree using the <code>:NERDTree</code> command, or by using <code>:NERDTreeToggle</code>. To close the tree window, use <code>:NERDTreeClose</code>.</p> <p><img src="http://nvie.com/img/2010/08/nerdtree.png" alt=""></p> <p>I have I&#x2019;ve mapped some shortcuts to these commands, for quick access to the list:</p> <pre><code class="language-vim"> nmap ,n :NERDTreeCloseCR:NERDTreeToggleCR nmap ,m :NERDTreeCloseCR:NERDTreeFindCR nmap ,N :NERDTreeCloseCR </code></pre> <p>You can add quick bookmarks to directories that you often visit (like project directories), which works really well. I have configured the following settings, which tells the plugin where the bookmark file is, which extensions to ignore, to show hidden files and to quit on open (which I like to have on, to have screen real estate for my code):</p> <pre><code class="language-vim"> " Store the bookmarks file let NERDTreeBookmarksFile=expand("$HOME/.vim/NERDTreeBookmarks") " Don't display these kinds of files let NERDTreeIgnore=[ '\.pyc$', '\.pyo$', '\.py\$class$', '\.obj$', \ '\.o$', '\.so$', '\.egg$', '^\.git$' ] let NERDTreeShowBookmarks=1 " Show the bookmarks table on startup let NERDTreeShowFiles=1 " Show hidden files, too let NERDTreeShowHidden=1 let NERDTreeQuitOnOpen=1 " Quit on opening files from the tree let NERDTreeHighlightCursorline=1 " Highlight the selected entry in the tree let NERDTreeMouseMode=2 " Use a single click to fold/unfold directories " and a double click to open files </code></pre> <p>You can add quick bookmarks to directories that you often visit (like project directories), which works really well, too.</p> <p>More documentation available at: the <a href="http://www.vim.org/scripts/script.php?script_id=1658">plugin page</a>.</p> </p> <p><!-- }}} --> <div class="ins"></div> <p>I used to have a whole discussion on the <a href="http://www.vim.org/scripts/script.php?script_id=1658">NERDTree explorer</a> plugin here, but I was pointed towards <a href="https://wincent.com/products/command-t">Command-T</a> by a few readers. Once I tried that plugin for a few minutes, it became clear that there would be no need for NERDTree anymore.</p> <p>The name Command-T is a reference to the original shortcut for &#x201C;Go to File&#x201D; in TextMate, which opens the quick file opener. Setting up this plugin is a bit more tricky than usual, because some files need to be compiled, but the instructions on the website are very clear and simple. There&#x2019;s even a screencast for Windows users.</p> <p>The plugin registers itself under <code>leadert</code> (in my case that&#x2019;s <code>,t</code>). And if it does, it shows a list of all the files from the current directory and a search box in which you can type any character progression. By typing more characters, the list of files is narrowed down to contain only files that have that string as a subset. But here&#x2019;s the real added value: you can type any sequence of characters that are in the file&#x2019;s path, they don&#x2019;t have to be subsequent characters. For example, if you have the following list of files:</p> <pre><code>foo/bar.py foo/qux.py tests/test_foo/test_bar.py tests/test_foo/test_qux.py</code></pre> <p>You could type the sequence <strong>fb</strong> to select the file <code>foo/bar.py</code>, or <strong>tfb</strong> to select <code>tests/test_foo/test_bar.py</code>. As you can imagine, this is a huge time saver. There is much more goodness in there. For that, please refer to Wincent&#x2019;s screencasts, or his website.</p> <p>You can download the plugin at <a href="http://www.vim.org/scripts/script.php?script_id=3025">vim.org</a>.</p> <p><strong>Note</strong>: On Vim instances that don&#x2019;t have Ruby support enabled (type <code>:version</code> to check this), the Commant-T plugin won&#x2019;t work. If it isn&#x2019;t an option to recompile Vim to add Ruby support, the <a href="http://www.vim.org/scripts/script.php?script_id=1658">NERDTree explorer</a> still is a good alternative.</p> </p> <h3>Snipmate: TextMate-style snippets for Vim</h3> <p>Another killer feature of TextMate are the intelligent snippets: you type some text, press Tab and TextMate creates a snippet for you, with placeholders at key positions within the snippet. The first placeholder is selected, your overwrite it with the text you want, then press Tab to select the second placeholder, etc. This lets you enter code super fast.</p> <p>Now it&#x2019;s available to us Vim users, too, in the form of the <a href="http://www.vim.org/scripts/script.php?script_id=2540">snipMate plugin</a> (dubbed after TextMate). There&#x2019;s a great <a href="http://vimeo.com/3535418">introductory screencast</a> to get you excited about it.</p> <h4>Writing your own snippets</h4> <p>There are already lots of specific language <del>plugins</del> <ins><a href="http://github.com/scrooloose/snipmate-snippets">snippets</a></ins> for snipMate available, but writing your own is simple in case you ever miss functionality. Just create a file called <code>~/.vim/snippets/foo.snippet</code>, where <code>foo</code> is the filetype you want to load the snippets for.</p> <p>Then, declare your snippets. That&#x2019;s really as easy as this:</p> <pre><code>snippet def def ${1:fname}(${2:arg}): ${3:pass}</code></pre> <p>If you declare this, you can simply use <code>defTab</code> and it will expand to a Python function definition. The <code>${1:fname}</code> means put the first placeholder at this position, and fill it with a default value of &#x201C;fname&#x201D;.</p> <h3>Other cool plugins</h3> <p>In order to make the article not any more longer than it already is, here&#x2019;s a list of other plugins that are really worth checking out (I use each of them regularly):</p> <ul> <li> <a href="http://www.vim.org/scripts/script.php?script_id=1408">localrc</a>: lets you load specific Vim settings for any file in the same directory (or a subdirectory thereof). Comes in super handy for project-wide settings.</li> <li><ins><a href="http://github.com/rstacruz/sparkup">Sparkup</a>: write <span class="caps">HTML</span> lightning fast by jotting down a &#x201C;<span class="caps">CSS</span> selector&#x201D;-like line and pressing a shortcut. Super time saver when you edit <span class="caps">HTML</span> manually. Go see <a href="http://www.youtube.com/watch?v=Jw3jipcenKc">the demo video</a>.</ins></li> <li><ins><a href="http://www.vim.org/scripts/script.php?script_id=1234">YankRing</a>: quickly cycle through your registers when pasting, to select the appropriate paste. How often have you &#x201C;cut&#x201D; a line, then &#x201C;deleted&#x201D; a line, only to find the &#x201C;deleted&#x201D; line in your last paste register?</ins></li> <li> <a href="http://www.vim.org/scripts/script.php?script_id=1624">Pastie</a>: lets you visually select a piece of code and submit it to <a href="http://pastie.org">pastie.org</a>. It even has automatic filetype recognition.</li> <li> <a href="http://www.vim.org/scripts/script.php?script_id=1697">surround</a>: quickly change surroundings of a piece of code. For example, to change <code>dict(mykey)</code> into <code>dict[mykey]</code>, put the cursor on <code>mykey</code>, then type <code>cs(]</code> (change surroundings from <code>()</code> to <code>[]</code>).</li> <li> <a href="http://www.vim.org/scripts/script.php?script_id=2136">repeat</a>: lets you repeat the changing of surroundings using the default Vim repeat operator <code>.</code> (dot).</li> <li> <a href="http://www.vim.org/scripts/script.php?script_id=1545">abolish</a>: bulk-define autocorrections (abbreviations) for many conjugations of words and smart conversion of words from snake_case (<code>crs</code>) to camelCase (<code>cr_</code>) or MixedCase (<code>crm</code>) to UPPER_CASE (<code>cru</code>) and vice versa.</li> <li><ins><a href="http://www.vim.org/scripts/script.php?script_id=2050">LustyJuggler</a>: a quick buffer switcher and a great companion to Command-T. See <a href="http://lococast.net/archives/185">this screencast</a> (Lococast) to get excited.</ins></li> </ul> <div class="ins"> <h3>Other resources</h3> <p>Some of the resources from where I have collected inspiration for my <code>.vimrc</code> file, plugins, and tricks:</p> <ul> <li><a href="http://vimcasts.org/">Vimcasts</a></li> <li><a href="http://lococast.net/">Lococast</a></li> <li> <a href="http://vimeo.com/user1690209/videos">Derek Wyatt&#x2019;s videos</a> (on Vimeo)</li> <li><ins>Steve Losh blogged about <a href="http://stevelosh.com/blog/2010/09/coming-home-to-vim/">moving back to Vim</a> and has some great tips and tricks.</ins></li> </ul> </div> <p>I hope you like these tips. Please add your comments below if you do, or if you have any Vim improvements or tips you&#x2019;d like to bring on yourself. <ins>You can have a look at my full Vim configuration in my <a href="http://github.com/nvie/vimrc">Github repo</a>.</ins></p> <p>A few weeks ago, I felt inspired by articles from <a href="http://jeffkreeftmeijer.com/2010/stumbling-into-vim/">Jeff Kreeftmeijer</a> and <a href="http://lucumr.pocoo.org/2010/7/29/sharing-vim-tricks">Armin Ronacher</a>. I took some time to configure and fine-tune my Vim environment. A lot of new stuff made it into my <code>.vimrc</code> file and my <code>.vim</code> directory. This blog post is a summary describing what I&#8217;ve added and how I use it in my daily work.</p> tag:nvie.com,2010-09-13:/posts/a-whole-new-blog/ A whole new blog 2010-09-12T22:00:00Z 2010-09-12T22:00:00Z <p>Finally, I&#x2019;ve made the move to a static blog engine! I&#x2019;m using <a href="http://nanoc.stoneship.org/">nanoc</a> now (bye bye WordPress). nanoc is a very flexible and customizable static site generator, written by <a href="http://twitter.com/ddfreyne">Denis Defreyne</a>.</p> <p>As with all static site generators, nanoc lets you write your source files in a simple markup language. Out of the box, nanoc offers you the choice of using Markdown, Textile, reStructuredText or plain <span class="caps">HTML</span> (with or without embedded Ruby). In fact, nanoc is nothing more than a generator honoring a <code>Rules</code>-file that tells it how to compile, layout and route the site&#x2019;s items.</p> <h2>Compiling items</h2> <p>An &#x201C;item&#x201D; is a file on your website. It can be any kind of file, like a web site page (<span class="caps">HTML</span>), an image, a JavaScript or <span class="caps">CSS</span> file or an <span class="caps">RSS</span> feed. During the compile phase, you specify which sequential actions should be performed on the <em>content</em> of that item. These actions are called <strong>filters</strong>. Some examples of filters are an embedded ruby filter, a <a href="http://redcloth.org/">Textile-to-<span class="caps">HTML</span></a> converter, a <a href="http://lesscss.org/">less</a> compiler, or minify <a href="http://code.google.com/p/rainpress/"><span class="caps">CSS</span></a>. Filters can be chained, for example:</p> <pre><code class="language-ruby"> compile '/static/css/*/' do # compress CSS :) filter :less filter :rainpress end </code></pre> <p>Which turns <code>.less</code>-files into compressed <span class="caps">CSS</span>:</p> <p><img src="http://nvie.com/img/2010/09/less2css.png" alt=""></p> <p>Any filter you can imagine, nanoc can handle. nanoc comes with a lot of filters <a href="http://nanoc.stoneship.org/docs/4-basic-concepts/#filters">out of the box</a>, but even <a href="http://nanoc.stoneship.org/docs/5-advanced-concepts/#writing-filters">writing your own</a> filters really is a piece of cake.</p> <h2>Routing items</h2> <p>After compiling (i.e. transforming content through filters) comes the routing of the items. This is a means of assigning file names to compiled content. nanoc calculates default files names from the input, but you can use this to influence the default naming. A special case is where you set the route to <code>Nil</code> which doesn&#x2019;t write the file at all. I use this to test draft posts locally, like this (oh, did I mention the <code>Rules</code> file is 100% Ruby?):</p> <pre><code class="language-ruby"> route '/posts/*/' do if $include_drafts or @item[:published] then '/posts/' + @item.slug + '/index.html' end end </code></pre> <h2>Laying out items</h2> <p>Finally, layouts are applied. Layouts are kind of templates that can be used to &#x201C;frame&#x201D; the item&#x2019;s contents. This is typically used for <span class="caps">HTML</span> files only, but isn&#x2019;t limited to it. For example, the blog posts are compiled into (partial) <span class="caps">HTML</span>, and the layout rules put the site&#x2019;s container <span class="caps">HTML</span> around it, adding <span class="caps">CSS</span> styling, jQuery scripts, the header, sidebars and footer and Google Analytics tracking (these go for each page). There&#x2019;s a special extra layout rule for blog post pages, which additionally adds Disqus comments.</p> <h2>Summary</h2> <p>Each build of this blog also automatically:</p> <ul> <li>Converts <a href="http://redcloth.org/">Textile</a> content to <span class="caps">HTML</span> </li> <li>Highlights syntax using <a href="http://pygments.org/">pygments</a> </li> <li>Converts <a href="http://lesscss.org/">less</a> to <span class="caps">CSS</span> </li> <li>Minifies <a href="http://code.google.com/p/rainpress/"><span class="caps">CSS</span></a> </li> <li>Minifies <a href="http://code.google.com/closure/compiler/">JavaScript</a> </li> <li> <a href="http://www.graphicsmagick.org/convert.html">Downsizes</a> source images</li> <li>Generates redirect pages for alternative (old-style) URL&#x2019;s (for user that have existing bookmarks to old WordPress URL&#x2019;s)</li> <li>Generates a new blog post <a href="http://nanoc.stoneship.org/docs/api/3.1/Nanoc3/Helpers/Blogging.html"><span class="caps">RSS</span> feed</a> </li> </ul> <p>In short, now nanoc is fully configured to my wishes, I can simply focus on writing <strong>blog content</strong>, without preparing image content (it is done automatically), and without having to choose between either a &#x201C;<span class="caps">WYSIWYG</span>&#x201D; editor or writing <span class="caps">HTML</span> manually. And I can do it in an offline fashion, too, which was one my main complaints about WordPress.</p> <p>So I&#x2019;m happy.</p> <p>Oh, and since I have been converting my blog anyway, I also created a new look and feel for it. I hope you like it. Feel free to comment.</p> <p>Finally, I&#8217;ve made the move to a static blog engine! I&#8217;m using <a href="http://nanoc.stoneship.org/">nanoc</a> now. nanoc is a very flexible and customizable static site generator, written by <a href="http://twitter.com/ddfreyne">Denis Defreyne</a>. As with all static site generators, nanoc lets you write your source files in a simple markup language. However, nanoc is much more flexible and customizable than most of the others out there. Let me show you a sneak peak of its internals.</p> tag:nvie.com,2010-03-04:/posts/an-upgrade-of-gitflow/ An upgrade of gitflow 2010-03-03T23:00:00Z 2010-03-03T23:00:00Z <p>Last week, I silently tagged <a href="http://github.com/nvie/gitflow/tree/0.2">gitflow 0.2</a>. The most important changes since 0.1 are:</p> <ul> <li>Order of arguments changed to have a more &#x201C;gitish&#x201D; subcommand structure. For example, you now say: <pre><code>git flow feature start myfeature</code></pre> </li> <li>Better initializer. <code>git flow init</code> now prompts interactively to set up a gitflow enabled repo.</li> <li>Added a command to list all feature/release/hotfix/support branches, e.g.: <pre><code>git flow feature list</code></pre> </li> <li>Made all merge/rebase operations failsafe, providing a non-destructive workflow in case of merge conflicts.</li> <li>Easy diff&#x2019;ing of all changes on a specific (or the current) feature branch: <pre><code>git flow feature diff [feature]</code></pre> </li> <li>Add support for feature branch rebasing: <pre><code>git flow feature rebase</code></pre> </li> <li>Some subactions now take name prefixes as their arguments, for convenience. For example, if you have feature branches called &#x201C;experimental&#x201D;, &#x201C;refactoring&#x201D; and &#x201C;feature-X&#x201D;, you could say: <pre><code>git flow feature finish ref</code></pre> And gitflow will know you mean the &#x201C;refactoring&#x201D; feature branch.<br> These actions are: <code>finish</code>, <code>diff</code> and <code>rebase</code>.</li> <li>Much better overall sanity checking.</li> <li>Better portability (<span class="caps">POSIX</span> compliant code)</li> <li>Better (more portable) flag parsing using Kate Ward&#x2019;s <a href="http://code.google.com/p/shflags/">shFlags</a>.</li> <li>Improved installer. To install <code>git flow</code> as a first-class Git subcommand, simply type: <pre><code>sudo make install</code></pre> </li> </ul> <ul> <li>Major and minor bug fixes.</li> </ul> <p>That&#x2019;s all for now.</p> <p>Last week, I silently tagged <a href="http://github.com/nvie/gitflow/tree/0.2">gitflow 0.2</a>. These are the most important changes since 0.1.</p> tag:nvie.com,2010-03-03:/posts/unexpected-side-effects-in-python-classes/ Unexpected side effects in Python classes 2010-03-02T23:00:00Z 2010-03-02T23:00:00Z <p>Today, I lost several hours while debugging a language implementation detail in Python that I did not know of and that really feels counterintuitive and dangerous to me.</p> <p>I was writing unit tests for a Python class that I was implementing, when one of the tests that had repeatedly been passing suddenly failed. Moreover, the failing test case was really for testing some completely unrelated piece of functionaly. This simply could not be broken!</p> <p>After at least an hour of scrutinizing the code, I was able to distill the real problem, which I think is summarized here in the most compact way:</p> <pre><code class="language-python"> class Foo: x = {} def __init__(self, id): self.x[id] = id f1 = Foo(5) print f1.x # {5:5}, as expected f2 = Foo(6) print f2.x # {5:5,6:6} ?! </code></pre> <p>Creating a simple <code>Foo</code> instance twice exposes the ugly side effect: the second <code>Foo</code> instance has an already initialized <code>x</code> instance variable when the constructor enters! Yuck! Moreover, now, too:</p> <pre><code class="language-python"> print f1.x # {5:5,6:6}, too! </code></pre> <p>Apparently, the <code>x</code> &#x201C;instance variable&#x201D; is a shared object, much like a global or class variable.</p> <p>To be even more confusing, this doesn&#x2019;t seem to hold for basic data types. For example, change the dictionary to an integer, and the example behaves as expected:</p> <pre><code class="language-python"> class Foo: x = 3 def __init__(self, id): self.x = id f1 = Foo(5) print f1.x # 5, as expected f2 = Foo(6) print f2.x # 6, as expected </code></pre> <h2>The behaviour demystified</h2> <p>The real confusion here is that I was thinking that I was creating &#x201C;instance variables&#x201D;, like you would in C++ or Java. As the <a href="http://docs.python.org/tutorial/classes.html#instance-objects">Python documentation</a> mentions:</p> <blockquote> <p>&#x201C;data attributes correspond to [&#x2026;] to data members in C++. Data attributes need not be declared; like local variables, they spring into existence when they are first assigned to.&#x201D;</p> </blockquote> <p>Yes, I knew that, but nonetheless my real-world class is much bigger than <code>Foo</code> and I wanted an explicit overview on which instance variables are in this class. Hence the data member.</p> <p>However, this is not how the Python interpreter processes Python code. In fact, upon class definition, the statement <code>x = {}</code> is executed within the scope of the newly defined class. To prove this:</p> <pre><code class="language-python"> class Bar: x = {} print Bar.x # {} </code></pre> <p>Even without a constructor or instance variable, we can access the data member <code>x</code>. Of course. Now this suddenly seems obvious.</p> <p>But what about our instance variables? Apparently, when we create a new instance of <code>Bar</code>, the instance data member <code>x</code> is initially <em>pointing to the same object</em> as the class data member <code>x</code>. The following example proves this:</p> <pre><code class="language-python"> class Foo: x = {} def __init__(self, id): self.x = { id: id } f1 = Foo(5) print f1.x # { 5:5 }, as expected f2 = Foo(6) print f2.x # { 6:6 }, as expected print Foo.x # {}, didn't intend this! </code></pre> <p>This example also demonstrates the subtlety of the accidentally discovered side-effect. Remember how we were changing the dictionary in our initial example? <code>self.x[id] = id</code><br> The instance data member was pointing to the same object as the class data member. By updating the dictionary, the single dictionary object was changed, causing unwanted side effects in other class instances.</p> <p>In the listing above, <code>x</code> is forced to point to a new dictionary by the assignment <code>self.x = { id:id }</code>. In other words, <code>x</code> points to a new object! This also perfectly explains why the integer example worked&#x2014;it&#x2019;s the same kind of assignment.</p> <h2>Conclusion</h2> <p>To summarize, I learned some important lessons today:</p> <ul> <li>All the time, I have been creating class data members in all my classes, without knowing this.</li> <li>I initialized those members to default values, effectively creating useless objects that are never accessed and just claiming memory.</li> <li>Although it can be explained, a seemingly innocent statement like <code>x = {}</code> can have very ugly side effects. Be warned!</li> <li>Never underestimate the power of unit tests. It is absolutely worth the investment.</li> </ul> <p>Today, I lost several hours while debugging a language implementation detail in Python that I did not know of and that really feels counterintuitive and dangerous to me.</p> tag:nvie.com,2010-01-26:/posts/gitflow-01-released/ gitflow 0.1 released 2010-01-25T23:00:00Z 2010-01-25T23:00:00Z <p>After the overwhelming attention and feedback on the <a href="http://nvie.com/archives/323">Git branching model post</a>, a general consensus was that this workflow would benefit from some form of proper scriptability. The workflow works seamlessly if you perform the steps involved manually, but hey&#x2026; manually is manually, really.</p> <blockquote> <p><ins><strong><span class="caps">UPDATE</span> 2/4/2010</strong>: Anyone reading this: I recommend <span class="caps">NOT</span> <span class="caps">USING</span> this very early release, but to jump on the <a href="http://github.com/nvie/gitflow/tree/develop">current develop tip</a>, which is much more mature. Release 0.2 is coming very soon.</ins></p> </blockquote> <p>An assisting tool (dubbed <code>gitflow</code>) was therefore created to provide simple, high-level commands to adopt the workflow into your own software development process. It&#x2019;s free and it&#x2019;s open source. Feel free to contribute to it if you like.</p> <blockquote> <p>Fork me on Github: <a href="http://github.com/nvie/gitflow">http://github.com/nvie/gitflow</a></p> </blockquote> <p>Since this morning, the first working <a href="http://github.com/nvie/gitflow/downloads">release 0.1</a> was tagged, albeit very basic.</p> <h3>A quick walkthrough</h3> <p>The <code>gitflow</code> script essentially features six subcommands: paired start/finish commands for managing the different types of branches from the originating article:</p> <ul> <li>Feature branches: <ul> <li> <code>gitflow start feature</code> <em><code>myfeature</code></em> </li> <li> <code>gitflow finish feature</code> <em><code>myfeature</code></em> </li> </ul> </li> </ul> <ul> <li>Release branches: <ul> <li> <code>gitflow start release</code> <em><code>version-id</code></em> </li> <li> <code>gitflow finish release</code> <em><code>version-id</code></em> </li> </ul> </li> </ul> <ul> <li>Hotfix branches: <ul> <li> <code>gitflow start hotfix</code> <em><code>version-id</code></em> </li> <li> <code>gitflow finish hotfix</code> <em><code>version-id</code></em> </li> </ul> </li> </ul> <p>Each of these scripts exactly reports what actions were taken and what follow-up actions are required by the user. This output will be polished in future versions to improve the <a href="http://en.wikipedia.org/wiki/User_experience_design">UX</a>. An example output:</p> <pre><code class="language-console"> $ gitflow finish feature foo Branches 'develop' and 'origin/develop' have diverged. And local branch 'develop' is ahead of 'origin/develop'. Switched to branch "develop" Your branch is ahead of 'origin/develop' by 12 commits. Merge made by recursive. README | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) Deleted branch foo (cd3effb). Summary of actions: - The feature branch 'foo' was merged into 'develop' - Feature branch 'foo' has been removed - You are now on branch 'develop' </code></pre> <h3>Limitations</h3> <p>The script is very limited at the moment yet, but future versions will fix that, too. Some of the main limitations:</p> <ul> <li>Branch names (<code>master</code>, <code>develop</code>) and the remote repo name (<code>origin</code>) are currently fixed.</li> <li>There is no support for dealing with merge conflicts yet.</li> <li>There is no support for <code>support-*</code> branches (see the <a href="http://nvie.com/archives/323#comment-185">original comment</a> that proposed this extension)</li> <li>There is no documentation.</li> <li>There is no installer.</li> </ul> <p>However, as this post is written, some of the limitations are already taken care of by community members. Power to the open source!</p> <p>After the overwhelming attention and feedback on the <a href="/archives/323">Git branching model post</a>, a general consensus was that this workflow would benefit from some form of proper scriptability. This post proposes the initial version of a tool I called <a href="http://github.com/nvie/gitflow">git-flow</a>.</p> tag:nvie.com,2010-01-13:/posts/building-git-from-scratch-on-snow-leopard/ Building Git from scratch on Snow Leopard 2010-01-12T23:00:00Z 2010-01-12T23:00:00Z <p>When you try to build Git <a href="http://github.com/git/git">from scratch</a> on a Snow Leopard machine, you may have ran into the following problem:</p> <pre><code class="language-console"> $ git clone git://github.com/git/git.git Initialized empty Git repository in /Users/nvie/git/.git/ remote: Counting objects: 111619, done. remote: Compressing objects: 100% (28007/28007), done. remote: Total 111619 (delta 82192), reused 111264 (delta 81852) Receiving objects: 100% (111619/111619), 27.60 MiB | 531 KiB/s, done. Resolving deltas: 100% (82192/82192), done. $ cd git $ make prefix=/usr/local/bin/git GIT_VERSION = 1.6.2.rc0.90.g0753 * new build flags or prefix CC fast-import.o CC abspath.o : : ld: warning: in /opt/local/lib/libexpat.dylib, file is not of required architecture ... ld: symbol(s) not found collect2: ld returned 1 exit status </code></pre> <p>Then, you have a pretty big change you are having an old Darwin ports (<a href="http://www.macports.org">macports</a>) collection in use which has not yet been upgraded to Snow Leopard&#x2019;s new x64 architecture.</p> <p>There is, however, a simple solution to this, namely to have the <code>git</code> build ignore the Darwin ports, simply by adding the following parameter to the build:</p> <pre><code class="language-console"> $ make NO_DARWIN_PORTS=1 prefix=/usr/local/bin/git </code></pre> <p>When you try to build Git <a href="http://github.com/git/git">from scratch</a> on a Snow Leopard machine, you may have ran into the following problem:</p> tag:nvie.com,2010-01-05:/posts/a-successful-git-branching-model/ A successful Git branching model 2010-01-04T23:00:00Z 2010-01-04T23:00:00Z <p>In this post I present the development model that I&#x2019;ve introduced for all of my projects (both at work and private) about a year ago, and which has turned out to be very successful. I&#x2019;ve been meaning to write about it for a while now, but I&#x2019;ve never really found the time to do so&#xA0;thoroughly, until now. I won&#x2019;t talk about any of the projects&#x2019; details, merely about the branching strategy and release management.</p> <p><img src="http://nvie.com/img/2009/12/Screen-shot-2009-12-24-at-11.32.03.png" class="center" alt=""></p> <p>It focuses around <a href="http://git-scm.com">Git</a> as the tool for the versioning of all of our source code.</p> <h2>Why git?</h2> <p>For a thorough discussion on the pros and cons of Git compared to centralized source code control systems, <a href="http://whygitisbetterthanx.com/">see</a> <a href="http://www.looble.com/git-vs-svn-which-is-better/">the</a> <a href="http://git.or.cz/gitwiki/GitSvnComparsion">web</a>. There are plenty of flame wars going on there. As a developer, I prefer Git above all other tools around today. Git really changed the way developers think of merging and branching. From the classic <span class="caps">CVS</span>/Subversion world I came from, merging/branching has always been considered a bit scary (&#x201C;beware of merge conflicts, they bite you!&#x201D;) and something you only do every once in a while.</p> <p>But with Git, these actions are extremely cheap and simple, and they are considered one of the core parts of your <em>daily</em> workflow, really. For example, in <span class="caps">CVS</span>/Subversion <a href="http://svnbook.red-bean.com">books</a>, branching and merging is first discussed in the later chapters (for advanced users), while in <a href="http://book.git-scm.com">every</a> <a href="http://pragprog.com/titles/tsgit/pragmatic-version-control-using-git">Git</a> <a href="http://github.com/progit/progit">book</a>, it&#x2019;s already covered in chapter 3 (basics).</p> <p>As a consequence of its simplicity and repetitive nature, branching and merging are no longer something to be afraid of. Version control tools are supposed to assist in branching/merging more than anything else.</p> <p>Enough about the tools, let&#x2019;s head onto the development model. The model that I&#x2019;m going to present here is essentially no more than a set of procedures that every team member has to follow in order to come to a managed software development process.</p> <h2>Decentralized but centralized</h2> <p>The repository setup that we use and that works well with this branching model, is that with a central &#x201C;truth&#x201D; repo. Note that this repo&#xA0;is only&#xA0;<em>considered</em> to be the central one (since Git is a <span class="caps">DVCS</span>, there is no such thing as a central repo at a technical level).&#xA0;We will refer to this repo as <code>origin</code>, since this name is familiar to all Git users.</p> <p><img src="http://nvie.com/img/2010/01/centr-decentr.png" class="center" alt=""></p> <p>Each developer pulls and pushes to origin. But besides the centralized push-pull relationships, each developer may also pull changes from other peers to form sub teams. For example, this might be useful to work together with two or more developers on a big new feature, before pushing the work in progress to <code>origin</code> prematurely. In the figure above, there are subteams of Alice and Bob, Alice and David, and Clair and David.</p> <p>Technically, this means nothing more than that Alice has defined a Git remote, named <code>bob</code>, pointing to Bob&#x2019;s repository, and vice versa.</p> <h2>The main branches</h2> <p><img src="http://nvie.com/img/2009/12/bm002.png" class="right" alt=""></p> <p>At the core, the development model is greatly inspired by existing models out there.&#xA0;The central repo holds two main branches with an infinite lifetime:</p> <ul> <li><code>master</code></li> <li><code>develop</code></li> </ul> <p>The <code>master</code> branch at <code>origin</code> should be familiar to every Git user.&#xA0;Parallel to the <code>master</code> branch, another branch exists called <code>develop</code>.</p> <p>We consider <code>origin/master</code> to be the main branch where the source code of <code>HEAD</code> always reflects a <em>production-ready</em> state.</p> <p>We consider <code>origin/develop</code> to be the main branch where the source code of <code>HEAD</code> always reflects a state with the latest delivered development changes for the next release. Some would call this the &#x201C;integration branch&#x201D;. This is where any automatic nightly builds are built from.</p> <p>When the source code in the <code>develop</code> branch reaches a stable point and is ready to be released, all of the changes should be merged back into <code>master</code> somehow and then tagged with a release number. How this is done in detail will be discussed further on.</p> <p>Therefore, each time when changes are merged back into <code>master</code>, this is a new production release <em>by definition</em>.&#xA0;We tend to be very strict at this, so that theoretically, we could use a Git hook script to automatically build and roll-out our software to our production servers everytime there was a commit on <code>master</code>.</p> <h2>Supporting branches</h2> <p>Next to the main branches <code>master</code> and <code>develop</code>, our development model uses a variety of supporting branches to aid parallel development between team members, ease tracking of features, prepare for production releases and to assist in quickly fixing live production problems. Unlike the main branches, these branches always have a limited life time, since they will be removed eventually.</p> <p>The different types of branches we may use are:</p> <ul> <li>Feature branches</li> <li>Release branches</li> <li>Hotfix branches</li> </ul> <p>Each of these branches have a specific purpose and are bound to strict rules as to which branches may be their originating branch and which branches must be their merge targets. We will walk through them in a minute.</p> <p>By no means are these branches &#x201C;special&#x201D; from a technical perspective. The branch types are categorized by how we <em>use</em> them. They are of course plain old Git branches.</p> <h3>Feature branches</h3> <p><img src="http://nvie.com/img/2009/12/fb.png" class="right" alt=""></p> <p>May branch off from:&#xA0;<code>develop</code><br> Must merge back into:&#xA0;<code>develop</code><br> Branch naming convention: anything except&#xA0;<code>master</code>, <code>develop</code>, <code>release-*</code>, or <code>hotfix-*</code></p> <p>Feature branches (or sometimes called topic branches) are used to develop new features for the upcoming or a distant future release. When starting development of a feature, the target release in which this feature will be incorporated may well be unknown at that point. The essence of a feature branch is that it exists as long as the feature is in development, but will eventually be merged back into <code>develop</code> (to definitely add the new feature to the upcoming release) or discarded (in case of a disappointing experiment).</p> <p>Feature branches typically exist in developer repos only, not in <code>origin</code>.</p> <h4>Creating a feature branch</h4> <p>When starting work on a new feature, branch off from the <code>develop</code> branch.</p> <pre><code class="language-console"> $ git checkout -b myfeature develop Switched to a new branch "myfeature" </code></pre> <h4>Incorporating a finished feature on develop</h4> <p>Finished features may be merged into the <code>develop</code> branch definitely add them to the upcoming release:</p> <pre><code class="language-console"> $ git checkout develop Switched to branch 'develop' $ git merge --no-ff myfeature Updating ea1b82a..05e9557 (Summary of changes) $ git branch -d myfeature Deleted branch myfeature (was 05e9557). $ git push origin develop </code></pre> <p>The <code>--no-ff</code> flag causes the merge to always create a new commit object, even if the merge could be performed with a fast-forward. This avoids losing information about the historical existence of a feature branch and groups together all commits that together added the feature. Compare:</p> <p><img src="http://nvie.com/img/2010/01/merge-without-ff.png" class="center" alt=""></p> <p>In the latter case, it is impossible to see from the Git history which of the commit objects together have implemented a feature&#x2014;you would have to manually read all the log messages. Reverting a whole feature (i.e. a group of commits), is a true headache in the latter situation, whereas it is easily done if the <code>--no-ff</code> flag was used.</p> <p>Yes, it will create a few more (empty) commit objects, but the gain is much bigger that that cost.</p> <p>Unfortunately, I have not found a way to make <code>--no-ff</code> the default behaviour of <code>git merge</code> yet, but it really should be.</p> <h3>Release branches</h3> <p>May branch off from:&#xA0;<code>develop</code><br> Must merge back into:&#xA0;<code>develop</code> and <code>master</code><br> Branch naming convention: <code>release-*</code></p> <p>Release branches support preparation of a new production release.&#xA0;They allow for last-minute dotting of i&#x2019;s and crossing t&#x2019;s. Furthermore, they allow for minor bug fixes and preparing meta-data for a release (version number, build dates, etc.). By doing all of this work on a release branch, the <code>develop</code> branch is cleared to receive features for the next big release.</p> <p>The key moment to branch off a new release branch from <code>develop</code> is when develop (almost) reflects the desired state of the new release.&#xA0;At least all features that are targeted for the release-to-be-built must be merged in to <code>develop</code> at this point in time. All features targeted at future releases may not&#x2014;they must wait until after the release branch is branched off.</p> <p>It is exactly at the start of a release branch that the upcoming release gets assigned a version number&#x2014;not any earlier. Up until that moment, the <code>develop</code> branch reflected changes for the &#x201C;next release&#x201D;, but it is unclear whether that &#x201C;next release&#x201D; will eventually become 0.3 or 1.0, until the release branch is started. That decision is made on the start of the release branch and is carried out by the project&#x2019;s rules on version number bumping.</p> <h4>Creating a release branch</h4> <p>Release branches are created from the <code>develop</code> branch. For example, say version 1.1.5 is the current production release and we have a big release coming up. The state of <code>develop</code> is ready for the &#x201C;next release&#x201D; and we have decided that this will become version 1.2 (rather than 1.1.6 or 2.0). So we branch off and give the release branch a name reflecting the new version number:</p> <pre><code class="language-console"> $ git checkout -b release-1.2 develop Switched to a new branch "release-1.2" $ ./bump-version.sh 1.2 Files modified successfully, version bumped to 1.2. $ git commit -a -m "Bumped version number to 1.2" [release-1.2 74d9424] Bumped version number to 1.2 1 files changed, 1 insertions(+), 1 deletions(-) </code></pre> <p>After creating a new branch and switching to it, we bump the version number. Here,&#xA0;<code>bump-version.sh</code> is a&#xA0;fictional&#xA0;shell script that changes some files in the working copy to reflect the new version. (This can of course be a manual change&#x2014;the point being that <em>some</em> files change.) Then, the bumped version number is committed.</p> <p>This new branch may exist there for a while, until the release may be rolled out definitely. During that time, bug fixes may be applied in this branch (rather than on the <code>develop</code> branch). Adding large new features here is strictly prohibited. They must be merged into <code>develop</code>, and therefore, wait for the next big release.</p> <h4>Finishing a release branch</h4> <p>When the state of the release branch is ready to become a real release, some actions need to be carried out. First, the release branch is merged into <code>master</code> (since every commit on <code>master</code> is a new release <em>by definition</em>, remember). Next, that commit on <code>master</code> must be tagged for easy future reference to this historical version. Finally, the changes made on the release branch need to be merged back into <code>develop</code>, so that future releases also contain these bug fixes.</p> <p>The first two steps in Git:</p> <pre><code class="language-console"> $ git checkout master Switched to branch 'master' $ git merge --no-ff release-1.2 Merge made by recursive. (Summary of changes) $ git tag -a 1.2 </code></pre> <p>The release is now done, and tagged for future reference.<br> <ins><strong>Edit:</strong> You might as well want to use the <code>-s</code> or <code>-u &lt;key&gt;</code> flags to sign your tag cryptographically.</ins></p> <p>To keep the changes made in the release branch, we need to merge those back into <code>develop</code>, though. In Git:</p> <pre><code class="language-console"> $ git checkout develop Switched to branch 'develop' $ git merge --no-ff release-1.2 Merge made by recursive. (Summary of changes) </code></pre> <p>This step may well lead to a merge conflict (probably even, since we have changed the version number). If so, fix it and commit.</p> <p>Now we are really done and the release branch may be removed, since we don&#x2019;t need it anymore:</p> <pre><code class="language-console"> $ git branch -d release-1.2 Deleted branch release-1.2 (was ff452fe). </code></pre> <h3>Hotfix branches</h3> <p><img src="http://nvie.com/img/2010/01/hotfix-branches1.png" class="right" alt=""></p> <p>May branch off from:&#xA0;<code>master</code><br> Must merge back into:&#xA0;<code>develop</code> and <code>master</code><br> Branch naming convention: <code>hotfix-*</code></p> <p>Hotfix branches are very much like release branches in that they are also meant to prepare for a new production release, albeit unplanned. They arise from the necessity to act immediately upon an undesired state of a live production version. When a critical bug in a production version must be resolved immediately, a hotfix branch may be branched off from the corresponding tag on the master branch that marks the production version.</p> <p>The essence is that work of team members (on the <code>develop</code> branch) can continue, while another person is preparing a quick production fix.</p> <h4>Creating the hotfix branch</h4> <p>Hotfix branches are created from the&#xA0;<code>master</code> branch. For example, say version 1.2 is the current production release running live and causing troubles due to a severe bug. But changes on <code>develop</code> are yet unstable.&#xA0;We may then branch off a hotfix branch and start fixing the problem:</p> <pre><code class="language-console"> $ git checkout -b hotfix-1.2.1 master Switched to a new branch "hotfix-1.2.1" $ ./bump-version.sh 1.2.1 Files modified successfully, version bumped to 1.2.1. $ git commit -a -m "Bumped version number to 1.2.1" [hotfix-1.2.1 41e61bb] Bumped version number to 1.2.1 1 files changed, 1 insertions(+), 1 deletions(-) </code></pre> <p>Don&#x2019;t forget to bump the version number after branching off!</p> <p>Then, fix the bug and commit the fix in one or more separate commits.</p> <pre><code class="language-console"> $ git commit -m "Fixed severe production problem" [hotfix-1.2.1 abbe5d6] Fixed severe production problem 5 files changed, 32 insertions(+), 17 deletions(-) </code></pre> <p><strong>Finishing a hotfix branch</strong></p> <p>When finished, the bugfix needs to be merged back into <code>master</code>, but also needs to be merged back into <code>develop</code>, in order to&#xA0;safeguard&#xA0;that the bugfix is included in the next release as well. This is completely similar to how release branches are finished.</p> <p>First, update <code>master</code> and tag the release.</p> <pre><code class="language-console"> $ git checkout master Switched to branch 'master' $ git merge --no-ff hotfix-1.2.1 Merge made by recursive. (Summary of changes) $ git tag -a 1.2.1 </code></pre> <p><ins><strong>Edit:</strong> You might as well want to use the <code>-s</code> or <code>-u &lt;key&gt;</code> flags to sign your tag cryptographically.</ins></p> <p>Next,&#xA0;include the bugfix in <code>develop</code>, too:</p> <pre><code class="language-console"> $ git checkout develop Switched to branch 'develop' $ git merge --no-ff hotfix-1.2.1 Merge made by recursive. (Summary of changes) </code></pre> <p>The one exception to the rule here is that,&#xA0;<strong>when a release branch currently exists, the hotfix changes need to be merged into that release branch, instead of <code>develop</code></strong>. Back-merging the bugfix into the release branch will eventually result in the bugfix being merged into <code>develop</code> too, when the release branch is finished. (If work in <code>develop</code> immediately requires this bugfix and cannot wait for the release branch to be finished, you may safely merge the bugfix into <code>develop</code> now already as well.)</p> <p>Finally, remove the temporary branch:</p> <pre><code class="language-console"> $ git branch -d hotfix-1.2.1 Deleted branch hotfix-1.2.1 (was abbe5d6). </code></pre> <h2>Summary</h2> <p>While there is nothing really shocking new to this branching model, the &#x201C;big picture&#x201D; figure that this post began with has turned out to be tremendously useful in our projects. It forms an elegant mental model that is easy to comprehend and allows team members to develop a shared understanding of the branching and releasing processes.</p> <p>A high-quality <span class="caps">PDF</span> version of the figure is provided here. Go ahead and hang it on the wall for quick reference at any time.</p> <p><ins><strong>Update:</strong> And for anyone who requested it: here&#x2019;s the <a href="http://github.com/downloads/nvie/gitflow/Git-branching-model-src.key.zip">gitflow-model.src.key</a> of the main diagram image (Apple Keynote).</ins></p> <p style="text-align:center;"><a href="http://github.com/downloads/nvie/gitflow/Git-branching-model.pdf"><img src="http://nvie.com/img/pdf.png" alt=""></a><br> <a href="http://github.com/downloads/nvie/gitflow/Git-branching-model.pdf">Git-branching-model.pdf</a></p> <p>Feel free to add your comments!</p> <p>In this post I present the development model that I&#8217;ve introduced for all of my projects (both at work and private) about a year ago, and which has turned out to be very successful. I&#8217;ve been meaning to write about it for a while now, but I&#8217;ve never really found the time to do so thoroughly, until now. I won&#8217;t talk about any of the projects&#8217; details, merely about the branching strategy and release management.</p> tag:nvie.com,2009-09-19:/posts/auto-generate-classes-for-your-core-data-data-model-revisited/ Auto-generate classes for your Core Data data model, revisited 2009-09-18T22:00:00Z 2009-09-18T22:00:00Z <p>A few months ago, I wrote about <a href="http://nvie.com/archives/263">automatically generating classes for your Core Data entities</a> and how to automate Xcode using users scripts, such that, when your model changed, you only needed to run your custom script again and your intermediate model files would reflect the new situation.</p> <p>Well, the guys from the <a href="http://github.com/rentzsch/mogenerator">mogenerator</a> project have come up with a far superior solution in the mean time. The newest version of mogenerator comes with an Xcode plugin named Xmo&#x2019;d, which monitors your <code>*.xcdatamodel</code> file for changes and, as soon as it changes, regenerates all of the neccessary files.</p> <p><strong>This means that there is officially no more reason not to use mogenerator.</strong></p> <p>To set it up, download the installer package from their (improved) <a href="http://rentzsch.github.com/mogenerator/">project website</a> and install it. (Before installing, please read the important release note about the renamed method <code>+newInManagedObjectContext:</code>.)</p> <p>When installed, all you need to do is Command-click your <code>*.xcdatamodel</code> file, click Get Info, switch to the Comments tab and add the string &#x201C;xmod&#x201D; to the comment field. This is the trigger for Xmo&#x2019;d to start (re)generating your machine-classes (the underscored class files) when the data model changes. Brilliant!</p> <p><img src="http://nvie.com/img/2009/10/comment-field.png" alt=""></p> <p>Oh, the default location at which the generated files will be emitted, is in a folder named after your project, right next to where your <code>*.xcdatamodel</code> already sits:</p> <p><img src="http://nvie.com/img/2009/10/emission-location.png" alt=""></p> <p>Enjoy it and spread the word!</p> <p>A few months ago, I wrote about <a href="/archives/263">automatically generating classes for your Core Data entities</a> and how to automate Xcode using users scripts, such that, when your model changed, you only needed to run your custom script again and your intermediate model files would reflect the new situation.</p> tag:nvie.com,2009-06-30:/posts/automatically-generate-classes-for-your-core-data-data-model/ Automatically generate classes for your Core Data data model 2009-06-29T22:00:00Z 2009-06-29T22:00:00Z <p>When designing a Core Data data model for your Xcode projects, you can choose to create Objective-C object wrappers for your entities, so that you can profit from type-safe code. The normal, tedious, workflow for this is that you select each entity from the model designer, select all of its attributes and relationships, Ctrl-click it and from the contextual menu first select &#x201C;Copy Obj-C 2.0 Method Declarations To Clipboard&#x201D;, paste it into the appropriate class header file, then do the same thing for the method implementations in the class implementation file. Waaaaaay too much work. Not to mention the manual copy-pastes are really hard to keep in sync once you start adding functionality to these class files, since you don&#x2019;t want to overwrite those additions, but you want to keep replacing everything else.</p> <h3>Meet mogenerator</h3> <p>Fortunately, there is a great way for automating this process, using mogenerator. The tool can be downloaded as a <a href="http://aralbalkan.com/2152"><span class="caps">DMG</span> installer</a> (Aral Balkan&#x2019;s blog mentions a workaround for older Xcode versions, but for Xcode 3.1.3 it worked out of the box for me), or you can checkout the sources from <a href="http://github.com/rentzsch/mogenerator/">github</a> and build it yourself.</p> <p>The mogenerator command line tool eases this generation process by reading the <code>*.xcdatamodel</code> file and generating both class files and intermediate class files for each entity. The intermediate classes (called <em>machine</em> classes) are continuously overwritten by subsequent regenerations, so you should never edit the contents of these files. The actual model object classes (called <em>human</em> classes) inherit from those intermediate classes with a default empty implementation, allowing for all manual extensions.</p> <p>For example, when you design a model with two entities Foo and Bar, mogenerator can be invokes as follows:</p> <pre><code>mogenerator -m MyDocument.xcdatamodel -M Entities -H Model</code></pre> <p>The flag <code>-m</code> sets the input model file, while <code>-M</code> and <code>-H</code> specify the output directories where the machine and human classes should be generated respectively.</p> <p>This does a few things:</p> <ul> <li>In the Entities subdirectory, there will be generated header and implementation files for NSManagedObject subclasses called _Foo and _Bar;</li> <li>In the Model subdirectory, there will be generated classes called Foo and Bar&#x2014;respective subclasses of _Foo and _Bar. These are only created if not available yet. Otherwise, they are left as is.</li> </ul> <h3>Wrapping it up</h3> <p>The trick of how mogenerator works is that you can run the script as often as you want. After every change in your model, you&#x2019;ll want to re-run the generation again to update the machine classes. You could easily leave Xcode, switch over to Terminal and issue the command above. But you&#x2019;ll get quite tired of that after a few times.</p> <p>Therefore, I&#x2019;ve written a custom user script that can be added to Xcode (see figure), which does the following:</p> <ul> <li>You can configure the output directories in the first lines of the script. There is no per-project configuration, so choose them as you would like to use them with all your projects;</li> <li>Mind that these generated files are not automatically included in your Xcode project. Drag them there once and ideally put the machine generated classes into a group under &#x201C;Other resource&#x201D;, so you never have to see them again. Whenever you add a new class to your model, new files will be generated, so again you must drag the new files to reference those, of course!</li> <li>The script can be run with any file in the project opened. It starts out with that file and walks up the directory tree to search for your Xcode project. If found, it executes all the rest from your project directory. (Suggestions are welcome, I could not find a better implementation since a variable like <code>%%%{PBXProjectPath}%%%</code> does not seem to exist.)</li> <li>It invokes mogenerator to generate all model classes for the project. It is smart enough to detect whether you are using Brian Webster&#x2019;s <a href="http://www.fatcatsoftware.com/blog/2008/per-object-ordered-relationships-using-core-data">BWOrderedManagedObject</a> in your project. If so, your generated machine classes will inherit from BWOrderedManagedObject instead of NSManagedObject.</li> </ul> <p><img src="http://nvie.com/img/2009/07/set-user-script.png" class="center" alt=""></p> <p>To add this script to Xcode, open the menu Scripts (the icon) &gt; Edit User Scripts&#x2026; Click the &#x201C;+&#x201D;-button on the bottom-left and select &#x201C;New shell script&#x201D;. Set the values for Input, Directory, Output and Errors as in the screenshot above, then copy-paste the script below into the code window. Add a nice keyboard shortcut to this action to top it off :-) I&#x2019;ve chosen ^&#x2325;&#x2318;G for this.</p> <p>Please feel free to leave any comments if this helped you.</p> <pre><code class="language-sh"> #!/bin/sh # # Automatic (re)generation of model classes for all *.xcdatamodel files. # Written by Vincent Driessen # # You are free to use this script in any way. # The original blog post is http://nvie.com/archives/263 # # Define output directories MACHINE_DIR="Entities" MODEL_DIR="Model" # Look for the Xcode project directory for this file cd `dirname "%%%{PBXFilePath}%%%"` while [ `ls -d *.xcodeproj 2&amp;gt;/dev/null | wc -l` -eq 0 ]; do cd .. if [ "`pwd`" = "/" ]; then echo "No Xcode project found." exit 1 fi done echo "Project directory is `pwd`" # # Check to see whether the base class is just a default (NSManagedObject) or # maybe Brian Webster's excellent BWOrderedManagedObject. # http://fatcatsoftware.com/blog/2008/per-object-ordered-relationships-using-core-data # # NOTE: # The check really is quite arbitrary: if there exists a file called # BWOrderedManagedObject.h somewhere below the project root directory, we # assume that we want to use this as the base class for all generated classes. # EXTRA_FLAGS= if [ `find . -name BWOrderedManagedObject.h | wc -l` -gt 0 ]; then EXTRA_FLAGS+="--base-class BWOrderedManagedObject" fi # Generate the model classes using mogenerator for model in `find . -name '*.xcdatamodel'`; do # The output directories have to exist, so create them mkdir -p "${MACHINE_DIR}" "${MODEL_DIR}" mogenerator ${EXTRA_FLAGS} -m "${model}" -M "${MACHINE_DIR}" -H "${MODEL_DIR}" done </code></pre> <p>When designing a Core Data data model for your Xcode projects, you can choose to create Objective-C object wrappers for your entities, so that you can profit from type-safe code. The normal, tedious, workflow for this is that you select each entity from the model designer, select all of its attributes and relationships, Ctrl-click it and from the contextual menu first select &#8220;Copy Obj-C 2.0 Method Declarations To Clipboard&#8221;, paste it into the appropriate class header file, then do the same thing for the method implementations in the class implementation file. Waaaaaay too much work. Not to mention the manual copy-pastes are really hard to keep in sync once you start adding functionality to these class files, since you don&#8217;t want to overwrite those additions, but you want to keep replacing everything else.</p> tag:nvie.com,2009-06-22:/posts/nsmanagedobjectcontext-extensions/ NSManagedObjectContext extensions 2009-06-21T22:00:00Z 2009-06-21T22:00:00Z <p>The Core Data framework rules, and its <span class="caps">API</span> is really really powerful. But really, why does the Core Data <span class="caps">API</span> require us to write so much boilerplate code? Simple things need to be simple.</p> <p>Why is the deletion of a managed object from the NSManagedObjectContext so easy:</p> <pre><code class="language-objc"> [context deleteObject:someObject]; </code></pre> <p>Compared to its creation:</p> <pre><code class="language-objc"> [NSEntityDescription insertNewObjectForEntityForName:@"someObjectClassName" inManagedObjectContext:context]; </code></pre> <h3>Extending NSManagedObjectContext</h3> <p>Add the following category on NSManagedObjectContext to all of your Core Data projects and your pains will be history.</p> <pre><code class="language-objc"> @implementation NSManagedObjectContext(NSManagedObjectContextConvenienceMethods) - (id)newObject:(Class)entity { return [NSEntityDescription insertNewObjectForEntityForName:[entity description] inManagedObjectContext:self]; } @end </code></pre> <p>Now, a call to create a new object is as easy as deleting it.</p> <pre><code class="language-objc"> [context newObject:[someEntity class]]; </code></pre> <h3>Further enhancements of NSManagedObject</h3> <p>Matt Gallagher has written an <a href="http://cocoawithlove.com/2008/03/core-data-one-line-fetch.html">excellent article</a> about how to further enhance NSManagedObject for adding simple, one-line fetch support. Be sure to check it out.</p> <p>The Core Data framework rules, and its <span class="caps">API</span> is really really powerful. But really, why does the Core Data <span class="caps">API</span> require us to write so much boilerplate code? Simple things need to be simple.</p> tag:nvie.com,2009-06-20:/posts/nspredicateeditor-tutorial/ NSPredicateEditor tutorial 2009-06-19T22:00:00Z 2009-06-19T22:00:00Z <p>Cocoa offers a nice visual editor for editing NSPredicate objects templates, called NSPredicateEditor. The NSPredicateEditor can be set up using code or in Interface Builder, which is preferable for simple use. The setup is fairly easy once you know how to do it. In this tutorial, we&#x2019;ll be building a simple predicate editor example which shows the basic functionality of the predicate editor.</p> <h3>Setting up the AppDelegate</h3> <p>Begin by creating a new Xcode project (Cmd+Shift+N). Name your project wisely and create a new class in the Classes group, called AppDelegate.</p> <p>Switch to the header file and declare two IBOutlets for the main window and the sheet on which we&#x2019;re going to display the editor in a few minutes. Also, add two IBActions called <code>-openEditor:</code> and <code>-closeEditor:</code>. Finally, add an ivar that holds the NSPredicate we&#x2019;re going to be editing.</p> <p><img src="http://nvie.com/img/2009/07/appdelegate1.png" alt=""></p> <p>Next, we&#x2019;re going to fire up Interface Builder to build the UI. Double click on the MainMenu.xib file under the Resources group.</p> <p>Drag an NSObject object from the Library into the <span class="caps">XIB</span> and call it App Delegate. Hit Cmd+6 and make it a subclass of the AppDelegate class we just created. Then, hook it up to the delegate property of the File&#x2019;s Owner.</p> <p class="autoalign"><img src="http://nvie.com/img/2009/07/hookup-appdelegate.png" alt=""> <img src="http://nvie.com/img/2009/07/choose-delegate.png" alt=""></p> <p class="clear">Drag a new NSWindow to the <span class="caps">XIB</span>-file and call it Sheet. Make sure the checkbox &#x201C;Visible At Launch&#x201D; is deselected or the sheet will not display properly at runtime. Open the main window and add a NSButton and a NSTextView to it. To the sheet window, drag a NSPredicateEditor and a NSButton. They should look somewhat like this now:</p> <p class="autoalign"><img src="http://nvie.com/img/2009/07/Picture-5.png" alt=""> <img src="http://nvie.com/img/2009/07/Picture-4.png" alt=""></p> <p>Now, we can hook up the outlets and actions as usual. Hook up the Edit Predicate button on the main window to <code>-openEditor:</code> and the OK button on the sheet window to closeEditor:. Then hook up the mainWindow and sheet outlets of the AppDelegate class to the respective NSWindow objects.</p> <p><img src="http://nvie.com/img/2009/07/hookup-windows.png" class="center" alt=""></p> <h3>Configure the NSPredicateEditor</h3> <p>Once we have all of the connections between Xcode and Interface Builder set up, we can continue to configure the predicate editor itself, which is actually what this tutorial is all about. An NSPredicateEditor control uses a list of NSPredicateEditorRowTemplate objects that can handle individual (simple) NSPredicate objects. Combining these row templates enables the NSPredicateEditor to edit compound predicates. There is no limitation to the depth of nested compound predicates, although nesting too deep would not be advisable from a usability perspective.</p> <p>In the edit window, click a few times until the &#x201C;name contains&#x201D; row template is selected. In this row template, you define which key paths are supported. Supported here means two things:</p> <ul> <li> <strong>matching</strong>&#x2014;given an existing predicate with this key path in it on the left-hand side, this row template can be used to alter the predicate;</li> <li> <strong>generation</strong>&#x2014;when using the editor to create new predicates, adding a new rule for this key path will generate a predicate for this key path.</li> </ul> <p class="autoalign"><img src="http://nvie.com/img/2009/07/Picture-10.png" alt=""> <img src="http://nvie.com/img/2009/07/Picture-13.png" alt=""></p> <h4>Gotcha</h4> <p>A small gotcha, at least one that initially put me on the wrong foot, is that there is quite a difference between the rows that you see design-time in Interface Builder and the rows that are available run-time. At design-time, you define the NSPredicateEditorRowTemplate objects while at run-time you see instances of them. Hence, the number of rows at design-time is the <em>number of different row templates available</em>. At run-time, however, the number of rows is the number of <em>(simple) predicates within the compound predicate</em> (which each has an associated row template instance that handles it). Subtle difference.</p> <p>In short, in Interface Builder, <strong>create a row template for <em>each type of match</em> that you want to allow</strong>. Typically, this means for each data type that you want to support. In our example, we have the following setup:</p> <ul> <li>Row template #1 is for all string matches. Here, we have defined it for the key paths &#x201C;firstname&#x201D;, &#x201C;lastname&#x201D;, &#x201C;address.street&#x201D; and &#x201C;address.city&#x201D;. They, per definition, have the same allowed operators. If we want to have an other set of operators for a specific key path, we need to define a separate row template for it.</li> <li>Row template #2 is for date matches, i.e. our &#x201C;birthdate&#x201D; key path.</li> <li>Row template #3 is for all integer matches, i.e. our &#x201C;address.number&#x201D; key path.</li> </ul> <p>The result looks like this:</p> <p><img src="http://nvie.com/img/2009/07/row-templates-setup.png" class="center" alt=""></p> <h3>Using bindings to connect the predicate to the UI</h3> <p><img src="http://nvie.com/img/2009/07/bindings.png" class="right" alt=""></p> <p>Next up, we simply connect both the text view from the main window and the predicate editor from the sheet window to the predicate key path using Cocoa bindings. In order to do so, select the NSPredicateEditor (first click the control to select the scroll view, then click again to select the inner NSPredicateEditor), hit Cmd+4. Then, unfold the &#x201C;Value&#x201D; binding and hook it up to the App Delegate&#x2019;s &#x201C;predicate&#x201D; key path.</p> <p>Do the same for the text view in the main window, but this time hook it up to the &#x201C;predicate.description&#x201D; key path (since only strings can be displayed in a text view). When you do this, make sure that the text view is read-only, since the description property of objects should never be set.</p> <h3>Writing the code to wrap it all up</h3> <p>Finally, we have only a bit of code to write in our AppDelegate implementation, so let&#x2019;s go:</p> <pre><code class="language-objc">// // AppDelegate.m // PredicateEditorTest // // Created by Vincent on 20-07-09. // #import "AppDelegate.h" #define DEFAULT_PREDICATE @"(firstname = 'John' AND lastname = 'Doe') " \ @"OR birthdate &amp;gt; CAST('01/01/1985', 'NSDate') " \ @"OR address.city = 'Chicago' " \ @"AND address.street != 'Main Street' " \ @"OR address.number &amp;gt; 1000" @implementation AppDelegate - (id)init { self = [super init]; if (self != nil) { predicate = [[NSPredicate predicateWithFormat:DEFAULT_PREDICATE] retain]; } return self; } - (void)dealloc { [predicate release]; [super dealloc]; } - (IBAction)openEditor:(id)sender { [NSApp beginSheet:sheet modalForWindow:mainWindow modalDelegate:nil didEndSelector:NULL contextInfo:nil]; } - (IBAction)closeEditor:(id)sender { [NSApp endSheet:sheet]; [sheet orderOut:sender]; } @end</code></pre> <p>In the <code>-init:</code> method, we initialize the AppDelegate by setting and retaining a reference to a rather complex default predicate. When the <span class="caps">XIB</span> is loaded at run-time, the textbox shows exactly this predicate and it can be edited by invoking the edit sheet.</p> <p>The actual implementation of the <code>-openEditor:</code> and <code>-closeEditor:</code> methods aren&#x2019;t too exciting.</p> <h3>Downloading the source</h3> <p>You can download the source code for this tutorial as an Xcode project here.</p> <p style="text-align:center;"><a href="http://nvie.com/files/PredicateEditorTest.zip"><img src="http://nvie.com/img/zip.png" alt=""></a><br> <a href="http://nvie.com/files/PredicateEditorTest.zip">PredicateEditorTest.zip</a></p> <p>Have a blast!</p> <p>Cocoa offers a nice visual editor for editing NSPredicate objects templates, called NSPredicateEditor. The NSPredicateEditor can be set up using code or in Interface Builder, which is preferable for simple use. The setup is fairly easy once you know how to do it. In this tutorial, we&#8217;ll be building a simple predicate editor example which shows the basic functionality of the predicate editor.</p>