<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[Frederic Hemberger]]></title>
  <link href="http://frederic-hemberger.de/atom.xml" rel="self"/>
  <link href="http://frederic-hemberger.de/"/>
  <updated>2012-02-21T13:04:07+01:00</updated>
  <id>http://frederic-hemberger.de/</id>
  <author>
    <name><![CDATA[Frederic Hemberger]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[SASS und Compass im Alltag]]></title>
    <link href="http://frederic-hemberger.de/artikel/sass-und-compass-im-alltag/"/>
    <updated>2012-02-21T19:22:00+01:00</updated>
    <id>http://frederic-hemberger.de/artikel/sass-und-compass-im-alltag</id>
    <content type="html"><![CDATA[<p>Es ist ja in letzter Zeit bereits einiges über CSS-Präprozessoren wie SASS und Compass geschrieben worden <sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup>, daher möchte ich statt der „großen Themen“ ein paar Dinge aufführen, die die alltägliche Arbeit mit Stylesheets erleichtern.</p>

<h2>Helfer im Alltag</h2>

<h3>Variablen/Berechnungen</h3>

<p>Ein interessanter Vorteil ist die Möglichkeit, Variablen zu definieren und damit sogar zu rechnen. Ein direkter Nutzen zeigt sich bei einem Beispiel, dass man so oder ähnlich öfters in CSS-Dateien finden kann:</p>

<p><figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='css'><span class='line'><span class="nc">.box</span> <span class="nt">h3</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">margin</span><span class="o">:</span> <span class="m">-18px</span> <span class="m">-15px</span> <span class="m">0</span><span class="p">;</span>
</span><span class='line'>  <span class="err">…</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure></p>

<p>Hmm. Woher kommen die Werte -18 und -15? Und warum wurden genau diese Werte gewählt? Schaut man sich das gesamte Beispiel an, wird es mit SASS auf den ersten Blick verständlicher:</p>

<p><figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='scss'><span class='line'><span class="na">$box-hpad</span><span class="o">:</span> <span class="mi">15</span><span class="kt">px</span><span class="p">;</span>
</span><span class='line'><span class="na">$box-vpad</span><span class="o">:</span> <span class="mi">18</span><span class="kt">px</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="nc">.box</span> <span class="p">{</span>
</span><span class='line'>  <span class="na">padding</span><span class="o">:</span> <span class="nv">$box-vpad</span> <span class="nv">$box-hpad</span><span class="p">;</span>
</span><span class='line'>  <span class="na">border</span><span class="o">:</span> <span class="mi">1</span><span class="kt">px</span> <span class="no">solid</span> <span class="mh">#ccc</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="nc">.box</span> <span class="nt">h3</span> <span class="p">{</span>
</span><span class='line'>  <span class="na">padding</span><span class="o">:</span> <span class="nv">$box-vpad</span> <span class="nv">$box-hpad</span><span class="p">;</span>
</span><span class='line'>  <span class="na">margin</span><span class="o">:</span> <span class="p">(</span><span class="o">-</span><span class="nv">$box-vpad</span><span class="p">)</span> <span class="p">(</span><span class="o">-</span><span class="nv">$box-hpad</span><span class="p">)</span> <span class="mi">0</span><span class="p">;</span>
</span><span class='line'>  <span class="na">background-color</span><span class="o">:</span> <span class="mh">#ccc</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure></p>

<p>Ändern sich hier im Layout die Abstände, muss dies nur noch an einer Stelle geschehen. Zugleich ist dokumentiert, was die einzelnen Pixelwerte bedeuten und man verhindert, einen Wert bei einer Änderung zu vergessen. Das hilft besonders, wenn mehrere Entwickler am Frontend arbeiten.</p>

<h3>Don‘t repeat yourself</h3>

<p>Viele Standard-Codesnippets, die man in fast jedem Projekt benötigt, sind in Compass bereits enthalten, das Zusammensuchen von Code entfällt also: Clearfix-Methode, diverse CSS-Reset-Einstellungen (basierend auf Eric Meyer‘s Reset 2.0), CSS3-Buttons, etc.</p>

<p>Wer genauer wissen will, was es mit den einzelnen Snippets auf sich hat, kann sich auf der Compass-Website jeden Sourcecode einzeln ansehen. Und das Beste: Sollte es für diese Mixins im Laufe der Zeit Updates geben (z.B. der Wegfall von Vendor-Prefixen), braucht man lediglich einmal Compass selbst zu aktualisieren und seine Stylesheets neu zu erzeugen.</p>

<p>Darüber hinaus gibt es auch weitere Mixins, z.B. zum automatischen Erstellen von CSS-Sprites, die einem die Arbeit erleichtern. Ebenso kann man eigene Module als Compass-Erweiterungen zusammenstellen.</p>

<h2>Deployment</h2>

<p>Einige nützliche Funktionen drehen sich um die Ausgabe der CSS-Dateien, die sich auch dann anbieten, selbst wenn man sonst kein einziges Feature von SASS nutzen würde:</p>

<h3>Strukturelle Validierung</h3>

<p>Beim Parsen der SASS-Datei wird der Code strukturell validiert. Sollten also eine Klammer oder ein Semikolon fehlen, wird eine Fehlermeldung im Browser angezeigt. Auf die verwendeten Eigenschaften hat es keine Auswirkungen, Vendor-Prefixes oder Browser-Hacks sind also weiterhin möglich.</p>

<h3>Codestrukturierung und Wiederverwendbarkeit</h3>

<p>Endlich ist <code>@import</code> nicht mehr „böse“. Bisher verhinderte diese Regel das parallele Herunterladen von CSS-Dateien und konnte so zu einer Verlangsamung des Seitenaufbaus führen. In SASS werden die importierten Dateien direkt in die Gesamtausgabe eingebettet. Man kann also seine Styles hervorragend modular aufbauen und für Wiederverwendbarkeit kapseln.</p>

<h3>Kommentare</h3>

<p>Kommentare, die mit <code>// …</code> statt dem üblichen <code>/* … */</code> eingesetzt werden, erscheinen nicht im ausgegebenen CSS. Man kann diese Möglichkeit also hervorragend nutzen, seinen Code zu kommentieren, ohne dass diese Anmerkungen nachher auf dem Produktivsystem zu sehen sind. Das ist besonders auch für Arbeiten im Team nützlich.</p>

<h3>Minifizierung des Codes</h3>

<p>Last but not least, kann mit einer Option die Ausgabe des Codes direkt minimiert erfolgen, also ideal für Produktivumgebungen.</p>

<p>Sicher kann man diese Möglichkeiten auch ohne den Einsatz eines Präprozessors nutzen, allerdings erfordert dies für gewöhnlich entweder einen eigenen Build-Prozess oder man ist auf die manuelle Nutzung von Online-Tools angewiesen. Als &#8220;Dreingabe&#8221; also auf jeden Fall schon interessant.</p>

<h2>Fazit</h2>

<p>Man sollte sich – wie bei allen neuen Techniken – anschauen, was SASS und Compass zu bieten hat und danach gezielt entscheiden, was für den eigenen Arbeitsworkflow sinnvoll ist.</p>

<p>Mit SASS kann man genauso übersichtliche oder unübersichtliche Stylesheets produzieren, wie man es auch mit CSS alleine machen kann, man muss also trotzdem die Regeln kennen. Dann können aber gerade die kleinen Handreichungen eine echte Erleichterung im alltäglichen Arbeiten sein.</p>

<br>


<div class="footnotes">
    <hr>
    <ol>
        <li id="fn:1">
            <ul>
                <li>Webkrauts: Effiziente CSS-Entwicklung mit Sass und Compass: <a href="http://www.webkrauts.de/2011/12/04/sass-compas/">Teil 1</a>, <a href="http://www.webkrauts.de/2011/12/05/sass-compass2/">Teil 2</a></li>
                <li>Maddesigns: <a href="http://maddesigns.de/compass-sass-1472.html">Compass & SASS – CSS3 Adventskalender Tag 17</a></li>
                <li><a href="http://atomeye.com/accolades/sass/">Sass & Compass: Why You Hatin’?</a></li>
                <li><a href="http://css-tricks.com/musings-on-preprocessing/">Musings on Preprocessing</a></li>
                <li>A List Apart: <a href="http://www.alistapart.com/articles/getting-started-with-sass/">Getting Started with Sass</a></li>
                <li><a href="http://grochtdreis.de/weblog/2012/02/14/compass-und-sass-haben-was/">Compass und Sass haben was</a>
            </ul>
            <a href="#fnref:1" rev="footnote">↩</a>
        </li>
    </ol>
</div>



]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Kurztipp: iCal – Animiertes Wecker-Icon entfernen]]></title>
    <link href="http://frederic-hemberger.de/artikel/ical-wecker-icon-entfernen/"/>
    <updated>2012-02-07T10:29:00+01:00</updated>
    <id>http://frederic-hemberger.de/artikel/ical-wecker-icon-entfernen</id>
    <content type="html"><![CDATA[<p><img class="border right" src="http://frederic-hemberger.de/static/assets/alarmclock.gif" title="nervendes iCal Wecker-Icon" >
Ich arbeite ja wirklich gerne mit iCal und nutze oft die Erinnerungsfunktion für Termine.
Aber dieses animierte Wecker-Icon in den Erinnerungs-Popups treibt mich auf Dauer in den Wahnsinn.
Zum Glück gibt es aber einen einfachen Weg, es los zu werden.<!--more--></p>

<pre><code>cd /Applications/iCal.app/Contents/Resources
sudo mv alarmclock.gif alarmclock.gif.original
touch alarmclock.gif
cd /System/Library/Frameworks/CalendarStore.framework/Versions/A/Resources/iCal\ Helper.app/Contents/Resources/
sudo mv alarmclock.gif alarmclock.gif.original
touch alarmclock.gif
</code></pre>

<p>Das Ganze funktioniert mit iCal ab Version 4 (Snow Leopard), bei älteren Versionen können die Pfade abweichen.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[beyond tellerrand 2011: Nachlese]]></title>
    <link href="http://frederic-hemberger.de/artikel/beyond-tellerrand-2011-nachlese/"/>
    <updated>2011-11-24T18:10:00+01:00</updated>
    <id>http://frederic-hemberger.de/artikel/beyond-tellerrand-2011-nachlese</id>
    <content type="html"><![CDATA[<p><img src="http://frederic-hemberger.de/static/assets/beyondtellerrand.png" title="beyond tellerrand" ></p>

<p>Die Woche startete großartig: In Düsseldorf fand die <a href="http://2011.beyondtellerrand.com">beyond tellerrand</a>-Konferenz in gemütlicher Atmosphäre des Capitol-Theaters statt, das der Veranstaltung direkt ein wenig Varieté-Atmosphäre verlieh.<!--more--> Und genau so, wie es der Rahmen versprach, waren die Themen der Vorträge auch interessant und abwechslungsreich gewählt.</p>

<h3>&#8220;More Honesty, Less Ninjas&#8221;</h3>

<p>Den Auftakt machte <a href="http://twitter.com/codepo8">Chris Heilmann</a>, der in gewohnt gut gelaunter Manier einen Rundumschlag interessanter Technologien zeigte, die in aktuelle Browser gerade Einzug halten. Gerade <a href="http://browserid.org">BrowserID</a> als Ersatz für heutige Login-Mechanismen erscheint äußerst vielversprechend: Damit dürfte das lästige Account-Anlegen oder Anmelden über Drittanbieter wie Twitter oder Facebook bald nicht mehr erforderlich sein, um sich eindeutig als Nutzer zu authentifizieren.</p>

<p>Der darauf folgende Vortrag von <a href="http://twitter.com/sniffles">Steph Troeth</a> mit dem Thema User Experience Design (UX) war etwas theoretischerer Natur und ob der Menge an Informationen leider ein wenig unter Zeitdruck, aber Sie machte deutlich, dass UX ein wichtiges Feld ist, mit dem sich Entwickler und Designer gleichermaßen mehr beschäftigen sollten. Danach gab <a href="http://twitter.com/aarongustafson">Aaron Gustafson</a> einen Überblick über Progressive Enhancement mit diversen Tipps und Techniken, wie man bestehende Funktionalitäten sinnvoll (und barrierearm) mir JavaScript und CSS erweitern kann.</p>

<p><img class="right border" src="http://farm8.staticflickr.com/7034/6396807437_ff204c4fb2_m.jpg" title="Naomi Atkinson von stn1978 bei Flickr" ></p>

<p><a href="http://twitter.com/naomisusi">Naomi Atkinson</a> sprach in ihrem Talk ein Thema an, dass gerade für deutsche Webworker interessant ist: Was können wir bei beruflicher Selbstdarstellung von den Stars lernen? Auch wenn sich das im ersten Moment seltsam anhören mag, scheinen es gerade deutsche (oder allgemein europäische) Webworker zu sein, die ihr Licht zu sehr unter den Scheffel stellen und die Bühne ihren amerikanischen oder britischen Kollegen überlassen. Man muss nicht bei Google, Mozilla oder einem fancy Sillicon Valley-Startup arbeiten, um interessante Dinge rund ums Web präsentieren zu können!</p>

<p>Danach ging es weiter mit der Frage, welche Möglichkeiten es gibt, mit Webapps auf Funktionen von mobilen Geräten wie Push Notifications, Kamera oder Sensoren zuzugreifen. <a href="http://twitter.com/hbehrens">Heiko Behrens</a> präsentierte Vor- und Nachteile unterschiedlicher Methoden und Frameworks.</p>

<p>Der Vortrag von Smashing Magazine-Gründer <a href="http://twitter.com/smashingmag">Vitaly Friedman</a> wurde von Vielen zwiespältig aufgenommen: Zwar waren einige Thesen um &#8220;The Invisible Side of Design&#8221; interessant, allerdings versuchte Vitaly, sie oftmals mit sehr visuell prägnanten Beispielen zu belegen, so dass die Argumentation teilweise eher verwirrend als erhellend war.</p>

<p>Wer bisher dachte, JavaScript in Webseiten wäre nur für Formularvalidierung gut, wurde nun anständig überrascht: <a href="http://twitter.com/seb_ly">Seb Lee-Delisle</a> zeigte in seinem Talk einige Tricks, die Teil seines Creative JS-Workshops vom Sonntag waren. In einer spontanen Live-Coding-Session zeigte er mit einfachen Canvas-Tricks wie Partikelsysteme, Feuerwerk oder wachsenden Bäumen, wie viel Spaß man mit JavaScript haben kann. Selbst die Designer unter den Anwesenden schauten neugierig, wie Codezeilen im Editor entstanden und danach vom Browser Leben eingehaucht bekamen. Coole und sehr unterhaltsame Präsentation.</p>

<p>Im Anschluss an die Talks gab es eine längere Pause, die wir für eine <a href="http://workingdraft.de/48/">Working Draft</a>-Sondersendung in recht großer Runde nutzten. Vielen Dank nochmals an Naomi, die die Herrenrunde durch ihre Anwesenheit bereichert hat und mit uns über ihren Vortrags diskutierte.</p>

<p>Um 20:00 zeigte <a href="http://twitter.com/baldcondensed">Yves Peters</a> in seinem Abendvortrag die Rolle der Schrift &#8220;Trajan&#8221; in Filmplakaten. Mit dem Slogan &#8220;make it Oscar&trade; material&#8221; entscheiden sich viele Filmstudios für diese Schrift, um Filme vermeidlich &#8220;edler&#8221; zu gestalten. Ein Trend der schlussendlich von den Academy Awards selbst für die Oscar&trade;-Veranstaltung übernommen wurde. Ebenso wurden &#8220;Gestaltungsregeln&#8221; und Trends für unterschiedliche Film-Genres deutlich, sobald man einige Filmplakate direkt miteinander vergleicht. Insgesamt ein sehr interessanter und unterhaltsamer Typographie-Vortrag, der den ersten Konferenztag offiziell beendete.</p>

<h2>Tag zwei: Content is King</h2>

<p><img class="right border" src="http://farm8.staticflickr.com/7147/6397306093_81320b583f_m.jpg" title="Stephanie Hay von stn1978 bei Flickr" ></p>

<p>Nach der Party den ersten Vortrag am nächsten Tag zu haben ist sicherlich der undankbarste Zeit-Slot. Das Thema &#8220;Datenvisualisierung&#8221; klingt auf den ersten Blick auch nicht grade spannend, aber weit gefehlt. <a href="http://twitter.com/destraynor">Des Traynor</a> gab einen interessanten thematischen Überblick: Wie lügt man mit Grafiken? Welche Darstellungen eigenen sich für welche Daten? Wie muss ich Daten für bestimmte Zielgruppen aufbereiten, damit sie tatsächlich auch nützlich sind?</p>

<p>Wenn Design und Entwicklung abgeschlossen ist und &#8220;Lorem Ipsum&#8221; ausgedient hat, beschäftigen sich viele erst mit dem ungeliebten Thema Content. <a href="http://twitter.com/steph_hay">Steph Hay</a> zeigte, wie wichtig jedoch gut geschriebene Inhalte sind und gab Tipps, wie man griffigen Content schreibt und überflüssiges Blabla vermeidet. Eine gute Ergänzung auch zu Naomis Vortrag vom Vortag.</p>

<h3>Webentwicklung als Handwerkskunst</h3>

<p><a href="http://twitter.com/colly">Simon Collison</a> hat für seinen Vortrag ein wenig in der Familiengeschichte geforscht: Er entstammt einer Familie, die über viele Generationen Backsteine in England gefertigt hat. Aber was hat dieser Hintergrund mit der Tätigkeit als Webentwickler zu tun? Es geht um &#8220;Software Craftmanship&#8221; - es geht darum, dass der Beruf des Webworkers in vielen Belangen auch eine Handwerkskunst ist. Damit ist auch verbunden, Stolz auf seinen Beruf und die eigenen Leistungen zu sein, den Anspruch zu haben, stets sein Bestes zu geben. Ein sehr inspirierender und wichtiger Vortrag.</p>

<p>Den anschließenden Talk von <a href="http://twitter.com/tcaspers">Tomas Caspers</a> habe ich leider völlig verpasst, habe nur im Nachhinein von schönen Tierbildern auf den Slides gehört.</p>

<p><a href="http://twitter.com/danrubin">Dan Rubin</a> zeigte in seinem Vortrag, wie man Usability Testing auch in engem Zeitrahmen und mit einfachsten Mitteln durchführen kann: Auch Seiten, die für Webworker absolut gruselig daherkommen, können für den normalen Nutzer durchaus funktionieren. Viele Leute werden ein optische Veränderung nicht bemerken, aber eine Verbesserung in der Funktionalität um so mehr. Daher muss es nicht unbedingt ein kompletter grafischer Relaunch sein, um die Benutzbarkeit für den Anwender zu verbessern.</p>

<p><img class="left border" src="http://farm8.staticflickr.com/7029/6395311701_e6018920d4_m.jpg" title="Jake Archibald von stn1978 bei Flickr" >
Falls es mit dem Programmieren irgendwann nicht mehr so läuft, sollte <a href="http://twitter.com/jaffathecake">Jake Archibald</a> dringend über eine Karriere als Standup-Comedian nachdenken:</p>

<p>Neben praxisnahen Beispielen, wie man in JavaScript wiederverwertbaren Code schreibt und APIs für eigene Plug-ins übersichtlich entwirft, berichtete er auch von einem aufwühlenden Ereignis seiner Jugend, wie er (durch einen Dokumentationsfehler in der Fernsehzeitung) unerwarteterweise &#8220;Berühmte Phalli der Geschichte&#8221; mit seiner Mutter schauen musste. Wenn das kein Anstoß ist, stets auf gründliche Dokumentation wert zu legen!</p>

<p>Den Abschluss des zweiten Tages bildete wieder ein Typographie-Vortrag. <a href="http://twitter.com/jontangerine">Jon Tan</a> spannte den Bogen von Grundlagen der Web-Typographie wie allgemeine Lesbarkeit bis hin zu den Möglichkeiten, die sich mit Schrifteinbettung über @font-face ergeben. Auch hier waren wieder viele praktische Tipps dabei, wie man mit einfachen typografischen Mitteln Websites deutlich aufwerten kann.</p>

<h2>Fazit</h2>

<p>Die zwei Tage waren eine gute thematische Mischung, so dass für jeden etwas dabei war. Viel wichtiger noch: Die Vorträge boten alle eine Menge Inspiration. Schon während man noch zuhörte und über das Gesagte nachdachte, wollte man direkt Hand an eigene Projekte legen. Und ich finde, dass dieses Gefühl mehr als alles andere für eine ausgezeichnete Konferenz spricht. Daher vielen Dank an Mark Thiele für die hervorragende Organisation, bis zum nächsten Mal!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Kurztipp: Einfaches Update aller installierten Homebrew-Packages]]></title>
    <link href="http://frederic-hemberger.de/artikel/homebrew-update-aller-installierten-packages/"/>
    <updated>2011-11-07T14:36:00+01:00</updated>
    <id>http://frederic-hemberger.de/artikel/homebrew-update-aller-installierten-packages</id>
    <content type="html"><![CDATA[<p>Für alle, die unter Mac OS X mit dem Paketmanager <a href="http://mxcl.github.com/homebrew">Homebrew</a> arbeiten, gibt es eine einfache Möglichkeit, mit einer einzigen Zeile sowohl Homebrew selbst, als auch alle installierten Packages auf einen Schlag zu aktualisieren<!--more-->:</p>

<pre><code>brew update &amp;&amp; brew upgrade `brew outdated`
</code></pre>

<p>Dabei kümmert sich <code>brew update</code> zuerst um die Aktualisierung von Homebrew und der Paketliste selbst, <code>brew outdated</code> listet alle lokal installierten Pakete, für die eine Aktualisierung vorliegt, die dann schließlich mit <code>brew upgrade</code> installiert werden. Voilá!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Octopress]]></title>
    <link href="http://frederic-hemberger.de/artikel/octopress/"/>
    <updated>2011-10-24T13:24:00+02:00</updated>
    <id>http://frederic-hemberger.de/artikel/octopress</id>
    <content type="html"><![CDATA[<p><img class="right" src="http://frederic-hemberger.de/static/assets/octopress-logo.png" title="Octopress" >
Nachdem ich in den letzten Wochen <a href="https://twitter.com/MadeMyDay">von</a> <a href="https://twitter.com/derSchepp">einigen</a> <a href="https://twitter.com/kahlillechelt">Personen</a> <a href="https://twitter.com/bueltge">genötigt</a> wurde, meine Tipps und Ideen zur Web-Entwicklung festzuhalten, habe ich mich ein wenig umgeschaut und bin schließlich bei <a href="http://octopress.org">Octopress</a> gelandet.<!--more--></p>

<p>Octopress basiert auf dem statischen Seitengenerator Jekyll, der unter anderem auch alle GitHub-Pages antreibt, bietet darüber hinaus viele weitere Features:</p>

<ul>
<li>Bequemes Schreiben mit dem Fokus auf Inhalten</li>
<li>Lesefreundlicher Standard-Theme mit Unterstützung von mobilen Geräten</li>
<li>Syntax-Highlighting für Code in <a href="http://ethanschoonover.com/solarized">Solarized</a>-Optik, diverse Einbettungsmöglichkeiten auch über Gist und jsFiddle</li>
<li>Unterstützung für Twitter, Facebook, Google +1, Google Analytics</li>
<li>Kommentare über Disqus</li>
<li>Einfacher Template-Aufbau</li>
<li>Vielfältige Deployment-Möglichkeiten</li>
</ul>


<p>Es ist wirklich so angenehm, sich beim Schreiben von Texten ganz auf den Inhalt konzentrieren zu können: Alle Texte werden einfach in <a href="http://daringfireball.net/projects/markdown/syntax">Markdown</a> geschrieben (mittlerweile eines meiner Lieblingsformate), das geht mit jedem beliebigen Text-Editor und passt sich so an persönliche Vorlieben und Workflows problemlos an. Damit sind die Texte auch jederzeit einfach portierbar, einen <a href="https://github.com/thomasf/exitwp">Konverter um Wordpress-Inhalte nach Markdown zu konvertieren</a> gibt es ebenfalls.</p>

<p>Octopress kommt dabei von Haus aus mit einem ansehnlichen, lesefreundlichen Standard-Theme, so dass man direkt loslegen kann, ohne sich vorher um viel kümmern zu müssen: In einer Konfigurationsdatei trägt man die wichtigsten Grundeinstellungen (Seiten-Name, URL-Struktur, etc.) ein und aktiviert nach Wunsch die mitgelieferten Widgets (u.a. GitHub, Twitter oder Google Analytics), dann kann es losgehen. Ein weiterer Vorteil ist die bequeme Art, Codebeispiele einbetten zu können: Entweder per reinem Markdown, in GitHub-typischer &#8220;Three Backtick&#8221;-Weise, als Link direkt aus einer Datei, per Gist oder jsFiddle, dazu alles direkt mit gut durchdachtem Syntax-Highlighting.</p>

<p>Die mitgelieferte Disqus-Integration lädt die Kommentare zu einem Beitrag über Ajax nach. Das mag nicht ganz ideal sein, da Artikel und Kommentare von einander getrennt sind, liegt aber durch die statisch generierten Seiten in der Natur der Sache. Disqus bietet dafür aber gute Moderations- und Spamfilter-Möglichkeiten, ebenso kann sich ein Nutzer direkt über Twitter, Facebook, o.ä. einloggen. Sollte man irgendwann in Betracht ziehen, die Kommentare anderswo verwalten zu wollen, ist ein kompletter Datenexport jederzeit möglich. In Octopress lassen sich auch andere Kommentarsysteme integrieren.</p>

<p>Da Octopress weder auf eine Datenbank oder eine bestimmte Serverumgebung angewiesen ist, fällt auch das Deployment sehr flexibel aus: Die statischen Seiten können auf beliebigen Hostingplattformen abgelegt werden. Das geht entweder direkt per RSync, alternativ stehen auch GitHub-Pages oder Heroku als Hosting-Plattform zur Auswahl (für die kommende Version sind sogar Amazon S3 und CloudFront in Planung). Wer seine Seiten vor der Publizierung nochmal prüfen möchte, kann dazu die Vorschau auf dem integrierten Webserver nutzen.</p>

<p>Neben der freien Plattform-Wahl können statische Seiten deutlich schneller ausgeliefert werden: Auch wenn es für datenbankgestütztze Systeme wie Wordpress diverse Caching-Plugins gibt, kommen Sie von der Performance her nicht an statische HTML-Seiten heran. Die Seiten sind weder anfällig für SQL-Injections, noch müssen Updates oder Sicherheits-Patches eingespielt werden.</p>

<h2>Fazit</h2>

<p>Octopress ist ein System um einfach und schnell Inhalte zu publizieren, gerade für Leute, die ohnehin lieber in Texteditor und Konsole arbeiten und nicht auf WYSIWYG-HTML-Editoren angewiesen sind. Ruby-Sprachkenntnisse sind für den täglichen Gebrauch nicht erforderlich: Die Templates sind in sehr übersichtlichem <a href="https://github.com/Shopify/liquid/wiki/Liquid-for-Designers">Liquid-Syntax</a> gehalten, aber wer mag kann mit wenigen Zeilen Code eigene Plugins erstellen oder vorhandene erweitern.</p>

<p>Eine ausführliche Dokumentation findet sich auf <a href="http://www.octopress.org">octopress.org</a>, probiert es einfach mal aus …</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Ruby: Umstellung von RVM auf rbenv/ruby-build]]></title>
    <link href="http://frederic-hemberger.de/artikel/ruby-umstellung-von-rvm-auf-rbenv-und-ruby-build/"/>
    <updated>2011-10-16T10:11:00+02:00</updated>
    <id>http://frederic-hemberger.de/artikel/ruby-umstellung-von-rvm-auf-rbenv-und-ruby-build</id>
    <content type="html"><![CDATA[<p>Sam Stephenson von 37signals hat eine schlanke Alternative zum Ruby Version Manager (RVM) geschaffen, die weniger in das System eingreift. Zeit für einen Wechsel.<!--more--></p>

<p>Bisher hatte ich zum Verwalten von Ruby-Versionen <a href="http://beginrescueend.com/">RVM</a> genutzt, um die Version 1.9.2 parallel zur mit OS X gelieferten System-Version 1.8.7 zu betreiben. Das funktioniert soweit auch ganz prächtig, wenn man (wie ich) aber keine weiteren Features von RVM benutzt, gibt es auch eine einfachere Alternative.</p>

<p><a href="https://github.com/sstephenson/rbenv">rbenv</a> konzentriert sich auf das Wesentliche, das Festlegen der verwendeten Ruby-Version, entweder auf globaler oder projektbezogener Ebene. Selbst das Downloaden und Installieren von unterschiedlichen Ruby-Versionen ist in das Schwesterprojekt <a href="https://github.com/sstephenson/ruby-build">ruby-build</a> ausgelagert. Damit folgt es dem UNIX-Gedanken, dass ein Programm lediglich eine einzige Aufgabe erfüllen sollte - und das zuverlässig. Die Verwaltung von Gemsets bietet rbenv nicht, dafür empfiehlt sich stattdessen <a href="http://gembundler.com/">Bundler</a>, das ohnehin mittlerweile in vielen Projekten Verwendung findet.</p>

<h2>Schritt 1: Ruby Version Manager (RVM) deinstallieren</h2>

<p>Wie tief sich RVM im System verankert stellt man fest, wenn man es versucht zu deinstallieren. Eigentlich sollten diese beiden Zeilen genügen:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'><span class="nv">$ </span>rvm implode
</span><span class='line'><span class="nv">$ </span>gem uninstall rvm
</span></code></pre></td></tr></table></div></figure>


<p>Dazu kommen - je nach System - allerdings noch Einträge in <code>~/.bashrc</code>, <code>~/.profile</code>, <code>~/.bash_profile</code> oder <code>/etc/profile</code> und die Ordner <code>/etc/rvmrc</code>, <code>/etc/profile.d/rvm</code> und <code>~/.rvmrc</code>.</p>

<p>Ebenso sollte man einen Blick in <code>/usr/local/bin</code> werfen: Hier können sich noch Symlinks und RVM-Ersatzscripte für erb, gem, irb, rake, rdoc, ri, ruby und testrb befinden. Ich hoffe, dass ich bei dieser Auflistung nichts vergessen habe, es empfiehlt sich auf jeden Fall, die entsprechenden Ordner und Dateien genau zu durchleuchten.</p>

<h2>Schritt 2: rbenv/ruby-build installieren</h2>

<p>Wenn man unter OS X den Paketmanager &#8220;homebrew&#8221; installiert hat, geht die Installation erfreulich einfach:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'><span class="nv">$ </span>brew update
</span><span class='line'><span class="nv">$ </span>brew install rbenv
</span><span class='line'><span class="nv">$ </span>brew install ruby-build
</span></code></pre></td></tr></table></div></figure>


<p>Danach fügt man noch in seinem Shell-Profil die Zeile <code>eval "$(rbenv init -)"</code> hinzu und startet anschließend den Shell-Prozess neu. Die <a href="https://github.com/sstephenson/rbenv#section_2">Installation ohne Paketmanager</a> ist ähnlich schnell erledigt.</p>

<h2>Schritt 3: Ruby installieren</h2>

<p>Die Installation einer neuen Ruby-Version ist dann in wenigen Schritten abgeschlossen:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'><span class="c"># Installiert die gewünschte Ruby-Version</span>
</span><span class='line'><span class="c"># (eine Übersicht der verfügbaren Versionen erhält man mit `rbenv install`)</span>
</span><span class='line'><span class="nv">$ </span>rbenv install 1.9.2-p290
</span><span class='line'>
</span><span class='line'><span class="c"># Wichtig: Muss nach jeder Installation von Ruby oder Gems mit</span>
</span><span class='line'><span class="c"># ausführbaren Dateien einmal aufgerufen werden.</span>
</span><span class='line'><span class="nv">$ </span>rbenv rehash
</span><span class='line'>
</span><span class='line'><span class="c"># Setzt die global verwendete Ruby-Version</span>
</span><span class='line'><span class="nv">$ </span>rbenv global 1.9.2-p290
</span></code></pre></td></tr></table></div></figure>


<p>&#8230; fertig und ready to rumble.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Terminal: Mehr Übersicht in versionierten Projekten]]></title>
    <link href="http://frederic-hemberger.de/artikel/terminal-mehr-uebersicht-bei-versionierten-projekten/"/>
    <updated>2011-09-20T18:20:00+02:00</updated>
    <id>http://frederic-hemberger.de/artikel/terminal-mehr-uebersicht-bei-versionierten-projekten</id>
    <content type="html"><![CDATA[<p>Wenn man im Terminal viel mit versionierten Projekten arbeitet, kann man schnell die Übersicht verlieren ob man sich gerade in einem Repository befindet und in welchem. Mit ein paar paar Zeilen in seinem Shell-Profil kann man sich bequem diese Information anzeigen lassen.<!-- more --></p>

<p>Üblicherweise befinden sich die Einstellungen zum Prompt in einer Datei namens .profile oder .bash_profile im Home-Ordner des eigenen Benutzers. Dort sucht man nach einer Zeile, die mit <code>PS1=</code> beginnt. Im folgenden Beispiel ist der Prompt so aufgebaut, dass er den aktuellen Benutzer, den Host- und aktuellen Verzeichnisnamen ausgibt, gefolgt von einem Dollar-Zeichen als Abschluss.</p>

<p>Das Ganze sieht dann in den Profileinstellungen so aus:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'><span class="nv">PS1</span><span class="o">=</span><span class="s1">&#39;[\u@\h] \w\$ &#39;</span>
</span></code></pre></td></tr></table></div></figure>


<p>Um nun Informationen über Git- und SVN-Repositories im Prompt anzeigen zu können, müssen wir die Einstellungen folgendermaßen erweitern:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>vcs_info<span class="o">()</span> <span class="o">{</span>
</span><span class='line'>    <span class="k">if</span> <span class="o">[</span> -d .svn <span class="o">]</span>; <span class="k">then</span>
</span><span class='line'><span class="k">        </span><span class="nb">echo</span> -e <span class="s2">&quot; [svn]&quot;</span>
</span><span class='line'>    <span class="k">else</span>
</span><span class='line'><span class="k">        </span><span class="nv">branch</span><span class="o">=</span><span class="sb">`</span>git branch 2&gt; /dev/null | sed -e <span class="s1">&#39;/^[^*]/d&#39;</span> -e <span class="s1">&#39;s/* \(.*\)/\1/&#39;</span><span class="sb">`</span>
</span><span class='line'>        <span class="k">if</span> <span class="o">[</span> <span class="nv">$branch</span> <span class="o">]</span>; <span class="k">then</span>
</span><span class='line'>            <span class="c"># If branch is not master, add branch name</span>
</span><span class='line'>            <span class="nv">branch</span><span class="o">=</span><span class="sb">`</span><span class="nb">echo</span> <span class="nv">$branch</span> | sed -e <span class="s1">&#39;s/master//&#39;</span><span class="sb">`</span>
</span><span class='line'>            <span class="k">if</span> <span class="o">[</span> <span class="nv">$branch</span> <span class="o">]</span>; <span class="k">then </span><span class="nv">branch</span><span class="o">=</span><span class="s2">&quot;:$branch&quot;</span>; <span class="k">fi</span>
</span><span class='line'><span class="k">            </span><span class="nb">echo</span> -e <span class="s2">&quot; [git$branch]&quot;</span>
</span><span class='line'>        <span class="k">fi</span>
</span><span class='line'><span class="k">    fi</span>
</span><span class='line'><span class="o">}</span>
</span><span class='line'>
</span><span class='line'><span class="nv">PS1</span><span class="o">=</span><span class="s1">&#39;[\u@\h] \w$(vcs_info)\$ &#39;</span>
</span></code></pre></td></tr></table></div></figure>


<p>Die Funktion prüft zunächst, ob es im aktuellen Verzeichnis einen versteckten Ordner <code>.svn</code> gibt. Das bedeutet, dass der Ordner zu einem Subversion-Repository gehört. Als Ausgabe erscheint dann im Prompt:</p>

<pre><code>[user@host] ~/Workspace/my_svn_project [<span style="color:#d33682;">svn</span>]$</code></pre>


<p>Für Git ist es ein kleines bisschen aufwändiger: Per <code>git branch</code> wird ermittelt, ob wir uns überhaupt in einem Git-Repository bewegen. Falls das der Fall sein sollte und wir im master-Branch arbeiten, geben wir die Information verkürzt aus:</p>

<pre><code>[user@host] ~/Workspace/my_git_project [<span style="color:#d33682;">git</span>]$</code></pre>


<p>Ist hingegen ein anderer Branch aktiv, wird dieser zusätzlich aufgeführt:</p>

<pre><code>[user@host] ~/Workspace/my_git_project [<span style="color:#d33682;">git</span>:<span style="color:#d33682;text-decoration:underline">my_git_branch</span>]$</code></pre>


<p>Der Übersicht halber, habe ich im obigen Code-Beispiel auf die Escape-Sequenzen zur Kolorierung verzichtet. Die vollständige Version findet sich zusammen mit anderen gesammelten Tricks in meinem <a href="https://github.com/fhemberger/dotfiles">dotfiles-Repository auf GitHub</a>.</p>

<p><strong>UPDATE:</strong> <a href="https://twitter.com/tfnico/status/116395429209440256">Thomas</a> hat mich freundlicherweise noch auf <a href="https://raw.github.com/git/git/master/contrib/completion/git-completion.bash">git-completion</a> hingewiesen, dass zudem noch Tab-Vervollständigung der Branch-Namen bietet.</p>

<p>Falls man – wie ich – das Kommando <code>git</code> durch einen Alias <code>g</code> ersetzt hat, muss man zusätzlich am Ende des Scriptes die folgende Zeile einfügen, damit die Vervollständigung auch mit dem Alias funktioniert:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'><span class="nb">complete</span> -o bashdefault -o default -o nospace -F _git g 2&gt;/dev/null <span class="se">\</span>
</span><span class='line'>    <span class="o">||</span> <span class="nb">complete</span> -o default -o nospace -F _git g
</span></code></pre></td></tr></table></div></figure>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Übersicht HTML5-Präsentationsframeworks]]></title>
    <link href="http://frederic-hemberger.de/artikel/uebersicht-html5-praesentationsframeworks/"/>
    <updated>2011-08-24T09:17:00+02:00</updated>
    <id>http://frederic-hemberger.de/artikel/uebersicht-html5-praesentationsframeworks</id>
    <content type="html"><![CDATA[<p>Neben PowerPoint und Keynote gibt es immer mehr Präsentationswerkzeuge, die auf HTML und CSS setzen und so außerordentlich flexibel in der Gestaltung sind. Ein Grund – grade für Web-Worker – sich einen kurzen Überblick zu verschaffen<!-- more -->:</p>

<h2>deck.js</h2>

<p>Das Framework <a href="http://imakewebthings.github.com/deck.js/">deck.js</a> von Caleb Troughton ist quasi &#8220;the new kid in town&#8221;. Was mir auf den ersten Blick gut gefällt ist der modulare Aufbau: Themes, Transitions und Erweiterungen wie eine Slideübersicht, sichtbare Slidenummern, etc. können alle nach eigenem Belieben zusammengestöpselt werden.</p>

<p>Das birgt natürlich auch die Gefahr, dass man sich statt am den Inhalt einer Präsentation zu sehr auf das Feintuning von Plug-Ins und Effekten konzentriert. Es ist auf jeden Fall ein interessantes Framework, die Modularität erlaubt das Abstimmen auf die eigenen Bedürfnisse, wenn man sich ein wenig Zeit nimmt, in die Details einzusteigen.</p>

<h2>impress.js</h2>

<p>In eine ähnliche Kerbe schlägt <a href="http://bartaz.github.com/impress.js">impress.js</a> das optisch wirklich äußerst beeindruckend ist. Es orientiert sich im Wesentlichen an dem Präsentationsservice <a href="http://prezi.com">prezi.com</a>, bedient sich dabei aber ausschließlich CSS3 Transformationen und Transitions von modernen Browsern. So lassen sich auf einer beliebig großen Präsentationsoberfläche Position, Rotation und Größe der einzelnen Objekte festlegen.</p>

<p>Momentan muss man die Werte leider für jedes Slide von Hand angeben, was die ganze Sache noch ein wenig mühselig macht. Aber da das Framework noch sehr jung ist, wird sich da sicherlich noch was tun.</p>

<h2>CSSS</h2>

<p>Das <a href="https://github.com/LeaVerou/CSSS">CSS-based SlideShow System</a> von Lea Verou setzt – wie der Name schon sagt – den Schwerpunkt bei der Umsetzung auf CSS, lediglich die Komponenten, die sich darüber nicht abbilden lassen, werden durch JavaScript unterstützt. Die Struktur der Folien bleibt dadurch schlank und das <a href="http://leaverou.me/csss/sample-slideshow.html">Ergebnis</a> kann sich sehen lassen.</p>

<h2>Pik6</h2>

<p>Eigentlich nur als selbstgebautes Hilfsmittel für seine HTML5-Erklärbär World Domination Tour gedacht, verfolgt <a href="http://peterkroener.de">Peter Kröner</a> mit <a href="https://github.com/SirPepe/Pik6">Pik6</a> einen sehr interessanten Ansatz: Durch die Verwendung von WebWorkern können mehrere Browserfenster mit der Präsentation synchron laufen. Das ermöglicht z.B. die Darstellung auf einem Projektor, während in einem anderen Fenster der Präsentationsmodus läuft, der auch separate Notizen für den Vortragenden ermöglicht. Ebenso können sich mehrere Clients die Präsentation gleichzeitig ansehen, etwa zusätzlich zur Projektion auf dem eigenen Laptop.</p>

<p>Praktisch für Entwickler: Automatisches Syntax-Highlighting von Quellcode ist schon direkt mit an Board.</p>

<h2>Reveal.js (aka CSS 3D Slideshow)</h2>

<p>Wem Präsentationen in 2D zu langweilig sind, der sollte zu <a href="http://lab.hakim.se/reveal-js">Reveal.js</a> von Hakim el Hattab greifen. Basierend auf seinem CSS-Experiment <a href="http://hakim.se/experiments/css/slideshow/">CSS 3D Slideshow</a>, kann man schnell gut aussehende Präsentationen erstellen, benötigt aber auch hier zur Darstellung einen aktuellen Browser, der CSS 3D Transitions und Transformationen unterstützt. Die anderen <a href="http://hakim.se/experiments">Experimente</a> auf seiner Seite können sich ebenfalls sehen lassen.</p>

<h2>HTML5 Slides</h2>

<p>Google stellt mit seinen <a href="http://code.google.com/p/html5slides/">HTML5 Slides</a> ebenfalls ein weitverbreitetes HTML-Präsentationsframework. Der Code ist dank HTML5 schön übersichtlich strukturiert, <code>&lt;article&gt;</code> Tags bilden die einzelnen Slides, die gängigen Präsentationselemente (einzeln eingeblendete Listenpunkte, Bilder in unterschiedlichen Größen, Codebeispiele mit Syntax-Highlighting, etc.) sind über Slide-Klassen bereits definiert.</p>

<p>Layouts für 4:3-Darstellung und Widescreen lassen sich über die jeweilige Klasse für die ganze Präsentation setzen … hier fehlt mir persönlich noch ein Automatismus, damit sich die Slides besser auf die Fullscreen-Darstellung anpassen.</p>

<h2>Weitere Frameworks</h2>

<ul>
<li><a href="http://meyerweb.com/eric/tools/s5/">S5</a> – Eines der ersten Frameworks für HTML-Präsentation von CSS Godfather Eric Meyer</li>
<li><a href="https://github.com/briancavalier/slides">slides</a> – Eine schlichte und elegante Lösung von Brian Cavalier</li>
<li><a href="https://github.com/pepelsbey/shower">Shower</a> von Vadim Makeev (Opera) bietet unter anderem eine schöne Slide-Übersicht</li>
</ul>


<h2>Fazit</h2>

<p>Für welches Framework man sich letzten Endes entscheidet bleibt eine Frage des Geschmacks. Es wird auf jeden Fall deutlich, dass aktuelle Web-Techniken in vielen Bereichen ein hervorragender Ersatz für klassische Präsentationssoftware sein können.</p>

<hr />

<p><em>Update (5.01.2012)</em>: impress.js als neues Framework hinzugefügt.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Einführung in Node.js]]></title>
    <link href="http://frederic-hemberger.de/artikel/einfuehrung-in-node-js/"/>
    <updated>2011-08-16T21:26:00+02:00</updated>
    <id>http://frederic-hemberger.de/artikel/einfuehrung-in-node-js</id>
    <content type="html"><![CDATA[<p>Node.js wird gerne als &#8220;serverseitiges JavaScript&#8221; bezeichnet, allerdings ist das technisch nicht so ganz korrekt: Node.js ist eine eventbasierte JavaScript-Laufzeitumgebung auf Basis von Googles V8-Engine (die auch die JavaScript-Basis für Google Chrome bildet). Was bedeutet das genau?<!-- more --></p>

<p>Normalerweise wird in den meisten Programmiersprachen Programmcode sequenziell abgearbeitet, das heißt eine neue Anweisung im Code wird erst dann begonnen, wenn die vorausgegangene Anweisung vollständig abgearbeitet ist. Wenn hingegen Vorgänge nebenläufig durchgeführt werden sollen, greifen Programmiersprachen wie z.B. Java auf sogenannte Threads zurück: Die nebenläufige Aufgabe wird angestoßen und durch einen separaten Prozess ausgeführt, während der vorhergehende Code weiterläuft. Das Problem dabei: Jeder zusätzliche Thread verbraucht sowohl CPU-Zeit als auch Speicherplatz im RAM, was bei vielen gleichzeitigen Threads zu Performance- und Skalierungsproblemen führen kann.</p>

<p>Node.js hingegen arbeitet mit einem einzigen Thread und verarbeitet den Code eventbasiert. Was das bedeutet, kennt man teilweise schon aus dem normalen clientseitigen JavaScript, wenn es z.B. um DOM-Events geht. Hier ein Beispiel in jQuery:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">$</span><span class="p">(</span><span class="s1">&#39;button&#39;</span><span class="p">).</span><span class="nx">click</span><span class="p">(</span><span class="kd">function</span><span class="p">(){</span>
</span><span class='line'>    <span class="nx">alert</span><span class="p">(</span><span class="s1">&#39;Hallo Welt!&#39;</span><span class="p">);</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>


<p>Die Aktion wird im Vorfeld definiert, was daraufhin aber geschehen soll kommt erst dann zum Tragen, wenn das Ereignis tatsächlich ausgelöst wird.</p>

<h2>Was hat diese Arbeitsweise für Vorteile in Node.js?</h2>

<p>Wie bereits zu Anfang erwähnt, wird in vielen Sprachen die weitere Ausführung von Code geblockt, bis eine Anweisung verarbeitet wurde. Dies betrifft nicht nur einfache Operationen, sondern auch z.B. Zugriffe auf das Dateisystem, Datenbankanfragen, Web-Services, etc. All diese Operationen blockieren die weitere Verarbeitung.</p>

<p>Auf den ersten Blick scheint das nicht weiter problematisch zu sein. Wenn man sich das aber mal in Rechenzyklen vorstellt, bekommt dieses Vorgehen schon ganz andere Dimensionen. Ich glaube, Ryan Dahl (der Entwickler von Node.js) hat dafür einmal folgendes Beispiel genutzt:</p>

<p>Liquid error: undefined method `map&#8217; for #&lt;String:0x00000101e7fc00></p>

<p>In all dieser Zeit bleibt die eigentliche Arbeit liegen, da immer noch auf die Information aus Tokio gewartet wird. Da man grade unterwegs ist, die Daten zu beschaffen, kann man auch in der Zwischenzeit keine anderen Arbeiten erledigen (z.B. Anrufe im Büro annehmen).</p>

<p>Aus diesem Grund sind solche Operationen in Node.js grundsätzlich &#8220;nicht blockierend&#8221; und werden wie z.B. aus dem DOM bekannt eventbasiert ausgeführt. Das gilt für Zugriffe auf das Dateisystem, Datenbanken, Netzwerk-Verbindungen, etc. Und das ist eigentlich auch der Part, an den man sich als Node.js-Einsteiger ein wenig gewöhnen muss.</p>

<p>Solche Anweisungen wie</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="kd">var</span> <span class="nx">myfile</span> <span class="o">=</span> <span class="nx">fs</span><span class="p">.</span><span class="nx">readFile</span><span class="p">(</span><span class="s1">&#39;myfile.txt&#39;</span><span class="p">,</span> <span class="s1">&#39;utf8&#39;</span><span class="p">);</span>
</span><span class='line'><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">myfile</span><span class="p">);</span>
</span><span class='line'><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">&#39;Fertig!&#39;</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>wird man so in der Regel in Node.js nicht finden, stattdessen werden Callback-Funktionen verwendet:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">fs</span><span class="p">.</span><span class="nx">readFile</span><span class="p">(</span><span class="s1">&#39;myfile.txt&#39;</span><span class="p">,</span> <span class="s1">&#39;utf8&#39;</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">err</span><span class="p">,</span> <span class="nx">data</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="nx">err</span><span class="p">)</span> <span class="k">throw</span> <span class="nx">err</span><span class="p">;</span>
</span><span class='line'>    <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">data</span><span class="p">);</span>
</span><span class='line'><span class="p">});</span>
</span><span class='line'><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">&#39;Fertig!&#39;</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>Das bedeutet also in diesem Fall auch, dass wir auf der Konsole zuerst &#8220;Fertig!&#8221; sehen und dann erst den Inhalt der Datei. Dessen muss man sich bei der Entwicklung bewusst sein. Das wird vor allem dann schnell ein wenig wuselig, wenn man beispielsweise Kombination hat wie:
Warte auf eine Datei, die per Webformular hochgeladen wird, lese diese Datei dann ein und schreibe deren Inhalt in eine Datenbank. Hier muss man also darauf achten, wann welche Daten tatsächlich zu Verfügung stehen, bevor man sie weiterverarbeiten kann.</p>

<h2>Und wofür kann ich Node.js verwenden?</h2>

<p>Für die Auslieferung einfacher statischer Inhalte tut es nach wie vor ein gewöhnlicher Webserver, dafür wäre Node.js kein Gewinn, ebenso wie bei rechenlastigen Apps. Wo es allerdings seine Stärken ausspielen kann, sind die Bereiche, in denen seine eventbasierte Art zum Tragen kommt. Also bei Datenverarbeitung wie beispielsweise bei (JSON) APIs oder Streaming. So können z.B. mit Node.js Videofilme schon beim Hochladen auf einen Server in ein anderes Format transkodiert werden oder Clients über WebSockets (bzw. sockets.io) mit aktuellen Daten versorgt werden.</p>

<p>Aber auch für Kommandozeilenprogramme und Shellscripte lässt sich Node.js verwenden, etwa für Buildtools oder zur Datenverarbeitung.</p>

<p>Node.js selbst ist vom Umfang her sehr rudimentär, bringt aber alle grundlegenden Bausteine mit, aus denen man eine ganze Menge ausbauen kann, etwa: Events, Buffer, Streams, TLS/SSL, Dateisystem-Zugriff, DNS, UDP und HTTP. Es ist auch bewusst das Ziel der Entwickler, den eigentlichen Kern schlank zu halten und sich auf das Wesentliche zu konzentrieren.</p>

<p>Man kann also mit wenigen Zeilen Code von Hand seinen eigenen Webserver schreiben (quasi das &#8220;Hello World&#8221; in fast allen Node.js-Tutorials), für weiterführende Aufgaben ist das natürlich wenig praktikabel. Es gibt natürlich schon eine ganze Menge Bibliotheken, die einem die Arbeit vereinfachen, so z.B. für Datenbank-Anbindungen, API-Handler, Parser, Template-Engines und vieles vieles mehr, wie etwa das Web-Framework &#8220;Express&#8221;.</p>

<h2>Kann man Node.js schon produktiv einsetzen?</h2>

<p>Diese Frage wird recht häufig gestellt, da der stabile Zweig von Node.js grade erst bei Version 0.4 ist. Eine pauschale Antwort darauf zu geben ist nicht leicht. Node.js hat erst vor etwa einem Jahr richtig an Fahrt aufgenommen, hat aber eine sehr aktives Entwicklerumfeld, der IRC-Channel ist immer gut gefüllt und die Leute insgesamt sind sehr hilfsbereit.</p>

<p>Auch wenn es noch vergleichsweise wenige Unternehmen gibt, die Node.js als Haupt- oder Exklusiv-Technologie verwenden, gibt es doch viele, die zumindest Teile ihres Business mit Node.js betreiben: So etwa Anbieter von Webservices und APIs, GitHub zum dynamischen Erstellen aller Downloads, LinkedIn hat grade den Server-Part ihrer mobilen App von Rails auf Node.js umgestellt, mit Yammer gibt es sogar ein komplettes Enterprise Social Network und Zynga verwendet es für ihre HTML5-basierten Spiele.</p>

<p>Es kommt also insgesamt auf den Kontext an. Was man aber eindeutig festhalten kann: Node.js gewinnt zunehmend an Bedeutung und erfährt eine breitere Adaption im produktiven Umfeld.</p>

<p>Am besten bekommt man aber ein Gefühl für Node.js, wenn man es direkt selber mal ausprobiert:</p>

<h2>Installation</h2>

<p>Linux-Nutzer können Node.js problemlos direkt kompilieren.</p>

<p>Wer Node.js auf Mac OS X installieren will, sollte vorher XCode installiert haben (oder das eigenständige GCC-Paket für OS X), da Node.js kompiliert werden muss. Das geht am einfachsten, wenn man es über einen Paketmanager wie &#8220;homebrew&#8221; macht.</p>

<p>Unter Windows ist das ganze momentan noch etwas umständlicher: Zwar gibt es einen nativen Build von Node.js für Windows, es handelt sich aber noch um eine recht junge Entwicklungsversion, in der noch nicht alles rund läuft. Bis Ende des Jahres wollen die Entwickler aber eine stabile Version anbieten.</p>

<p>Alternativ lässt sich Node.js aber auch via Cygwin installieren, entweder von Hand oder als aktuelles <a href="http://node-js.prcn.co.cc/">Binary-Paket</a>.</p>

<p>Als nächstes noch den Paketmanager npm installieren, über den man Zugriff auf die vielen bestehenden Tools und Bibliotheken erhält.</p>

<p>Dann kann es jetzt ja losgehen …</p>

<h2>Links:</h2>

<ul>
<li><a href="http://nodejs.org">Node.js</a></li>
<li><a href="http://npmjs.org">NPM</a></li>
<li><a href="http://nodeguide.com/index.html">Felix&#8217;s Node.js Guide</a></li>
<li><a href="http://www.nodebeginner.org/">Node Beginners Book</a></li>
<li><a href="http://visionmedia.github.com/masteringnode/">Mastering Node.js (Free E-Book)</a></li>
<li><a href="http://expressjs.com">Express</a></li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Einführung in Ruby/Rails]]></title>
    <link href="http://frederic-hemberger.de/artikel/einfuehrung-in-ruby-rails/"/>
    <updated>2011-08-14T16:02:00+02:00</updated>
    <id>http://frederic-hemberger.de/artikel/einfuehrung-in-ruby-rails</id>
    <content type="html"><![CDATA[<h2>Was ist Ruby?</h2>

<p>Ruby ist eine dynamische, stark typisierte Sprache, die Mitte der 90er von Yukihiro &#8220;Matz&#8221; Matsumoto geschaffen wurde. Der große Unterschied z.B. zu PHP ist dabei, dass diese Sprache komplett objektorientiert aufgebaut ist, was eines der herausragenden Merkmale von Ruby ist.<!-- more --></p>

<p>Die aktuelle Version von Ruby ist 1.9.2 … dabei müsste sich die Versionsnummer eigentlich genauer genommen auf den Ruby-Interpreter beziehen. Denn hier sind wir schon bei einer Besonderheit. Neben dem &#8220;offiziellen&#8221; Ruby-Interpreter (auch MRI, &#8220;Matz&#8217; Ruby Interpreter&#8221; genannt), gibt es noch weitere kompatible Interpreter, die teilweise für spezielle Einsatzzwecke angepasst sind, z.B. Rubinius, JRuby, Ruby Enterprise Edition, IronRuby oder MacRuby.</p>

<p>Auch wenn ich mir die Interpreter noch nicht genauer angesehen habe, sind doch zwei davon recht interessant: Zum einen ist das JRuby, das eine 100%ige Java-Implementierung von Ruby darstellt. Man kann damit also beide Welten miteinander verbinden und auf existierenden Code von beiden Seiten aus zugreifen. Sicherlich auch im Enterprise-Kontext nicht uninteressant. Der zweite interessante Interpreter ist MacRuby, das sich auch mit XCode zusammen verwenden lässt, um native Mac-Programme ohne Objective-C zu schreiben. Für iOS ist das leider nicht geeignet aufgrund des dort fehlenden Garbage Collectors. Mit Ruboto hingegen ist ein Ruby für Android bereits in der Entwicklung.</p>

<p>Aber für diese Betrachtung bleibe ich weiterhin beim &#8220;normalen&#8221; MRI Ruby 1.9.2.</p>

<h2>Installation</h2>

<p>Wer sich Ruby einfach mal ein wenig ansehen möchte oder auch professionell damit entwickeln möchte, sollte sich entweder den <a href="https://rvm.beginrescueend.com/">Ruby Version Manager</a> (RVM) oder <a href="https://github.com/sstephenson/rbenv">rbenv</a> von 37signals verwenden. Das sorgt für eine saubere Trennung der Ruby-Umgebungen, so dass man getrost mehrere Interpreter parallel installieren kann, ohne irgendwann in heilloses Chaos zu versinken. Darüber hinaus wird bei OS X die mitgelieferte System-Ruby-Version von der eigenen Entwicklungsumgebung getrennt (man kann also nicht aus Versehen seine System-Rubyversion beschädigen).</p>

<p>Die Installation ist bei beiden Tools mit wenigen Handgriffen abgeschlossen und gut dokumentiert. Ich persönlich bevorzuge rbenv, man kann aber auch nachträglich <a href="http://frederic-hemberger.de/artikel/2011/10/16/ruby-umstellung-von-rvm-auf-rbenv-und-ruby-build/">von RVM auf rbenv umsteigen</a>.</p>

<h3>Ruby unter Windows</h3>

<p>Wer Ruby unter Windows installieren möchte, findet ein komplettes Paket auf <a href="http://rubyinstaller.org">rubyinstaller.org</a>. Es empfiehlt sich für einige Erweiterungen direkt das angebotene Development-Pack mit zu installieren. Danach müssen nur noch zwei Umgebungsvariablen für UTF-8 als Standardzeichensatz gesetzt werden (statt en_US kann man natürlich auch de_DE verwenden):</p>

<pre><code>set LC_ALL=en_US.UTF-8
set LANG=en_US.UTF-8
</code></pre>

<h2>Erste Schritte in Ruby</h2>

<p>Eine gute Einführung in Ruby findet sich unter <a href="http://tryruby.org">Try Ruby</a> – hier wird man in kleinen interaktiven Einheiten in die Grundlagen der Sprache eingeführt, so dass man mit ersten Programmen schon direkt anfangen kann. Ich kann die Website nur wärmstens empfehlen: Schon nach etwa 20-30 Minuten hat man die wichtigsten Konzepte der Sprache kennengelernt. Ebenfalls praktischerweise in Ruby enthalten ist &#8220;irb&#8221;, die interaktive Ruby Konsole. Hier kann man direkt die ersten Schritte wagen und Ruby ausprobieren.</p>

<p>Wenn der Standard-Umfang der Sprache nicht mehr ausreichen sollte, kann man zusätzlich auf Pakete zugreifen, von denen es im Netz mehr als 27.000 Stück für so ziemlich alle Lebenslagen gibt. Mit</p>

<pre><code>gem install &lt;paketname&gt;
</code></pre>

<p>installiert man ein solches &#8220;Gem&#8221;, um bereits vorhandene Pakete auf den neusten Stand zu bringen reicht ein &#8220;gem update&#8221;. Ein Verzeichnis der Gems findet man unter anderem auf <a href="http://rubygems.org/">rubygems.org</a> oder GitHub.
Übrigens: Man kann auch problemlos Ruby verwenden, um damit eigene Shell-Scripte für *nix und Mac zu schreiben und hat dabei ebenfalls Zugriff auf den vollen Sprachumfang.</p>

<h2>Rails</h2>

<p>Rails ist das am weitesten verbreitete MVC Framework für Ruby und ist ideal für Web-Applikationen und schnelles Prototyping. Alle typischen CRUD-Datenoperationen (Create, Read, Update, Delete) können dabei einfach über die URL aufgerufen werden, z.B.:</p>

<pre><code>/users           Listet alle Datensätze des Typs "user" auf
/user/1          Zeigt den User-Datensatz mit der ID 1
/users/new       Zeigt eine Eingabemaske um einen neuen Benutzer anzulegen
/users/1/edit    Zeigt eine Eingabemaske um den Benutzer mit der ID 1 zu editieren
</code></pre>

<p>Rails Motto ist &#8220;convention over configuration&#8221;, so dass vieles schon bereits &#8220;out of the box&#8221; funktioniert, wenn man sich an die Rails-Konventionen hält, natürlich kann man auch Dinge anpassen, muss diese aber dann von Hand konfigurieren. So lässt sich natürlich im obigen Fall z.B. der Zugriff beschränken (z.B. für angemeldete Benutzer oder Administratoren) oder die Namen der Routen ändern.</p>

<h2>Rails: Scaffolding</h2>

<p>Neue Datenmodelle legt man in der Regel über ein sogenanntes Scaffolding an, dass bereits alle notwendigen Dateien (Model, View, Controller und Unit-Tests) anlegt und auch im Datenbank-Script die entsprechenden Einträge hinterlegt (welches sogar versioniert aufgebaut ist, so dass Änderungen in der Entwicklungs-Umgebung auch versionsweise auf dem Produktiv-System automatisch nachgezogen werden können).</p>

<p>Ein Scaffolding-Aufruf für ein einfaches Benutzer-Modell sieht so aus:</p>

<pre><code>rails generate scaffold User name:string email:string password:string
</code></pre>

<h2>Rails: Models</h2>

<p>Nur um kurz zu zeigen, weshalb Rails einem die Entwicklung an vielen Stellen so vereinfacht, möchte ich noch ein Beispiel für den Umgang mit der Datenmodellierung geben.</p>

<p>Selbst ohne weitere Kommentare kann man sehr gut verstehen, wie das Modell aufgebaut ist:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">class</span> <span class="nc">User</span> <span class="o">&lt;</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Base</span>
</span><span class='line'>  <span class="n">validates</span> <span class="ss">:name</span><span class="p">,</span> <span class="ss">:presence</span> <span class="o">=&gt;</span> <span class="kp">true</span>
</span><span class='line'>  <span class="n">validates</span> <span class="ss">:email</span><span class="p">,</span> <span class="ss">:presence</span> <span class="o">=&gt;</span> <span class="kp">true</span><span class="p">,</span> <span class="ss">:uniqueness</span> <span class="o">=&gt;</span> <span class="kp">true</span><span class="p">,</span> <span class="ss">:format</span> <span class="o">=&gt;</span> <span class="p">{</span> <span class="ss">:with</span> <span class="o">=&gt;</span> <span class="sr">/[\w\d]*@[\w\d]*\.\w{2,5}/</span> <span class="p">}</span>
</span><span class='line'>  <span class="n">validates</span> <span class="ss">:password</span><span class="p">,</span> <span class="ss">:presence</span> <span class="o">=&gt;</span> <span class="kp">true</span><span class="p">,</span> <span class="ss">:length</span> <span class="o">=&gt;</span> <span class="p">{</span> <span class="ss">:minimum</span> <span class="o">=&gt;</span> <span class="mi">5</span> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">has_many</span> <span class="ss">:postings</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="k">class</span> <span class="nc">Posting</span> <span class="o">&lt;</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Base</span>
</span><span class='line'>  <span class="n">validates</span> <span class="ss">:title</span><span class="p">,</span> <span class="ss">:presence</span> <span class="o">=&gt;</span> <span class="kp">true</span><span class="p">,</span> <span class="ss">:length</span> <span class="o">=&gt;</span> <span class="p">{</span> <span class="ss">:minimum</span> <span class="o">=&gt;</span> <span class="mi">2</span><span class="p">,</span> <span class="ss">:maximum</span> <span class="o">=&gt;</span> <span class="mi">200</span> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">belongs_to</span> <span class="ss">:user</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>So einfach werden Validierungsregeln und Datenabhängigkeiten untereinander definiert.</p>

<p>Um an die Informationen im Modell zu kommen, benutzt man folgenden Aufruf:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">administrator</span> <span class="o">=</span> <span class="no">User</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="c1">#&lt;User id: 1, name: &quot;Jim Panse&quot;, email: &quot;jim@panse.com&quot;, password: &quot;ILoveTheJungle&quot;&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>Ebenso kommt man über diesen User direkt auch an seine Postings:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">administrator</span><span class="o">.</span><span class="n">postings</span><span class="o">.</span><span class="n">count</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="mi">4</span>
</span><span class='line'>
</span><span class='line'><span class="n">administrator</span><span class="o">.</span><span class="n">postings</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="o">[</span><span class="c1">#&lt;Posting id: 1, …&gt;, #&lt;Posting id: 4, …&gt;, …]</span>
</span></code></pre></td></tr></table></div></figure>


<h2>Rails: Fazit</h2>

<p>Mein erster Eindruck: Wenn man schnell eine Webapplikation bauen möchte, die in das oben beschriebene Schema passt, geht das mit Rails wirklich fix. Mit einem grundlegenden Tutorial daneben, um ab und an Details nachzuschlagen, kann man sehr schnell auch produktive Apps bauen.</p>

<p>Hat man hingegen sehr unstrukturierte Daten oder muss an vielen Stellen Hand anlegen und tief im System rumwerkeln, ist Rails glaube ich nicht die richtige Wahl, da auch sehr viel &#8220;Magic&#8221; im Hintergrund geschieht. Die immer im Detail zu verstehen und entsprechend &#8220;umbiegen&#8221; zu können ist sicher eher was für Rails-Experten.</p>

<p>Ich denke, auch hier greift wieder die typische 80/20-Regel: Für 80% der üblichen Web-Applikationen, die in irgendeiner Art Datensätze verwalten dürfte Rails gut passen und eine tolle Vereinfachung darstellen. Grade bei für Entwickler so leidige Themen wie Validierung, Datenmodellierung und -verarbeitung kann man sich vieles sparen und sich direkt um den Kern der Anwendung kümmern.</p>

<p>Rails hat eine sehr aktive Entwicklergemeinde, daher wird das Framework stets weiterentwickelt und verbessert, wobei man sich auch nicht scheut, Komponenten auszutauschen oder alte Zöpfe abzuschneiden, so dass man beim Updaten zumindest in Hauptversionszweigen (2.x, 3.0, 3.1) auf jeden Fall ein wenig die Augen aufhalten muss.
Da Rails aber dazu anhält, testorientiert zu entwickeln, lässt sich vieles vorab prüfen und beheben, bevor man eine neue Version seiner App in die Produktivumgebung einspielt.</p>

<h2>Links:</h2>

<ul>
<li><a href="http://tryruby.org">Try Ruby</a></li>
<li><a href="http://ruby.railstutorial.org/ruby-on-rails-tutorial-book">Ruby on Rails Tutorial</a></li>
<li><a href="http://www.railsforzombies.org">Interaktiver Screencast: Rails for Zombies</a></li>
<li><a href="http://rubyweekly.com/">Ruby Weekly: A free, once–weekly e-mail round-up of Ruby news and articles.</a></li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[CoffeeScript Tipp: require()-Aufrufe in Node.js mit einer Zeile]]></title>
    <link href="http://frederic-hemberger.de/artikel/coffeescript-tipp-require-aufrufe-in-node-js-mit-einer-zeile/"/>
    <updated>2011-07-30T09:17:00+02:00</updated>
    <id>http://frederic-hemberger.de/artikel/coffeescript-tipp-require-aufrufe-in-node-js-mit-einer-zeile</id>
    <content type="html"><![CDATA[<p>Wenn man bei der Entwicklung in Node.js CoffeeScript verwendet, kann man sich beim Laden von Modulen in ein wenig Tipparbeit sparen.</p>

<!-- more -->


<p>Statt alle Module einzeln einzubinden</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='coffeescript'><span class='line'><span class="nv">http = </span><span class="nx">require</span> <span class="s1">&#39;http&#39;</span>
</span><span class='line'><span class="nv">url  = </span><span class="nx">require</span> <span class="s1">&#39;url&#39;</span>
</span><span class='line'><span class="nv">util = </span><span class="nx">require</span> <span class="s1">&#39;util&#39;</span>
</span><span class='line'><span class="nv">fs   = </span><span class="nx">require</span> <span class="s1">&#39;fs&#39;</span>
</span></code></pre></td></tr></table></div></figure>


<p>lässt sich das auch bequem in einer Zeile abkürzen:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='coffeescript'><span class='line'><span class="p">[</span><span class="s1">&#39;http&#39;</span><span class="p">,</span> <span class="s1">&#39;url&#39;</span><span class="p">,</span> <span class="s1">&#39;util&#39;</span><span class="p">].</span><span class="nx">forEach</span> <span class="nf">(m) -&gt;</span> <span class="nx">global</span><span class="p">[</span><span class="nx">m</span><span class="p">]</span> <span class="o">=</span> <span class="nx">require</span> <span class="nx">m</span>
</span></code></pre></td></tr></table></div></figure>


<p>Danke an <a href="http://www.twitter.com/teemow">@teemow</a> für die kleine Korrektur.</p>
]]></content>
  </entry>
  
</feed>

