<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>RailsMagazin - Alles rund um Ruby on Rails &#187; Entwickler</title>
	<atom:link href="http://railsmagazin.de/category/entwickler/feed" rel="self" type="application/rss+xml" />
	<link>http://railsmagazin.de</link>
	<description></description>
	<lastBuildDate>Thu, 22 Jul 2010 16:47:38 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>de</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Ruby User Group München — Juli-Treffen</title>
		<link>http://railsmagazin.de/ruby-user-group-munchen-%e2%80%94-juli-treffen-1513</link>
		<comments>http://railsmagazin.de/ruby-user-group-munchen-%e2%80%94-juli-treffen-1513#comments</comments>
		<pubDate>Wed, 23 Jun 2010 14:40:27 +0000</pubDate>
		<dc:creator>Roland Moriz</dc:creator>
				<category><![CDATA[Entwickler]]></category>
		<category><![CDATA[Lokales]]></category>

		<guid isPermaLink="false">http://railsmagazin.de/?p=1513</guid>
		<description><![CDATA[
Die Münchner Ruby User Group trifft sich wieder am 12.07.2010 um 19:00 Uhr in den Räumen der Firma Valiton.
Um eine Anmeldung wird gebeten.
Weitere Informationen auf der Mailingliste.
Ähnliche ArtikelNeues von der Ruby User Group M&#252;nchenUser Group D&#252;sseldorf trifft sich am 31.03.2009Ruby und Ruby on Rails NutzergruppenM&#252;nchner Railser aufgepasst!D&#252;sseldorf on Rails l&#228;dt ein!]]></description>
			<content:encoded><![CDATA[<p><a href="http://ruby-muenchen.de/"><img src="http://railsmagazin.de/wp-content/uploads/2010/04/rugmuc_logo-300x183.jpg" alt="Ruby und Ruby on Rails in München" title="Ruby User Group München" width="300" height="183" class="alignright size-medium wp-image-1470" /></a><br />
Die <a href="http://ruby-muenchen.de/">Münchner Ruby User Group</a> trifft sich wieder am 12.07.2010 um 19:00 Uhr in den Räumen der Firma Valiton.</p>
<p><a href="http://www.doodle.com/hqaea7dzaue662k4">Um eine Anmeldung wird gebeten.</a></p>
<p><a href="http://groups.google.de/group/munich-on-rails/browse_thread/thread/388b1c90ce78ff1a">Weitere Informationen auf der Mailingliste.</a></p>
<div id="crp_related"><h3>Ähnliche Artikel</h3><ul><li><a href="http://railsmagazin.de/neues-von-der-ruby-user-group-munchen-1469" rel="bookmark">Neues von der Ruby User Group M&uuml;nchen</a></li><li><a href="http://railsmagazin.de/ruby-on-rails-user-group-dusseldorf-trifft-sich-am-31032009-1129" rel="bookmark">User Group D&uuml;sseldorf trifft sich am 31.03.2009</a></li><li><a href="http://railsmagazin.de/ruby-und-ruby-on-rails-nutzergruppen-965" rel="bookmark">Ruby und Ruby on Rails Nutzergruppen</a></li><li><a href="http://railsmagazin.de/muenchner-railser-aufgepasst-48" rel="bookmark">M&uuml;nchner Railser aufgepasst!</a></li><li><a href="http://railsmagazin.de/dusseldorf-on-rails-ladt-ein-1386" rel="bookmark">D&uuml;sseldorf on Rails l&auml;dt ein!</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://railsmagazin.de/ruby-user-group-munchen-%e2%80%94-juli-treffen-1513/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>RailsWayCon 2010 Fazit</title>
		<link>http://railsmagazin.de/railswaycon-2010-fazit-1477</link>
		<comments>http://railsmagazin.de/railswaycon-2010-fazit-1477#comments</comments>
		<pubDate>Thu, 03 Jun 2010 13:11:53 +0000</pubDate>
		<dc:creator>Roland Moriz</dc:creator>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[Entscheider]]></category>
		<category><![CDATA[Entwickler]]></category>
		<category><![CDATA[Lokales]]></category>
		<category><![CDATA[Veranstaltungen]]></category>

		<guid isPermaLink="false">http://railsmagazin.de/?p=1477</guid>
		<description><![CDATA[Auch dieses Jahr fand wieder die vom Software &#038; Support Verlag veranstaltete Konferenz im Rahmen der Webinale und International PHP Conference in Berlin statt. Gegenüber 2009 wurde der Veranstaltungsort gewechselt und man fand sich im Maritim proArte in der Friedrichstraße ein.
Die dreitägige Konferenz hat rundum überzeugt, die Vorträge waren besser und nützlicher als im letzten [...]]]></description>
			<content:encoded><![CDATA[<p>Auch dieses Jahr fand wieder die vom <a href="http://software-support.biz/">Software &#038; Support Verlag</a> <a href="http://www.railswaycon.com">veranstaltete Konferenz</a> im Rahmen der Webinale und International PHP Conference in Berlin statt. Gegenüber 2009 wurde der Veranstaltungsort gewechselt und man fand sich im Maritim proArte in der Friedrichstraße ein.</p>
<p>Die dreitägige Konferenz hat rundum überzeugt, die Vorträge waren besser und nützlicher als im letzten Jahr. Das Interesse, Rails in die sogenannten Enterprise-Bereiche (&#8220;<em>Websfear</em>&#8220;) zu bringen, prägte sehr viele Vorträge und auch die Paneldiskussion, an der u.a. <a href="http://yehudakatz.com/">Yehuda Katz</a> (Rails &#038; jQuery Core Entwickler) teilnahm. </p>
<p>Auch Rails 3 und Hosting waren heisse Themen die von mehreren Vorträgen behandelt wurden.</p>
<p>Hier eine Sammlung mit Links zu den Slides, sofern mir bekannt:</p>
<p><strong>Montag</strong></p>
<p>Dynamic Language VMs: Ruby 1.9<br />
<a href="http://blog.methodmissing.com/">Lourens Naudé</a><br />
<a href="http://www.slideshare.net/methodmissing/railswaycon-2010-dynamic-language-vms">http://www.slideshare.net/methodmissing/railswaycon-2010-dynamic-language-vms</a></p>
<p>Push it to the limit &#8211; An intro to Websockets and Rails applications<br />
<a href="http://rails-experts.com">Michael Johann</a></p>
<p>CouchDB on Rails<br />
<a href="http://blog.innerewut.de/">Jonathan Weiss</a><br />
<a href="http://www.slideshare.net/jweiss/couchdb-on-rails-railswaycon-2010">http://www.slideshare.net/jweiss/couchdb-on-rails-railswaycon-2010</a></p>
<p>Cross-browser testing in the real world<br />
<a href="http://www.yes-no-cancel.co.uk/">Martin Kleppmann</a><br />
<a href="http://www.slideshare.net/martinkleppmann/crossbrowser-testing-in-the-real-world">http://www.slideshare.net/martinkleppmann/crossbrowser-testing-in-the-real-world</a></p>
<p>Ruby on Rails Security Updated<br />
<a href="http://www.rorsecurity.info/">Heiko Webers</a><br />
<a href="http://www.slideshare.net/heikowebers/ruby-on-rails-security-updated-rails-3-at-railswaycon">http://www.slideshare.net/heikowebers/ruby-on-rails-security-updated-rails-3-at-railswaycon</a></p>
<p>Small is Sexy &#8211; We need Components in Rails!<br />
<a href="http://nicksda.apotomo.de/">Nick Sutterer</a></p>
<p>Be Authentic &#8211; Get into LDAP, Users and Roles<br />
<a href="http://rails-experts.com">Michael Johann</a></p>
<p>mongodb and mongomapper 4 real!<br />
<a href="http://jan.krutisch.de/">Jan Krutisch</a><br />
<a href="http://slidesha.re/aSNEan">http://slidesha.re/aSNEan</a></p>
<p>Command your Domain<br />
<a href="http://blog.methodmissing.com/">Lourens Naudé</a><br />
<a href="http://www.slideshare.net/methodmissing/railswaycon-2010-command-your-domain">http://www.slideshare.net/methodmissing/railswaycon-2010-command-your-domain</a></p>
<p><strong>Dienstag</strong></p>
<p>Rails 3: Dashing to the Finish<br />
<a href="http://yehudakatz.com/">Yehuda Katz</a><br />
<a href="http://www.slideshare.net/wycats/rails-3-dashing-to-the-finish">http://www.slideshare.net/wycats/rails-3-dashing-to-the-finish</a></p>
<p>A Testing Survival Guide<br />
<a href="http://upstre.am/blog/">Thilo Utke</a><br />
<a href="http://www.slideshare.net/freaklikeme/testing-survival-small">http://www.slideshare.net/freaklikeme/testing-survival-small</a></p>
<p>Rails in the Cloud &#8211; Lessons learned from building a platform on EC2<br />
<a href="http://blog.innerewut.de/">Jonathan Weiss</a><br />
<a href="http://www.slideshare.net/jweiss/rails-in-the-cloud-experiences-from-running-on-ec2">http://www.slideshare.net/jweiss/rails-in-the-cloud-experiences-from-running-on-ec2</a></p>
<p>Enterprise Rails Hosting<br />
<a href="http://www.avarteq.de/">Julian Fischer</a><br />
<a href="http://www.slideshare.net/avarteq/enterprise-hosting-2448821">http://www.slideshare.net/avarteq/enterprise-hosting-2448821</a></p>
<p>betterplace.org: Crashing and uncrashing a social startup<br />
Phillip Oertel, Till Behnke</p>
<p>10 fun projects to improve your coding skills<br />
<a href="http://jan.krutisch.de/">Jan Krutisch</a><br />
<a href="http://slidesha.re/aFHE0O">http://slidesha.re/aFHE0O</a><br />
<a href="http://jan.krutisch.de/en/fun_projects/">http://jan.krutisch.de/en/fun_projects/</a></p>
<p>SOLID Rails, SOLID Ruby &#8211; practical patterns applied<br />
<a href="http://blog.invisible.ch/">Jens-Christian Fischer</a>, <a href="http://www.michaelmahlberg.de/">Michael Mahlberg</a><br />
<a href="http://github.com/MichaelMahlberg/RailsWayCon2010">http://github.com/MichaelMahlberg/RailsWayCon2010</a></p>
<p>Productive Rails development with RubyMine<br />
<a href="http://twitter.com/oleg_s">Oleg Shpynov</a>, <a href="http://twitter.com/en_dal">Dennis Ushakov</a><br />
<a href="http://www.slideshare.net/olegshpynov/productive-rails-development-with-rubymine">http://www.slideshare.net/olegshpynov/productive-rails-development-with-rubymine</a></p>
<p>Evolutionary programming with Ruby<br />
<a href="http://www.avarteq.de/">Julian Fischer</a><br />
<a href="http://www.slideshare.net/avarteq/evolutionary-algorithms-in-ruby">http://www.slideshare.net/avarteq/evolutionary-algorithms-in-ruby</a></p>
<p>Improved performance with client side optimization<br />
<a href="http://www.huesler-informatik.ch/blog/">Patrick Hüsler</a></p>
<p>Culerity: Full stack Rails testing with Cucumber and Celerity<br />
<a href="http://www.huesler-informatik.ch/blog/">Patrick Hüsler</a></p>
<p><strong>Mittwoch</strong></p>
<p>Establishing an integrated JRuby/Rails &#8211; Stack in a Legacy environment<br />
<a href="http://www.innoq.com/blog/rps/">Rubén Parés-Selders</a></p>
<p>The State of RESTful Rails<br />
<a href="http://www.innoq.com/blog/st/">Stefan Tilkov</a><br />
<a href="http://www.innoq.com/blog/st/presentations/2010/2010-06-02-REST-Rails--RailsWayCon.pdf">http://www.innoq.com/blog/st/presentations/2010/2010-06-02-REST-Rails&#8211;RailsWayCon.pdf</a></p>
<p>Rails/Ruby Coding Dojo<br />
<a href="http://blog.invisible.ch/">Jens-Christian Fischer</a>, <a href="http://www.michaelmahlberg.de/">Michael Mahlberg</a><br />
<a href="http://github.com/jcfischer/RwcCodingDojo">http://github.com/jcfischer/RwcCodingDojo</a></p>
<p>Ruby and Redis &#8211; Simple meets Awesome<br />
<a href="http://www.paperplanes.de/">Mathias Meyer</a><br />
<a href="http://redis-railswaycon2010.heroku.com/">http://redis-railswaycon2010.heroku.com/</a></p>
<p>Using jQuery with Rails<br />
<a href="http://yehudakatz.com/">Yehuda Katz</a></p>
<p>The Anatomy of Ruby I18n: Overview of the Gem&#8217;s architecture and advanced features<br />
<a href="http://svenfuchs.com/">Sven Fuchs</a></p>
<p>Deliver Software with MacRuby<br />
<a href="http://upstre.am/blog/">Thilo Utke</a><br />
<a href="http://www.slideshare.net/freaklikeme/mac-ruby-deployment">http://www.slideshare.net/freaklikeme/mac-ruby-deployment</a></p>
<p><strong>Fazit:</strong></p>
<p>Die RWC2010 hat mir dieses Jahr deutlich besser gefallen als 2009. Die Talks waren nützlich und fast ausnahmslos sehr gut präsentiert. Es ergab sich durch das tägliche gemeinsame Mittagessen auch eine gute Möglichkeit zum Netzwerken. Die Party am Dienstag habe ich leider verschlafen, verweise aber auch deshalb gerne <a href="http://search.twitter.com/search?q=%23railswaycon">auf Twitter (#railswaycon) </a>.</p>
<p>Ich würde mich sehr über eine RailsWayConf 2011 oder 2012 freuen, wenn man die Überschneidung mit der Euruko 2011 in Berlin vermeiden möchte.</p>
<p>Am letzten Tag dann noch eine wunderbare Art des Reality-Checks: Ein Panel der Webinale, die für alle Teilnehmer geplant wurde, zeigte uns unbeabsichtigt auf, wie weit die deutsche Internet/Web/Medienszene im letzten Jahrhundert verankert ist:</p>
<p>Die von vielen von uns eingesetzten agilen Methoden, testgetriebene oder zumindest testgestützte Entwicklung in Kombination mit guter Usability braucht sich keinesfalls verstecken und ist noch immer Lichtjahre den etablierten voraus. Lasst uns also gemeinsam den Leuten zeigen wie es besser geht <img src='http://railsmagazin.de/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<div id="crp_related"><h3>Ähnliche Artikel</h3><ul><li><a href="http://railsmagazin.de/railswaycon-in-6-minuten-1411" rel="bookmark">RailsWayCon in 6 Minuten</a></li><li><a href="http://railsmagazin.de/video-deployment-mit-webistrano-1272" rel="bookmark">(Video) Deployment mit Webistrano</a></li><li><a href="http://railsmagazin.de/besuch-der-railswaycon-1393" rel="bookmark">Besuch der RailsWayCon</a></li><li><a href="http://railsmagazin.de/ical-timetable-fur-die-railswaycon-1382" rel="bookmark">iCal Timetable f&uuml;r die RailsWayCon</a></li><li><a href="http://railsmagazin.de/ruby-user-group-munchen-%e2%80%94-juli-treffen-1513" rel="bookmark">Ruby User Group M&uuml;nchen &mdash; Juli-Treffen</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://railsmagazin.de/railswaycon-2010-fazit-1477/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Munich on Rails trifft sich am 8. Oktober 2009</title>
		<link>http://railsmagazin.de/munich-on-rails-trifft-sich-am-donnerstag-8-oktober-2009-1450</link>
		<comments>http://railsmagazin.de/munich-on-rails-trifft-sich-am-donnerstag-8-oktober-2009-1450#comments</comments>
		<pubDate>Mon, 05 Oct 2009 13:45:00 +0000</pubDate>
		<dc:creator>Roland Moriz</dc:creator>
				<category><![CDATA[Entscheider]]></category>
		<category><![CDATA[Entwickler]]></category>
		<category><![CDATA[Veranstaltungen]]></category>

		<guid isPermaLink="false">http://railsmagazin.de/?p=1450</guid>
		<description><![CDATA[Wir laden herzlich ein zu unserem nächsten Treffen!
Termin 
  Donnerstag, 8. Oktober 2009 19:00 Uhr
   iCal: http://tinyurl.com/adj4hp
Vorträge
+ Marco Otte-Witte: Excellent  (http://simplabs.github.com/excellent)
+ Peter Schrammel: Share-Nothing Private Assets Server
+ Sven C. Koehler: Localmemcache  (http://localmemcache.rubyforge.org/ +   http://github.com/sck/localmemcache)
+ &#8230; Du?
Ort &#038; Anmeldung
Wir treffen uns dieses Mal bei der Experteer GmbH. Vielen Dank [...]]]></description>
			<content:encoded><![CDATA[<p>Wir laden herzlich ein zu unserem nächsten Treffen!</p>
<p><strong>Termin </strong></p>
<p>  Donnerstag, 8. Oktober 2009 19:00 Uhr</p>
<p>   iCal: <a href="http://tinyurl.com/adj4hp">http://tinyurl.com/adj4hp</a></p>
<p><strong>Vorträge</strong></p>
<p>+ Marco Otte-Witte: Excellent  (<a href="http://simplabs.github.com/excellent">http://simplabs.github.com/excellent</a>)</p>
<p>+ Peter Schrammel: Share-Nothing Private Assets Server</p>
<p>+ Sven C. Koehler: Localmemcache  (<a href="http://localmemcache.rubyforge.org/">http://localmemcache.rubyforge.org/</a> +   <a href="http://github.com/sck/localmemcache">http://github.com/sck/localmemcache</a>)</p>
<p>+ &#8230; Du?</p>
<p><strong>Ort &#038; Anmeldung</strong></p>
<p>Wir treffen uns dieses Mal bei der Experteer GmbH. Vielen Dank an Peter und das Experteer-Team für die Einladung!<br />
<strong>Bitte gebt uns auch wieder Bescheid ob Ihr teilnehmen möchtet um die Planung zu erleichtern. Bitte bis Mittwoch 7.10. per Mail an:</strong></p>
<p>    anmeldung AT munich-on-rails.com</p>
<p>Adresse:</p>
<p>Experteer GmbH<br />
Lenbachplatz 3<br />
80333 München</p>
<div id="crp_related"><h3>Ähnliche Artikel</h3><ul><li><a href="http://railsmagazin.de/munich-on-rails-ladt-ein-1139" rel="bookmark">Munich-on-Rails l&auml;dt ein!</a></li><li><a href="http://railsmagazin.de/excellent-statische-analyse-fur-ruby-und-rails-1444" rel="bookmark">Excellent - Statische Code Analyse f&uuml;r Ruby und Rails</a></li><li><a href="http://railsmagazin.de/muenchner-railser-aufgepasst-48" rel="bookmark">M&uuml;nchner Railser aufgepasst!</a></li><li><a href="http://railsmagazin.de/ruby-user-group-berlin-trifft-sich-am-242009-1234" rel="bookmark">Ruby User Group Berlin trifft sich am 2.4.2009</a></li><li><a href="http://railsmagazin.de/video-rspec-827" rel="bookmark">(Video) RSpec</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://railsmagazin.de/munich-on-rails-trifft-sich-am-donnerstag-8-oktober-2009-1450/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Schema F</title>
		<link>http://railsmagazin.de/schema-f-1419</link>
		<comments>http://railsmagazin.de/schema-f-1419#comments</comments>
		<pubDate>Thu, 11 Jun 2009 08:00:58 +0000</pubDate>
		<dc:creator>Peter Schrammel</dc:creator>
				<category><![CDATA[Entwickler]]></category>
		<category><![CDATA[Tipps]]></category>
		<category><![CDATA[datenbanken]]></category>
		<category><![CDATA[postgresql]]></category>

		<guid isPermaLink="false">http://railsmagazin.de/?p=1419</guid>
		<description><![CDATA[PostgreSQL bietet, wie einige andere Datenbanken auch, die Möglichkeit Schemata zu definieren um Namensräume für Tabellen und andere Datenbankobjekte anzulegen. Rails&#8217; Postgres Adapter kann mit Schemata umgehen und mit ein paar Tricks hat man eine Menge interessanter Anwendungsmöglichkeiten.

Am Anfang war die Konfiguration. Diese erfolgt wie üblich in der config/database.yml. Der Postgres Adapter kennt das Schlüsselwort [...]]]></description>
			<content:encoded><![CDATA[<p>PostgreSQL bietet, wie einige andere Datenbanken auch, die Möglichkeit Schemata zu definieren um Namensräume für Tabellen und andere Datenbankobjekte anzulegen. Rails&#8217; Postgres Adapter kann mit Schemata umgehen und mit ein paar Tricks hat man eine Menge interessanter Anwendungsmöglichkeiten.<br />
<span id="more-1419"></span><br />
Am Anfang war die Konfiguration. Diese erfolgt wie üblich in der config/database.yml. Der Postgres Adapter kennt das Schlüsselwort schema_search_path. Wenn man z.B.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">schema_search_path:  myschema,otherschema,public</pre></div></div>

<p>angibt, werden Datebankobjekte zunächst in myschema, dann in otherschema und schließlich in public gesucht. </p>
<p>Ein Anwendungsbeispiel wären z.B. temporäre Tabellen, die man während der Laufzeit erzeugen und mit einem &#8216;DROP SCHEMA xyz&#8217; wieder löschen kann. </p>
<p>Will man hingegen eine ganze Railsanwendung in einem Schema laufen lassen, stößt man unweigerlich auf ein Problem mit den Tests. Bei Tests wird ein &#8220;DROP testdatenbank&#8221; durchgeführt und das nimmt natürlich nicht nur das verwendete Schema mit ins Datennirvana.</p>
<p>Deshalb muß der Task &#8216;create_database&#8217; und die Methode &#8216;drop_database&#8217; ein wenig gepatcht werden. Man erstellt also in &#8216;/lib/tasks/core.rake&#8217; (oder wie man es auch immer nennen mag) eine Date folgenden Inhalts:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">namespace <span style="color:#ff3333; font-weight:bold;">:db</span> <span style="color:#9966CC; font-weight:bold;">do</span>
  namespace <span style="color:#ff3333; font-weight:bold;">:create</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    <span style="color:#9966CC; font-weight:bold;">def</span> create_database<span style="color:#006600; font-weight:bold;">&#40;</span>config<span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#008000; font-style:italic;">#ensure the database exists:</span>
      <span style="color:#9966CC; font-weight:bold;">begin</span>
        ccopy=config.<span style="color:#9900CC;">dup</span>.<span style="color:#9900CC;">merge</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'schema_search_path'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'public'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
        <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>.<span style="color:#9900CC;">establish_connection</span><span style="color:#006600; font-weight:bold;">&#40;</span>ccopy<span style="color:#006600; font-weight:bold;">&#41;</span>
        <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>.<span style="color:#9900CC;">connection</span>
      <span style="color:#9966CC; font-weight:bold;">rescue</span>
        <span style="color:#0066ff; font-weight:bold;">@encoding</span> = config<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:encoding</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">||</span> ENV<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'CHARSET'</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">||</span> <span style="color:#996600;">'utf8'</span>
        <span style="color:#9966CC; font-weight:bold;">begin</span>
          ccopy=config.<span style="color:#9900CC;">dup</span>.<span style="color:#9900CC;">merge</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'database'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'postgres'</span>,
                       <span style="color:#996600;">'schema_search_path'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'public'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
          <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>.<span style="color:#9900CC;">establish_connection</span><span style="color:#006600; font-weight:bold;">&#40;</span>ccopy<span style="color:#006600; font-weight:bold;">&#41;</span>
         <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>.<span style="color:#9900CC;">connection</span>.<span style="color:#9900CC;">create_database</span><span style="color:#006600; font-weight:bold;">&#40;</span>config<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'database'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
           config.<span style="color:#9900CC;">merge</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'encoding'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0066ff; font-weight:bold;">@encoding</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
        <span style="color:#9966CC; font-weight:bold;">rescue</span>
          <span style="color:#ff6633; font-weight:bold;">$stderr</span>.<span style="color:#CC0066; font-weight:bold;">puts</span> $!, <span style="color:#006600; font-weight:bold;">*</span><span style="color:#006600; font-weight:bold;">&#40;</span>$!.<span style="color:#9900CC;">backtrace</span><span style="color:#006600; font-weight:bold;">&#41;</span>
          <span style="color:#ff6633; font-weight:bold;">$stderr</span>.<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;Couldn't create database for #{config.inspect}&quot;</span>
        <span style="color:#9966CC; font-weight:bold;">end</span>
      <span style="color:#9966CC; font-weight:bold;">else</span>
        <span style="color:#ff6633; font-weight:bold;">$stderr</span>.<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;#{config['database']} already exists&quot;</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
      <span style="color:#008000; font-style:italic;">#ensure the schema exists:</span>
      <span style="color:#9966CC; font-weight:bold;">if</span> schema_name=config<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'working_schema'</span><span style="color:#006600; font-weight:bold;">&#93;</span>
        <span style="color:#9966CC; font-weight:bold;">begin</span>
          <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>.<span style="color:#9900CC;">establish_connection</span><span style="color:#006600; font-weight:bold;">&#40;</span>config<span style="color:#006600; font-weight:bold;">&#41;</span>
          <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>.<span style="color:#9900CC;">connection</span>
        <span style="color:#9966CC; font-weight:bold;">rescue</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::StatementInvalid</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> e
          <span style="color:#CC0066; font-weight:bold;">puts</span> e.<span style="color:#9966CC; font-weight:bold;">class</span>.<span style="color:#9900CC;">ancestors</span>.<span style="color:#9900CC;">inspect</span>
          <span style="color:#9966CC; font-weight:bold;">begin</span>
            ccopy=config.<span style="color:#9900CC;">dup</span>.<span style="color:#9900CC;">merge</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'schema_search_path'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'public'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
            <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>.<span style="color:#9900CC;">establish_connection</span><span style="color:#006600; font-weight:bold;">&#40;</span>ccopy<span style="color:#006600; font-weight:bold;">&#41;</span>
            <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>.<span style="color:#9900CC;">connection</span>.<span style="color:#9900CC;">execute</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;CREATE SCHEMA <span style="color:#000099;">\&quot;</span>#{schema_name}<span style="color:#000099;">\&quot;</span>&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
            <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>.<span style="color:#9900CC;">establish_connection</span><span style="color:#006600; font-weight:bold;">&#40;</span>config<span style="color:#006600; font-weight:bold;">&#41;</span>
          <span style="color:#9966CC; font-weight:bold;">rescue</span>
            <span style="color:#ff6633; font-weight:bold;">$stderr</span>.<span style="color:#CC0066; font-weight:bold;">puts</span> $!, <span style="color:#006600; font-weight:bold;">*</span><span style="color:#006600; font-weight:bold;">&#40;</span>$!.<span style="color:#9900CC;">backtrace</span><span style="color:#006600; font-weight:bold;">&#41;</span>
            <span style="color:#ff6633; font-weight:bold;">$stderr</span>.<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;Couldn't create database for #{config.inspect}&quot;</span>
          <span style="color:#9966CC; font-weight:bold;">end</span>
          <span style="color:#008000; font-style:italic;">#some error</span>
        <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
      <span style="color:#9966CC; font-weight:bold;">end</span> <span style="color:#008000; font-style:italic;">#schema</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">def</span> drop_database<span style="color:#006600; font-weight:bold;">&#40;</span>config<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>.<span style="color:#9900CC;">establish_connection</span><span style="color:#006600; font-weight:bold;">&#40;</span>config.
      <span style="color:#9900CC;">merge</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'database'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'postgres'</span>, <span style="color:#996600;">'schema_search_path'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'public'</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">if</span> schema_name=config<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'working_schema'</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>.<span style="color:#9900CC;">connection</span>.<span style="color:#9900CC;">execute</span> <span style="color:#996600;">&quot;DROP SCHEMA IF EXISTS <span style="color:#000099;">\&quot;</span>#{schema_name}<span style="color:#000099;">\&quot;</span> CASCADE&quot;</span>
  <span style="color:#9966CC; font-weight:bold;">else</span>
    <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>.<span style="color:#9900CC;">connection</span>.<span style="color:#9900CC;">drop_database</span> config<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'database'</span><span style="color:#006600; font-weight:bold;">&#93;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Die config/database.yml könnte wie folgt aussehen:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">test:
  adapter: postgresql
  database: development
  schema_search_path: test,base_data,public
  working_schema: test
  host: myhost
  username: username
  password: password</pre></div></div>

<p>Durch diesen Patch kann man ein &#8220;working_schema&#8221; wie eine richtige Datenbank verwenden. Wozu das gut ist? </p>
<ul>
<li>
Mehrere Applikationen können sich eine Datenbank teilen.
</li>
<li>Die Applikationen können sich Basisdaten (User, Geolocations, &#8230;) und andere Datenbankobjekte teilen.
</li>
<li> Man benötigt keine DROP/CREATE DATABASE Privilegien.</li>
<li> Im Gegensatz zu Datenbanken können Abfragen schemata-übergreifend formuliert werden.</li>
</ul>
<p>Lasst euch was einfallen und viel Spaß beim einem interessanten Setup (und das bestimmt nicht nach Schema F).</p>
<div id="crp_related"><h3>Ähnliche Artikel</h3><ul><li><a href="http://railsmagazin.de/cursors_in_rails-214" rel="bookmark">(Fake-) Cursors f&uuml;r ActiveRecord (Rails 2.3)</a></li><li><a href="http://railsmagazin.de/refactoring-von-rails-anwendungen-was-tun-wenn-der-laufsteg-durchbricht-450" rel="bookmark">Refactoring von Rails-Anwendungen: Was tun wenn der Laufsteg durchbricht?</a></li><li><a href="http://railsmagazin.de/besuch-der-railswaycon-1393" rel="bookmark">Besuch der RailsWayCon</a></li><li><a href="http://railsmagazin.de/excellent-statische-analyse-fur-ruby-und-rails-1444" rel="bookmark">Excellent - Statische Code Analyse f&uuml;r Ruby und Rails</a></li><li><a href="http://railsmagazin.de/tipps-der-woche-09-2009-126" rel="bookmark">Tipps der Woche - 09/2009</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://railsmagazin.de/schema-f-1419/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Besuch der RailsWayCon</title>
		<link>http://railsmagazin.de/besuch-der-railswaycon-1393</link>
		<comments>http://railsmagazin.de/besuch-der-railswaycon-1393#comments</comments>
		<pubDate>Wed, 27 May 2009 20:04:38 +0000</pubDate>
		<dc:creator>Bernhard Fuchs</dc:creator>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[Entwickler]]></category>

		<guid isPermaLink="false">http://railsmagazin.de/?p=1393</guid>
		<description><![CDATA[Heute schloss die RailsWayCon in Berlin seine Pforten und drei Tage lang durften sich die Teilnehmer großartiger Vorträge und Workshops erfreuen. Natürlich waren auch einige User von Munich-On-Rails präsent (unter anderem ich   ) &#8211; daher gibt es jetzt und hier ein kleines Fazit.

Keynotes
Die erste Keynote hielt Ola Bini, dem JRuby Guru und Erfinder [...]]]></description>
			<content:encoded><![CDATA[<p>Heute schloss die <a href="http://it-republik.de/conferences/railswaycon/">RailsWayCon</a> in Berlin seine Pforten und drei Tage lang durften sich die Teilnehmer großartiger Vorträge und Workshops erfreuen. Natürlich waren auch einige User von Munich-On-Rails präsent (unter anderem ich <img src='http://railsmagazin.de/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  ) &#8211; daher gibt es jetzt und hier ein kleines Fazit.</p>
<p><span id="more-1393"></span></p>
<p><strong>Keynotes</strong></p>
<p>Die erste Keynote hielt <a href="http://ola-bini.com/">Ola Bini</a>, dem JRuby Guru und Erfinder der Sprache <a href="http://ioke.org">Ioke</a>. Sehr humorvoll legte er die Geschichte von Programmiersprachen dar und machte einen Ausblick auf deren Zukunft. Die Relevanz von Java wurde dabei relativiert, da es ja die JVM sei, die die Stabilität gewährleistet und nicht die Sprache darüber. Bini räumte Ruby einen grossen Part ein, war aber auch der Meinung dass in Zukunft eher “Multi-Language-Programming” zur Disziplin werden würde und auch der Fokus in Richtung Domain-Specific-Languages gehen würde.</p>
<p>Bei der zweiten liess uns <a href="http://yehudakatz.com/">Yehuda Katz</a> einen Blick in das 2009 erwartete Rails 3.0 Framework werfen. Ein grosser Schritt wird dabei die Einführung von ActiveORM sein, einer Abstraktion der Datenbankdriver. Dadurch können Schnittstellen zu Datenbanken wie z.B. CouchDB oder SimpleDB geschaffen werden, die besser mit ActiveRecord zusammenarbeiten als es bisher möglich ist. Durch den Einsatz von Rack für die Abstraktion des Controllerdesigns lassen sich in Zukunft alternative Frameworks wie Sinatra oder Merb in Rails einbauen, so dass man die Flexibilität erhält in der Anwendung diese Framewerks parallel zu verwenden. Rails3 ist allerdings nicht vor Ende des Google Summer of Code zu erwarten.</p>
<p><strong>Vorträge</strong></p>
<p>Die Vorträge waren bunt gemischt und oft fiel die Wahl sehr schwer, welchen man nun besuchen sollte daher kann ich hier auch nur einige erwänen.</p>
<p><a href="http://jan.krutisch.de/">Jan Krutisch</a> machte den Besuchern die Verwendung von HAML und SASS schmackhaft. Beides sind Templatesprachen, die das Erstellen von HTML und CSS sehr vereinfachen und strukturierten Code erzeugen. SASS hat den enormen Vorteil dass man Konstanten für das Styling benutzen kann und somit beispielsweise Farbangaben einmal definiert und beliebig verwenden kann. Ein anschliessender Einblick in das CSS Metaframework <a href="http://github.com/chriseppstein/compass/tree/master">Compass</a> schloss das Thema rund ab.</p>
<p>Stefan Tilkov von <a href="http://innoQ.de">innoQ</a> gab einen tieferen Einblick in das Konzept von RESTful Rails und welches die besten Praktiken dafür sind. Dabei wurden die Standardmethoden (GET,PUT,POST,DELETE) erleutert und wann sie zu benutzen sind. Sehr interessant dabei war, dass man durchaus eigene Methoden hinzufügen kann auch wenn es nicht notwendigerweise Sinn ergibt. Da REST über HTTP optimal implementiert ist, schlug Tilkov vor durchaus kleinere Anwendungsteile mit Rails zu erstellen und REST-Schnittstellen zu schaffen, da die Operabilität zu anderen Anwendungsteilen dadurch gewährleistet ist.</p>
<p>Ein Vortrag auf den ich mich besonders gefreut hatte war “Rails sitting on the Couch” von Alexander Lang. Er stellte sein Plugin <a href="http://github.com/langalex/couch_potato">Couch Potato</a> vor, das eine Schnittstelle zur der dokumentbasierten Datenbank CouchDB bietet. Diese ist leider nicht ActiveRecord kompatibel, was jedoch auch nur schwer möglich ist, da es keine Tabellen und somit auch keine Tabellenbezüge gibt. Lang vertrat die Ansicht, dass durch eine DB, die wie CouchDB eine REST-Schnittstelle bietet der Server als “Middleware” komplett wegfallen könne und somit die Anwendungen auf reinen Javascript-Frameworks wie Sammy laufen könnten und direkt mit der Datenbank sprechen. Hier bin ich persönlich sehr skeptisch da schon allein der Sicherheitsaspekt problematisch wird.</p>
<p>“JQuery mit Rails” hiess ein Vortrag von Yehuda Katz, bei dem es um den Einsatz von JQuery parallel zu Prototype ging. Dabei wurden das Konzept von JQuery erklärt und einige konkrete Beispiele gezeigt. Katz vertritt die Meinung, dass RJS unbrauchbar ist und zeigte best practises wie man Templates von JS-Code entkoppelt.</p>
<p>Ein ähnliches Thema präsentierte Steven Bristol (<a href="http://lesseverything.com/">Less Everything</a>). Ihm ging es um “Advanced Javascript and Rails”. Dabei vertrat er jedoch die gegenteilige Meinung als Yehuda Katz, da mit Hilfe von JRails, einem Plugin das Prototype in Rails ersetzt, alle Helper benutzt werden können und der eigentliche Rubycode somit sauber bleibt. Da Katz mit im Publikum saß gab das natürlich eine Grundsatzdiskussion, jedoch akzeptierten beide die Meinungen des jeweils anderen. Interessant bei dem Vortrag waren auch die aufgezeigte Möglichkeit des Monkey Patching in JavaScript, sowie elegate OOP Vorgehensweisen.</p>
<p><a href="http://www.rails-experts.com/">Michael Johann</a>, Chefredakteur des <a href="http://it-republik.de/railsway/">RailsWay-Magazins</a>, gab einen großartigen Einblick darüber wie man in JRuby auf Swing und EJB 3.0 zugreifen kann. Sehr beeindruckend war wie man über die (J)Ruby-Konsole on-the-fly interaktiv eine GUI erstellen kann. Mit vielen praktischen Beispielen zeigte Johann, wie einfach sich EJB-Klassen mit Rails verbinden lassen und man dadurch bestehende Webanwendungen in Rails-Anwendungen integrieren kann. Dies eröffnet dem Ruby-Programmierer die komplette Java-Welt und umgekehrt können Javaentwickler Rails benutzen ohne auf gewohnte Frameworks verzichten zu müssen.</p>
<p>Des weiteren stellte Ralph von der Heyden, Mitarbeiter bei <a href="http://www.xing.de/">Xing</a>,  Möglichkeiten zur Verbessung von Frontend Performance vor und <a href="http://blog.geekQ.net">Vladimir Dobriakov</a> (<a href="http://www.innoQ.de">innoQ</a>) zeigte uns wie evil “eval” beim Metaprogramming sein kann.</p>
<p><strong>Fazit</strong></p>
<p>Wie schon erwähnt kann der Artikel nur einen kleinen Einblick in die RailsWayCon bieten, die von Anfang bis Ende als voller Erfolg zu bezeichnen ist. Schade dass es vorbei ist, die Woche hätte man meinetwegen gerne voll machen können. Aber da bleibt nur übrig sich auf nächstes Jahr zu freuen.</p>
<div id="crp_related"><h3>Ähnliche Artikel</h3><ul><li><a href="http://railsmagazin.de/railswaycon-2010-fazit-1477" rel="bookmark">RailsWayCon 2010 Fazit</a></li><li><a href="http://railsmagazin.de/kurz-berichtet-jruby-im-enterprise-1244" rel="bookmark">Kurz berichtet: JRuby im Enterprise</a></li><li><a href="http://railsmagazin.de/ical-timetable-fur-die-railswaycon-1382" rel="bookmark">iCal Timetable f&uuml;r die RailsWayCon</a></li><li><a href="http://railsmagazin.de/railswaycon-in-6-minuten-1411" rel="bookmark">RailsWayCon in 6 Minuten</a></li><li><a href="http://railsmagazin.de/dusseldorf-on-rails-ladt-ein-3-1446" rel="bookmark">D&uuml;sseldorf on Rails l&auml;dt ein!</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://railsmagazin.de/besuch-der-railswaycon-1393/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Success Story: globago.com</title>
		<link>http://railsmagazin.de/success-story-globagocom-1334</link>
		<comments>http://railsmagazin.de/success-story-globagocom-1334#comments</comments>
		<pubDate>Tue, 28 Apr 2009 10:08:48 +0000</pubDate>
		<dc:creator>Marco Otte-Witte</dc:creator>
				<category><![CDATA[Entscheider]]></category>
		<category><![CDATA[Entwickler]]></category>
		<category><![CDATA[success story]]></category>

		<guid isPermaLink="false">http://railsmagazin.de/?p=1334</guid>
		<description><![CDATA[Am vergangenen Freitag ist Globago.com in die (Private) Beta gelauncht. Globago ist eine Plattform für Geschäftsreisende, die verschiedene Informationen über das jeweilige Reiseziel bereitstellt und Funktionen etwa zur Anzeige von Hotels etc. auf Google Maps sowie zur Erstellung eines persönlichen Reiseplans bietet.
Die Plattform wurde in nur 6 Wochen from scratch entwickelt. Ausgangslage waren lediglich ein [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://globago.com"><img src="http://railsmagazin.de/wp-content/uploads/2009/04/globagocom.png" alt="Globago.com" title="Globago.com" width="300" height="221" class="alignleft size-medium wp-image-1364" /></a>Am vergangenen Freitag ist <a href="http://globago.com">Globago.com</a> in die (Private) Beta gelauncht. Globago ist eine Plattform für Geschäftsreisende, die verschiedene Informationen über das jeweilige Reiseziel bereitstellt und Funktionen etwa zur Anzeige von Hotels etc. auf Google Maps sowie zur Erstellung eines persönlichen Reiseplans bietet.</p>
<p>Die Plattform wurde in nur 6 Wochen <strong>from scratch</strong> entwickelt. Ausgangslage waren lediglich ein mehr oder weniger grobes Konzept sowie ein darauf basierendes und damit zwangsläufig zu Anfang ebenso grobes Design. Eine Vielzahl von wichtigen Entscheidungen zu Design und Funktionalität wurde also erst relativ spontan während der Entwicklungsphase getroffen.</p>
<p>Dieser Artikel geht auf einige technische Aspekte des Projekts ein und zeigt auf wie viel man mit <a href="http://rubyonrails.org">Rails</a> in kurzer Zeit bei hoher Qualität und Flexibilität erreichen kann.</p>
<p><span id="more-1334"></span></p>
<h2>Infrastruktur</h2>
<p>Am Anfang eines jeden Projekts steht das Aufsetzen der Infrastruktur wie Versionskontrolle, Ticketing System etc. Hier muss man sich entscheiden ob man alles selbst aufsetzen möchte (SVN, Trac etc.) oder lieber auf <strong><a href="http://de.wikipedia.org/wiki/Software_as_a_Service">SaaS</a> Angebote</strong> zurückgreift. Diese haben den Vorteil, dass keinerlei oder nur sehr geringer Aufwand entsteht und sie (evtl. mit Ausnahme von github <img src='http://railsmagazin.de/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  zuverlässig laufen.</p>
<p>Für dieses Projekt habe ich mich für die Kombination aus <a href="http://github.com">gihub</a>, <a href="http://lighthouseapp.com">Lighthouse</a> und <a href="http://hoptoadapp.com">Hoptad</a> entschieden, die sich auch in vergangenen Projekten schon bewährt hat. Insbesondere die Integration der einzelnen Services ist dabei ein großer Vorteil. So kann man bspw. <a href="http://hoth.entp.com/2008/4/11/github-and-lighthouse-sitting-in-a-tree">in Commit Messages Lighthouse-Tickets referenzieren oder sogar modifizieren</a> und seit neuestem auch <a href="http://giantrobots.thoughtbot.com/2009/4/8/hoptoad-now-supports-github-integration">aus in Hoptoad angezeigten Backtraces direkt auf den entsprechenden Code in der entsprechenden Revision auf github wechseln</a>. </p>
<h2>Testing</h2>
<p>Obwohl ich selbst ein großer Freund von Testing bzw. Specs bin (siehe auch <a href="http://railsmagazin.de/video-rspec-827">meinen Vortrag zu RSpec</a>) muss man bei einem Projekt wie diesem, mit straffem Zeitrahmen und zunächst mehr oder weniger ungenauen Anforderungen, abwägen zwischen Flexibilität und Entwicklungsgeschwindigkeit auf der einen und gut getestetem Code auf der anderen Seite. Wenn die Anfoderungen nicht einigermaßen eindeutig bekannt und insb. formuliert sind, ist es fast kontraproduktiv, zunächst eine umfassende Test- bzw. Spec- Suite zu schreiben, da das durch eine solche Suite spezifizierte Verhalten ja noch gar nicht ausreichend bekannt ist. Es fließt in diesem Fall also viel Arbeit in die permanente Aktualisierung der Specs so dass es sicher mehr Sinn macht, mindestens den Prototypen quasi auf althergebrachte Art und Weise zu entwicklen und die Anwendung erst in der Konsolidierungsphase umfassend zu testen. Ich habe daher weitestgehend auf Specs verzichtet und lediglich Dinge wie Validations etc. spezifiziert um sicherzugehen, dass das grundlegende Model korrekt ist. Das eigentliche Acceptance Testing wurde jeweils zum Abschluss der einzelnen Milestones vom Kunden selbst durchgeführt. So erhält der Entwickler frühzeitig Feedback vom Kunden, der widerum frühzeitig einen Blick auf seinen zukünftige Anwendung werfen und den Entwicklungsverlauf verfolgen kann.</p>
<h2>Per Scaffolding zum (fast) fertigen Backend</h2>
<p>Das oftmals zu recht kritisierte <a href="http://api.rubyonrails.org/classes/ActionController/Scaffolding/ClassMethods.html">Scaffolding</a> kann für prototypische Anwendungen und insbesondere Backend-Funktionalität gute Dienste leisten. Bei einem Content getriebenen Dienst wie <a href="http://globago.com">Globago.com</a>, bei dem die Hauptaufgabe des Backends das Anlegen, Bearbeiten, Löschen etc. von unterschiedlichem Content ist, kommt man per Scaffolding &#8211; selbst wenn man die generierten Controller, Views etc. noch anpassen muss, innerhalb kürzester Zeit zum fertigen Backend. Alternativ macht sicher auch der Einsatz von Plugins wie <a href="http://github.com/hcatlin/make_resourceful/tree/master">Hampton Catlins make_resourceful</a> Sinn, die im Gegensatz zu <code>./script/generate scaffold ...</code> <a href="http://de.wikipedia.org/wiki/DRY">DRY</a>- konformer sind, allerdings nicht das manuelle Anlegen von Views ersparen.</p>
<h2>Deployment</h2>
<p>Für das Deployment von Rails Anwendungen gibt es mittlerweile <a href="http://rubyonrails.org/deploy">eine Vielzahl von Optionen</a>. Die mit dem geringsten Aufwand ist aber sicherlich <a href="http://www.modrails.com/">Passenger</a>, das in der <a href="http://blog.phusion.nl/2009/04/16/phusions-one-year-anniversary-gift-phusion-passenger-220/">neusten Version jetzt auch für Nginx</a> verfügbar ist. Gegenüber anderen Ruby Webservern wie <a href="http://mongrel.rubyforge.org/">Mongrel</a> oder <a href="http://code.macournoyer.com/thin/">Thin</a> hat Passenger zwar keinen signifikanten Performance Vorteil, in der Regel aber einen deutlich kleineren Memory Footprint. Vor allem wird aber das Deployment deutlich vereinfacht. Anstatt <code>mongrel_cluster</code> oder <code>thin start --socket ...</code>, wobei man ggf. noch darauf achten muss, die einzelnen Prozesse zeitversetzt neu zu starten um Downtimes zu vermeiden (siehe auch <a href="http://blog.pragmatic-it.de/articles/2008/07/09/poor-mans-rolling-restart-for-thin-god">Poor mans rolling restart for thin + god</a>), genügt bei Passenger ein einfaches <code>touch restart.txt</code> im <code>RAILS_ROOT</code> und Passenger startet die Anwendung automatisch neu, spawnt Prozesse etc. Auch ist kein Monitoring von Prozessen mehr nötig wie es bei Mongrel oder Thin praktisch unverzichtbar ist. Auch die Konfiguration von Passenger ist denkbar einfach &#8211;  insbesondere in Kombination mit Nginx:</p>
<p><code></p>
<pre style="background: white;">
  http {
    passenger_root /opt/ruby-enterprise-1.8.6-20090201/lib/ruby/gems/1.8/gems/passenger-2.2.1;
    passenger_ruby /opt/ruby-enterprise-1.8.6-20090201/bin/ruby;
    ...
    server {
        listen       80;
        server_name  *.globago.com;

        root &lt;path to RAILS_ROOT/public&gt;;
        passenger_enabled on;
    }
    ...
  }
</pre>
<p></code></p>
<h2>Fazit</h2>
<p>Das Projekt <a href="http://globago.com">Globago.com</a> zeigt deutlich, wie viel sich in kurzer Zeit mit Rails realisieren lässt. Es lassen sich extrem schnell Features umsetzen (auch ohne die komplette Anwendung einfach zu scaffolden <img src='http://railsmagazin.de/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  ohne dass die Qualität des Ergebnisses leidet. Mit anderen Frameworks mag sich ebenso viel in ebenso kurzer Zeit realisieren lassen, das Ergebnis ist aber mit relativ hoher Sicherheit minderwertiger. Auch existiert mit github, Lighthouse, Hoptoad und anderen Diensten eine hervorragende Projekt- Infrastruktur als SaaS.</p>
<h2>Das Projekt</h2>
<table class="widefat" style="background: white;">
<tr>
<th><strong>Entwicklungszeit</strong></th>
<td>6 Wochen</td>
</tr>
<tr>
<th><strong>Entwicklerteam</strong></th>
<td>1 Entwickler in Vollzeit, 1 Designer in Teilzeit, PSD2HTML</td>
</tr>
<tr>
<th><strong>Projekt-Infrastruktur</strong></th>
<td>github, Lighthouse, Hoptoad</td>
</tr>
<tr>
<th><strong>Plugins</strong></th>
<td>acts_as_list, hoptoad_notifier, paperclip, rspec, thinking_sphinx, geokit, will_paginate</td>
</tr>
<tr>
<th><strong>Deployment</strong></th>
<td>Capistrano, Passenger, Nginx</td>
</tr>
</table>
<div id="crp_related"><h3>Ähnliche Artikel</h3><ul><li><a href="http://railsmagazin.de/logfile-rotation-fur-phusion-passenger-292" rel="bookmark">Logfile Rotation f&uuml;r Phusion Passenger</a></li><li><a href="http://railsmagazin.de/video-rspec-827" rel="bookmark">(Video) RSpec</a></li><li><a href="http://railsmagazin.de/google_gdata_rails-238" rel="bookmark">Google ver&ouml;ffentlicht gem f&uuml;r diverse APIs</a></li><li><a href="http://railsmagazin.de/refactoring-von-rails-anwendungen-was-tun-wenn-der-laufsteg-durchbricht-450" rel="bookmark">Refactoring von Rails-Anwendungen: Was tun wenn der Laufsteg durchbricht?</a></li><li><a href="http://railsmagazin.de/buchvorstellung-enterprise-rails-901" rel="bookmark">Buchvorstellung: Enterprise Rails</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://railsmagazin.de/success-story-globagocom-1334/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>(Video) Was ist Rack?</title>
		<link>http://railsmagazin.de/video-was-ist-rack-1255</link>
		<comments>http://railsmagazin.de/video-was-ist-rack-1255#comments</comments>
		<pubDate>Sun, 05 Apr 2009 13:47:42 +0000</pubDate>
		<dc:creator>Christian Neukirchen</dc:creator>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[Entwickler]]></category>
		<category><![CDATA[Veranstaltungen]]></category>
		<category><![CDATA[Videos]]></category>
		<category><![CDATA[rack]]></category>

		<guid isPermaLink="false">http://railsmagazin.de/?p=1255</guid>
		<description><![CDATA[
Letzten Donnerstag (02.04.2009) hielt ich bei der Münchner Ruby on Rails User Group einen Vortrag zum Thema &#8220;Was ist Rack?&#8221;.
Der Talk dauert gute 20 Minuten und beantwortet unter anderem:

 Was ist Rack?
Wie sieht eine einfache Rack-Anwendung aus?
Welche Vorteile bietet Rack?
Wer verwendet Rack?
Wie profitieren Rails-User?  Wie können Rails-User Rack verwenden?
Rack in anderen Sprachen
Q&#38;A



Download (650 MB, [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://railsmagazin.de/video-was-ist-rack-1255"><img src="http://railsmagazin.de/wp-content/uploads/2009/04/rack1.jpg" alt="rack1" title="rack1" width="250" height="167" class="alignright size-full wp-image-1261" /></a></p>
<p>Letzten Donnerstag (02.04.2009) hielt ich bei der <a href="http://www.munich-on-rails.com/">Münchner Ruby on Rails User Group</a> einen Vortrag zum Thema &#8220;Was ist Rack?&#8221;.</p>
<p>Der Talk dauert gute 20 Minuten und beantwortet unter anderem:</p>
<ul>
<li> Was ist Rack?</li>
<li>Wie sieht eine einfache Rack-Anwendung aus?</li>
<li>Welche Vorteile bietet Rack?</li>
<li>Wer verwendet Rack?</li>
<li>Wie profitieren Rails-User?  Wie können Rails-User Rack verwenden?</li>
<li>Rack in anderen Sprachen</li>
<li>Q&amp;A</li>
</ul>
<p><span id="more-1255"></span></p>
<p><object classid="clsid:02bf25d5-8c17-4b23-bc80-d3488abddc6b" width="640" height="378" codebase="http://www.apple.com/qtactivex/qtplugin.cab#version=6,0,2,0"><param name="src" value="http://dl.dropbox.com/u/28187/RubyMuenchenVideos/MoR-Christian_Neukirchen-Rack-720.mov" /><param name="autoplay" value="false" /><param name="type" value="video/quicktime" /><embed type="video/quicktime" scale="tofit"  width="640" height="378" src="http://dl.dropbox.com/u/28187/RubyMuenchenVideos/MoR-Christian_Neukirchen-Rack-720.mov" autoplay="false"></embed></object></p>
<p><a href="http://dl.dropbox.com/u/28187/RubyMuenchenVideos/MoR-Christian_Neukirchen-Rack-720.mov">Download (650 MB, 720HD 16:9, Quicktime) </a></p>
<p>Die Folien gibts <a href="http://chneukirchen.org/talks/index.html#wasistrack">direkt auf meiner Website</a>.</p>
<p>Weitere Links:</p>
<ul>
<li> <a href="http://rack.rubyforge.org/">http://rack.rubyforge.org/</a></li>
<li> <a href="http://github.com/rack/">http://github.com/rack/</a></li>
<li> <a href="http://wiki.github.com/rack/rack/presentations">Weitere Vorträge zu Rack</a></li>
</ul>
<div id="crp_related"><h3>Ähnliche Artikel</h3><ul><li><a href="http://railsmagazin.de/video-deployment-mit-webistrano-1272" rel="bookmark">(Video) Deployment mit Webistrano</a></li><li><a href="http://railsmagazin.de/datenbankreplikation-rails-714" rel="bookmark">(Video) Datenbankreplikation &amp; Rails</a></li><li><a href="http://railsmagazin.de/video-rspec-827" rel="bookmark">(Video) RSpec</a></li><li><a href="http://railsmagazin.de/munich-on-rails-ladt-ein-1139" rel="bookmark">Munich-on-Rails l&auml;dt ein!</a></li><li><a href="http://railsmagazin.de/kurz-berichtet-neues-von-saps-blue-ruby-1282" rel="bookmark">Kurz berichtet: Neues von SAPs Blue Ruby</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://railsmagazin.de/video-was-ist-rack-1255/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
<enclosure url="http://dl.dropbox.com/u/28187/RubyMuenchenVideos/MoR-Christian_Neukirchen-Rack-720.mov" length="696830737" type="video/quicktime" />
		</item>
		<item>
		<title>Refactoring von Rails-Anwendungen: Was tun wenn der Laufsteg durchbricht?</title>
		<link>http://railsmagazin.de/refactoring-von-rails-anwendungen-was-tun-wenn-der-laufsteg-durchbricht-450</link>
		<comments>http://railsmagazin.de/refactoring-von-rails-anwendungen-was-tun-wenn-der-laufsteg-durchbricht-450#comments</comments>
		<pubDate>Thu, 12 Mar 2009 22:05:46 +0000</pubDate>
		<dc:creator>Maximilian Schöfmann</dc:creator>
				<category><![CDATA[Entwickler]]></category>
		<category><![CDATA[Tipps]]></category>
		<category><![CDATA[composition]]></category>
		<category><![CDATA[fat model]]></category>
		<category><![CDATA[kate moss]]></category>
		<category><![CDATA[refactoring]]></category>
		<category><![CDATA[skinny controller]]></category>

		<guid isPermaLink="false">http://www.railsmagazin.de/?p=450</guid>
		<description><![CDATA[Bevor ich mit dem eigentlichen Artikel beginne, möchte ich den geneigten Leser bitten, kurz folgenden Befehl im Root-Verzeichnis seiner aktuellen Rails-Anwendung einzugeben:

wc -l app/models/* &#124; sort

Fertig? Ok. Alle Nicht-Windows-User sollten eine hübsche Liste an Zahlen und Dateinamen zurück bekommen haben. Alle Leser, bei denen in den letzten 3 Einträgen der Liste die Datei user.rb auftaucht, [...]]]></description>
			<content:encoded><![CDATA[<p>Bevor ich mit dem eigentlichen Artikel beginne, möchte ich den geneigten Leser bitten, kurz folgenden Befehl im Root-Verzeichnis seiner aktuellen Rails-Anwendung einzugeben:</p>
<pre style="margin-bottom:25px">
wc -l app/models/* | sort
</pre>
<p>Fertig? Ok. Alle Nicht-Windows-User sollten eine hübsche Liste an Zahlen und Dateinamen zurück bekommen haben. Alle Leser, bei denen in den letzten 3 Einträgen der Liste die Datei <tt>user.rb</tt> auftaucht, oder ein Eintrag mindestens vierstellig ist, würde ich bitten diese Zeile in einen Kommentar zu pasten. Danke.</p>
<h2>Warum Kate Moss keine Rails-Entwicklerin wurde</h2>
<p><span id="more-450"></span></p>
<p>Im Lebenszyklus einer Webanwendung werden ständig neue Features entwickelt. Nach dem Credo <a href="http://www.vimeo.com/1050762">&#8220;Skinny Controller</a> &#8211; <a href="weblog.jamisbuck.org/2006/10/18/skinny-controller-fat-model">Fat Model&#8221;</a> wandert die Business-Logik der Features in das Model, und das ist auch richtig so. Für viele Rails-Entwickler ist <em>Model</em> aber gleichbedeutend mit <em>ActiveRecord</em>, und so wachsen diese Klassen oft auf unübersichtliche Größen an. Das <tt>User</tt>-Model ist hier ein besonders populäres Opfer, insbesondere wenn es nicht um ein <tt>Profile</tt>- oder <tt>Person</tt>-Model ergänzt wurde.</p>
<p>Höchste Zeit also für ein wenig Refactoring! Und das geht so:</p>
<h2>Ruby-Lego: Module und Mixins</h2>
<p>Die einfachste Möglichkeit besteht darin, thematisch verwandte Methoden in Modulen zu sammeln und per <tt>include</tt> im Model verfügbar zu machen. Idealerweise werden diese Module dann in einem separeten Namespace gruppiert:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;"># app/models/user.rb</span>
<span style="color:#9966CC; font-weight:bold;">class</span> User <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
  <span style="color:#9966CC; font-weight:bold;">include</span> <span style="color:#6666ff; font-weight:bold;">UserStuff::Admin</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># app/models/user_stuff/admin.rb</span>
<span style="color:#9966CC; font-weight:bold;">module</span> UserStuff
  <span style="color:#9966CC; font-weight:bold;">module</span> Admin
    <span style="color:#9966CC; font-weight:bold;">def</span> schedule_backup
      <span style="color:#008000; font-style:italic;"># ...</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Wird die gleiche Funktionalität von verschiedenen Klassen benötigt, lassen sich solche Mixins bei entsprechendem Design auch wiederverwenden:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;"># app/models/user.rb</span>
<span style="color:#9966CC; font-weight:bold;">class</span> User <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
  <span style="color:#9966CC; font-weight:bold;">include</span> Authentication
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># app/models/api_client.rb</span>
<span style="color:#9966CC; font-weight:bold;">class</span> ApiClient
  <span style="color:#9966CC; font-weight:bold;">include</span> Authentication
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># lib/authentication.rb</span>
<span style="color:#9966CC; font-weight:bold;">module</span> Authentication
  <span style="color:#9966CC; font-weight:bold;">def</span> authenticate<span style="color:#006600; font-weight:bold;">&#40;</span>credentials<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#008000; font-style:italic;"># authenticate via ldap, kerberos etc.</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<h2>Der Unterschied zwischen Klassen in Ruby und Postschaltern zur Mittagszeit</h2>
<p>Als Alternative zu Modulen, lässt sich der Umstand ausnutzen, dass Klassen in Ruby immer offen sind. Es können jederzeit weitere Methoden hinzugefügt werden, wodurch sich lange Klassendefinitionen einfach aufzusplitten lassen um sie in separaten Dateien abzulegen:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;"># app/models/user.rb</span>
<span style="color:#9966CC; font-weight:bold;">class</span> User <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> name
    <span style="color:#996600;">&quot;#{first_name} #{last_name}&quot;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
require_dependency <span style="color:#996600;">'user/admin'</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># app/models/user/admin.rb</span>
<span style="color:#9966CC; font-weight:bold;">class</span> User <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> schedule_backup
    <span style="color:#008000; font-style:italic;"># ...</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Jake Howerton hat dieses Muster in seinem (ganze 7 LOC umfassenden) Gem, <a href="http://github.com/jakehow/concerned_with">concerned_with</a>, mit etwas syntaktischem Zucker versehen:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> User <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
  concerned_with <span style="color:#ff3333; font-weight:bold;">:admin</span>, <span style="color:#ff3333; font-weight:bold;">:validations</span>, ... 
  <span style="color:#008000; font-style:italic;"># ...</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Hier werden automatisch die Dateien <tt>app/models/user/admin.rb</tt> und <tt>app/models/user/validations.rb</tt> geladen.</p>
<h2>Kosmetik für Models</h2>
<p>Sowohl Module als auch &#8220;concerned_with&#8221; haben leider einen gravierenden Nachteil: Es ist meist reine Kosmetik. Die Methoden werden lediglich in eine andere Datei verschoben, verschmutzen aber weiterhin den Namensraum der ursprünglichen Klasse. Werden Methoden der Urprungsklasse überschrieben, gibt es auch keine einfache Möglichkeit auf die Originalimplementierung zurückzugreifen. Allein die Lösung mit Modulen lässt zumindest zu, eine von der Klasse überschriebene, aber in einem Modul definierte Methode mittels <tt>super</tt> zu referenzieren. In der Regel ist aber eher der umgekehrte Fall erwünscht, nämlich die Methode der Klasse zu überschreiben. Zudem führt ein solches Vorgehen zu einer unschönen Kopplung von Modul und Klasse &#8211; die Methode der Klasse muß von der Existenz des Moduls wissen.</p>
<p>Ein weitaus größerer Nachteil ist jedoch, dass die Methoden selbst dafür sorgen müssen, nie im falschen Kontext aufgerufen zu werden. Im obigen Beispiel würde dies vermutlich wie folgt aussehen:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> schedule_backup
  <span style="color:#CC0066; font-weight:bold;">raise</span> <span style="color:#996600;">&quot;Security Error!&quot;</span> <span style="color:#9966CC; font-weight:bold;">unless</span> has_role?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:admin</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#008000; font-style:italic;">#...</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Die Methode muß sich hier unnötigerweise mit administrativer Logik herumschlagen, die nichts zu ihrem eigentlich Auftrag, dem Anstoßen eines Backups, beiträgt. Möchte man nicht auch noch Aspektorientierung aus der Trickkiste hervorholen, müsste der entsprechende Code zudem in jeder verwandten Methode dupliziert werden &#8211; ein klarer Verstoß des in Rails heiligen <a href="http://de.wikipedia.org/wiki/DRY">DRY-Prinzips</a>.</p>
<p>Zur Verteidigung von &#8220;concerned_with&#8221; darf nicht unerwähnt bleiben, dass das kanonische Beispiel für dieses Gem die Auslagerung von Validations und ähnlichem ist. Für solche Zwecke ist es bei komplexen Klassen durchaus nützlich.</p>
<h2>Erbschaften sind immer willkommen!</h2>
<p>Eine klassische, objektorientierte Herangehensweise an solche Probleme ist ohne Zweifel Vererbung:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;"># app/models/user.rb</span>
<span style="color:#9966CC; font-weight:bold;">class</span> User <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> name
    <span style="color:#996600;">&quot;#{first_name} #{last_name}&quot;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># app/models/admin.rb</span>
<span style="color:#9966CC; font-weight:bold;">class</span> Admin <span style="color:#006600; font-weight:bold;">&lt;</span> User
  <span style="color:#9966CC; font-weight:bold;">def</span> schedule_backup
    <span style="color:#008000; font-style:italic;"># ...</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Durch diesen Ansatz wird sichergestellt, dass jedes Objekt nur die Methoden besitzt, die es auch besitzen darf. Zusätzliche Prüfungen im Code, wie im obigen Beispiel, sind daher nicht notwenig. Aus überschriebenen Methoden in <tt>Admin</tt> lässt sich auch einfach per <tt>super</tt> die gleichnamige Originalmethode in <tt>User</tt> aufrufen.</p>
<p>Rails unterstützt Vererbung in ActiveRecord-Models sehr bequem mittels STI (<a href="http://martinfowler.com/eaaCatalog/singleTableInheritance.html">Single Table Inheritance</a>) durch Hinzufügen einer <tt>type</tt>-Spalte zur jeweiligen Tabelle.<br />
Dieser Ansatz ist aber nur sinnvoll, wenn tatsächlich eine &#8220;is_a&#8221;-Beziehung vorliegt. Er funktioniert auch nur 1x pro Klasse, da Ruby keine direkte, mehrfache Vererbung erlaubt. Letzteres lässt sich in manchen Fällen durch <a href="http://java.sun.com/j2se/1.5.0/docs/api/overview-tree.html">komplexe Vererbungshierarchien</a> abbilden, aber unnötige Komplexität ist ja gerade das, was wir mit Ruby vermeiden wollen.</p>
<h2>&#8220;Das Ganze ist mehr als die Summe seiner Teile&#8221;</h2>
<p>Entscheidend für ein gelungenes Refactoring ist oft die Erkenntnis dass der bestehende Code nicht mehr hinreichend die Realität abbildet.<br />
Dinge in der realen Welt bestehen immer aus anderen Dingen, die wiederum aus weiteren Dingen bestehen.<br />
Solche Beziehungen werden in Rails üblicherweise durch die gängigen Assoziationsmakros <tt>has_many</tt>, <tt>has_one</tt> usw. implementiert. Diese Makros eignen sich jedoch nur für persistente ActiveRecord-Objekte. Da der gemeine Rails-Entwickler an sich eher faul ist, ignoriert er mangels bequemer Makros gerne die Tatsache, dass nicht alle Teile einer solchen <em>Composition</em> persistent sein müssen.</p>
<p>Jamis Buck hat im <a href="http://www.37signals.com/svn/posts/1553-models-vs-modules">Blog von 37signals ein sehr schönes Beispiel</a> veröffentlicht, wie er vormalig im <tt>User</tt>-Model definierte Methoden zur Manipulation von Avataren in eine eigene, nicht persistente, <tt>Avatar</tt>-Klasse auslagern konnte. Im obigen Beispiel würde sich diese Lösung wie folgt gestalten:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;"># app/models/user.rb</span>
<span style="color:#9966CC; font-weight:bold;">class</span> User <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
  <span style="color:#008000; font-style:italic;"># ...</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> admin
    <span style="color:#0066ff; font-weight:bold;">@admin</span> <span style="color:#006600; font-weight:bold;">||</span>= AdminCapability.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF; font-weight:bold;">self</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">if</span> has_role?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:admin</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># app/models/admin_capability.rb</span>
<span style="color:#9966CC; font-weight:bold;">class</span> AdminCapability
  <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span>user<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@user</span> = user
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> schedule_backup
    <span style="color:#008000; font-style:italic;"># ...</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#008000; font-style:italic;"># ...</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Um dem ganzen mehr Composition-Character zu verleihen, sind administrative Methoden jetzt in der <tt>AdminCapability</tt>-Klasse untergebracht. Aufgerufen werden sie wie folgt: <tt>user.admin.schedule_backup</tt>. Der Vorteil gegenüber der Lösung mit Vererbung liegt auf der Hand: Wir können beliebig weitere Capabilities erfinden und sauber vom Code der User-Klasse getrennt implementieren.</p>
<p>Für komplexere Szenarion bietet ActiveRecord im <a href="http://api.rubyonrails.org/classes/ActiveRecord/Aggregations/ClassMethods.html">Aggregations-Modul das <tt>composed_of</tt>-Makro</a>. Zweck von Aggregations ist es hauptsächlich <a href="http://c2.com/cgi/wiki?ValueObject">Value-Objects</a> abzubilden. Für den Anwendungsfall, &#8220;Avatar&#8221;, von Jamis Buck wäre es also durchaus ebenso geeignet.<br />
Ein weiteres, beliebtes Beispiel sind Adressen: Möchte man, z.B. aus Performance-Gründen, keine separate <tt>addresses</tt>-Tabelle, können die Felder in der <tt>users</tt>-Tabelle angelegt und mittels <tt>composed_of</tt> als <tt>Address</tt>-Objekt zur Verfügung gestellt werden. Die <tt>Address</tt>-Klasse selbst kann dann komplexe Methoden &#8211; etwa <a href="http://railsmagazin.de/geokit-rails-und-google-maps-teil-1-552">Geocoding</a> &#8211; implementieren.</p>
<h2>Verlängerte Beziehung</h2>
<p>Beziehungen zwischen Klassen benötigen häufig Funktionalität die in Beziehung stehenden Objekte zu manipulieren oder zu verwalten. Die gängigsten Operationen, wie das erzeugen, löschen oder finden assoziierter Objekte, werden durch die Association-Makros (<tt>has_many</tt> etc.) bereits zur Verfügung gestellt:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">user = User.<span style="color:#9900CC;">first</span>
user.<span style="color:#9900CC;">addresses</span>.<span style="color:#9900CC;">create</span> <span style="color:#ff3333; font-weight:bold;">:street</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;Musterstr. 2&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:city</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;München&quot;</span>
user.<span style="color:#9900CC;">addresses</span>.<span style="color:#9900CC;">destroy_all</span></pre></div></div>

<p>Funktionen die darüber hinausgehen und selbst implementiert werden müssen, landen allzuoft einfach in der Klasse selbst, bei unseren Codebeispielen war dies etwa <tt>has_role?</tt>.<br />
Dabei bietet ActiveRecord eine sehr saubere Möglichkeit diese assoziationsspezifische Logik zu kapseln: <em>Association Extensions</em>.</p>
<p>Solche Extensions können entweder als Blockparameter des Assoziationsmakros, oder in eigenständigen Modulen implementiert sein. In unserem Beispiel sähe dies so aus:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;"># app/models/user.rb</span>
<span style="color:#9966CC; font-weight:bold;">class</span> User <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
  has_and_belongs_to_many <span style="color:#ff3333; font-weight:bold;">:roles</span>, <span style="color:#ff3333; font-weight:bold;">:extend</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> RoleManagement
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># app/models/role_management.rb</span>
<span style="color:#9966CC; font-weight:bold;">module</span> RoleManagement
  <span style="color:#9966CC; font-weight:bold;">def</span> got?<span style="color:#006600; font-weight:bold;">&#40;</span>role_name<span style="color:#006600; font-weight:bold;">&#41;</span>
    exists? <span style="color:#ff3333; font-weight:bold;">:name</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> role_name.<span style="color:#9900CC;">to_s</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Anstatt <tt>user.has_role?(:admin)</tt> kann das Vorhandensein der Rolle nun mit <tt>user.roles.got?(:admin)</tt> geprüft werden.</p>
<h2>Automatische Beziehungsverlängerung</h2>
<p>Mit einem kleinen Griff in die Metaprogrammierungs-Trickkiste lässt sich aber noch mehr erreichen. In unserem Beispiel gibt es sowohl eine Rolle namens &#8220;admin&#8221;, als auch eine Klasse, zuletzte <tt>AdminCapability</tt> genannt, die die dazugehörige Business-Logik implementiert.</p>
<p>Wäre es nicht nett wenn je nach zugewiesenen Rollen automatisch die entsprechenden <tt>Capability</tt>-Objekte zur Verfügung stünden? </p>
<p>Um es kurz zu machen: Ja &#8211; das wäre nett! Und so gehts:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;"># app/models/role_management.rb</span>
<span style="color:#9966CC; font-weight:bold;">module</span> RoleManagement
  <span style="color:#9966CC; font-weight:bold;">def</span> method_missing<span style="color:#006600; font-weight:bold;">&#40;</span>method, <span style="color:#006600; font-weight:bold;">*</span>args<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@capabilities</span> <span style="color:#006600; font-weight:bold;">||</span>= <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span>
    <span style="color:#0066ff; font-weight:bold;">@capabilities</span><span style="color:#006600; font-weight:bold;">&#91;</span>method<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">||</span>= <span style="color:#9966CC; font-weight:bold;">begin</span>
      <span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#9966CC; font-weight:bold;">super</span> <span style="color:#9966CC; font-weight:bold;">if</span> method.<span style="color:#9900CC;">to_s</span> == <span style="color:#996600;">'exists?'</span> <span style="color:#006600; font-weight:bold;">||</span> !exists?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:name</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> method.<span style="color:#9900CC;">to_s</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#996600;">&quot;#{method.to_s.camelize}Capability&quot;</span>.<span style="color:#9900CC;">constantize</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>proxy_owner<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p><tt>method_missing</tt> sorgt hier dafür dass falls der <tt>proxy_owner</tt>, also hier der User, über die gegebene Rolle verfügt, <tt>exists?(:name => method.to_s)</tt>, ein entsprechendes Capability-Objekt erzeugt wird. Wurde es bereits erzeugt und im <tt>@capabilities</tt>-Hash abgelegt, wird einfach dieses zurückgegeben.<br />
Andernfalls wird mittels <tt>super</tt> die nächste Implementierung von <tt>method_missing</tt> aufgerufen. Dies ist wichtig, da die Association-Proxies von ActiveRecord selbst sehr viel mit <tt>method_missing</tt> arbeiten: Z.B. wird auch der Aufruf von <tt>exists?</tt> über diesen Mechanismus abgefangen, daher muß er hier explizit behandelt werden.</p>
<p>Angenommen wir fügen jetzt noch eine Rolle &#8220;author&#8221; und die dazugehörige Klasse <tt>AuthorCapability</tt> ein, lässt sich diese neue API wie folgt nutzen:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">user.<span style="color:#9900CC;">roles</span>.<span style="color:#9900CC;">admin</span>.<span style="color:#9900CC;">schedule_backup</span>  <span style="color:#008000; font-style:italic;">#=&gt; ...</span>
user.<span style="color:#9900CC;">roles</span>.<span style="color:#9900CC;">author</span>                 <span style="color:#008000; font-style:italic;">#=&gt; NoMethodError: undefined method author...</span>
user.<span style="color:#9900CC;">roles</span> <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> Role.<span style="color:#9900CC;">find_by_name</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;author&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
user.<span style="color:#9900CC;">roles</span>.<span style="color:#9900CC;">author</span>                 <span style="color:#008000; font-style:italic;">#=&gt; #&lt;AuthorCapability:0x22384d8&gt;</span>
user.<span style="color:#9900CC;">roles</span>.<span style="color:#9900CC;">author</span>.<span style="color:#9900CC;">publish_post</span>!   <span style="color:#008000; font-style:italic;">#=&gt; ...</span></pre></div></div>

<h2>Kommen wir endlich zum Schluß</h2>
<p>Ich hoffe, ich konnte in diesem Artikel zeigen, dass Models nicht zwingend an Übergewicht leiden müssen. Auch wenn es vielleicht nicht für Heidi Klums Show reicht, so können unsere Models mit der Modul-Diät, der concerned_with-Kur, der Composition-Diät oder der Association-Extension-Formel genug überflüssige Pfunde verlieren um eine erfolgreiche Karriere auf den virtuellen Laufstegen des Webs machen.</p>
<div id="crp_related"><h3>Ähnliche Artikel</h3><ul><li><a href="http://railsmagazin.de/schema-f-1419" rel="bookmark">Schema F</a></li><li><a href="http://railsmagazin.de/cursors_in_rails-214" rel="bookmark">(Fake-) Cursors f&uuml;r ActiveRecord (Rails 2.3)</a></li><li><a href="http://railsmagazin.de/domanenspezifische-sprachen-und-ruby-422" rel="bookmark">Dom&auml;nenspezifische Sprachen und Ruby</a></li><li><a href="http://railsmagazin.de/excellent-statische-analyse-fur-ruby-und-rails-1444" rel="bookmark">Excellent - Statische Code Analyse f&uuml;r Ruby und Rails</a></li><li><a href="http://railsmagazin.de/ruby-user-group-munchen-%e2%80%94-juli-treffen-1513" rel="bookmark">Ruby User Group M&uuml;nchen &mdash; Juli-Treffen</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://railsmagazin.de/refactoring-von-rails-anwendungen-was-tun-wenn-der-laufsteg-durchbricht-450/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Prim(a) Lösungen in Ruby</title>
		<link>http://railsmagazin.de/prima-losungen-in-ruby-490</link>
		<comments>http://railsmagazin.de/prima-losungen-in-ruby-490#comments</comments>
		<pubDate>Tue, 03 Mar 2009 23:01:59 +0000</pubDate>
		<dc:creator>Bernhard Fuchs</dc:creator>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[Entwickler]]></category>
		<category><![CDATA[Neues in Rails]]></category>
		<category><![CDATA[Lernen]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://www.railsmagazin.de/?p=490</guid>
		<description><![CDATA[Als Neueinsteiger einer Programmiersprache sollte man sich bekannte Probleme suchen, die man schon in früheren Sprachen gelöst hat und diese umsetzen. Bei allen meinen früheren Schwenks zu den diversesten Sprachen war hier das große Wehklagen vorprogrammiert. Nicht so bei Ruby. 
Die Freiheit in der Syntax half sehr zu einem schnellen Ergebnis zu kommen und das [...]]]></description>
			<content:encoded><![CDATA[<p>Als <strong>Neueinsteiger</strong> einer Programmiersprache sollte man sich bekannte Probleme suchen, die man schon in früheren Sprachen gelöst hat und diese umsetzen. Bei allen meinen früheren Schwenks zu den diversesten Sprachen war hier das große <strong>Wehklagen</strong> vorprogrammiert. <strong>Nicht so bei Ruby.</strong> </p>
<p>Die Freiheit in der Syntax half sehr zu einem schnellen Ergebnis zu kommen und das bewegte mich dazu zu recherchieren, wie denn andere Entwickler mit deren Background an die Sache rangehen. Resultat waren einige interessante Konstrukte deren Performance ganz unterschiedlich ist. </p>
<p><span id="more-490"></span></p>
<p>Vorab möchte ich den/die Leser/in bitten, sich nicht auf den Schlips getreten zu fühlen, falls er/sie sich in Syntax oder Semantik der ausgegrabenen Beispiele wiedererkennen sollte. Die Klassifizierung der Beispiele in <strong>&#8220;Entwicklertypen&#8221;</strong> ist lediglich humorvoll gemeint. Im Prinzip kann jeder auf jede der Lösungen kommen, bis auf eine vielleicht und ich meine nicht meine. <img src='http://railsmagazin.de/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  </p>
<p>Das Problem, dass ich am liebsten in neue Sprachen umsetze sind <a href="http://de.wikipedia.org/wiki/primzahl">Primzahlen</a>. Die einfachste Möglichkeit hierbei ist es von <strong>2</strong> bis <strong>max</strong> zu interieren und dabei <strong>jede</strong> Zahl zu prüfen ob von <strong>2</strong> bis <strong>sqrt(max)</strong> die <strong>Modulooperation 0</strong> ergibt. Das ist jedoch nicht die beste. Der griechische Mathematiker <a href="http://de.wikipedia.org/wiki/Eratosthenes">Eratosthenes von Kyrene</a> hatte sich hierbei ein <a href="http://de.wikipedia.org/wiki/Sieb_des_Eratosthenes">&#8220;Sieb&#8221;</a> ausgedacht, was im Prinzip ein <strong>Array</strong> darstellt in dem alle <strong>Vielfachen</strong> einer Zahl gestrichen werden. Dieser Alorithmus stellt demnach auch die Standardimplementierung im Schulungsbereich dar, da man sie einfach visualisieren kann.</p>
<p>Doch wie stellen sich die Umsetzung nun Entwickler vor? Da hätten wir als erstes mal den</p>
<p><strong>C-Programmierer</strong></p>
<p>Er denkt kompakt und liebt kurze Variablennamen. Sein einziger Gedanke gilt der optimalen Speicherauslastung bei maximaler Effizienz. So könnte seine Lösung aussehen:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> prim_cway<span style="color:#006600; font-weight:bold;">&#40;</span>max<span style="color:#006600; font-weight:bold;">&#41;</span>
  i=l=<span style="color:#006666;">1</span>
  <span style="color:#9966CC; font-weight:bold;">while</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#40;</span>l<span style="color:#006600; font-weight:bold;">*</span>=i<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&amp;&amp;</span> <span style="color:#006600; font-weight:bold;">&#40;</span>i<span style="color:#006600; font-weight:bold;">&lt;</span>max<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#40;</span>l<span style="color:#006600; font-weight:bold;">%</span>i<span style="color:#006600; font-weight:bold;">+</span>=<span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&gt;</span>i<span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">2</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">then</span>
      <span style="color:#CC0066; font-weight:bold;">printf</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;%d &quot;</span>,i<span style="color:#006600; font-weight:bold;">&#41;</span>;
    <span style="color:#9966CC; font-weight:bold;">end</span> 
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p>Natürlich hätte man sich hier auch an das Sieb halten können, aber die Primzahlen sollen ja möglichst schnell berechnet werden und ausserdem liegt Tosthi hier völlig falsch, da er ja noch nicht auf embedded Prozessoren hacken musste und Doppelschleifen sowieso saugen. <img src='http://railsmagazin.de/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Aber wie funktioniert der Code nun in nur einer Schleife? <strong>l</strong> wird pro Durchlauf immer um <strong>i</strong> vervielfacht. In der if-Anweisung erfolgt die Erhöung von <strong>i</strong> um 1 allerdings noch <strong>bevor</strong> das Modulo ausgeführt wird, weil Zuweisungen in Operationen vorgezogen werden. Das Ergebnis ist also nicht größer als <strong>i-1</strong>. Handelt es sich bei <strong>i</strong> um eine Primzahl, so wird <strong>l % (i+1) = 0</strong> werden und ist somit <strong>kleiner als i-2</strong>. Im Prinzip könnte man auch hier auf 0 vergleichen, jedoch würden dann die 1 und 2 mit ausgegeben, die eine Ausnahme bilden. Diese Lösung implementiert übrigens die sogenannte <a href="http://de.wikipedia.org/wiki/Primzahl#Lineare_Rekursionen">Lineare Rekursion</a> basierend auf dem <a href="http://de.wikipedia.org/wiki/Kleiner_Fermatscher_Satz">kleinen Satz des Fermat</a>. Aber lasst uns die Franzosen bei Seite schieben und wieder zurück zu unserem Griechen kommen. </p>
<p><strong>Der Java-Programmierer</strong> wird sich hier eher am Sieb orientieren und vorhandene Klassen und Methoden genauer betrachten und auch einsetzen.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> prim_erat1<span style="color:#006600; font-weight:bold;">&#40;</span>limit<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#9966CC; font-weight:bold;">if</span> limit <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#006666;">2</span>
&nbsp;
  length = <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#40;</span>limit<span style="color:#006600; font-weight:bold;">/</span><span style="color:#006666;">2</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span> <span style="color:#006600; font-weight:bold;">+</span> limit<span style="color:#006600; font-weight:bold;">%</span>2<span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
  sieve = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#0000FF; font-weight:bold;">true</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">*</span> <span style="color:#006600; font-weight:bold;">&#40;</span>length<span style="color:#006600; font-weight:bold;">+</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
  0.<span style="color:#9900CC;">upto</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC00FF; font-weight:bold;">Math</span>.<span style="color:#9900CC;">sqrt</span><span style="color:#006600; font-weight:bold;">&#40;</span>limit<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">to_i</span> <span style="color:#006600; font-weight:bold;">&gt;&gt;</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>i<span style="color:#006600; font-weight:bold;">|</span>
    <span style="color:#9966CC; font-weight:bold;">next</span> <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#9966CC; font-weight:bold;">not</span> sieve<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span>
&nbsp;
    <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#40;</span>i<span style="color:#006600; font-weight:bold;">*</span><span style="color:#006600; font-weight:bold;">&#40;</span>i<span style="color:#006600; font-weight:bold;">+</span><span style="color:#006666;">3</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">3</span><span style="color:#006600; font-weight:bold;">&#41;</span>...<span style="color:#9900CC;">length</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">step</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#40;</span>i <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">3</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>j<span style="color:#006600; font-weight:bold;">|</span>
      sieve<span style="color:#006600; font-weight:bold;">&#91;</span>j<span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#0000FF; font-weight:bold;">false</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  primes = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">2</span><span style="color:#006600; font-weight:bold;">&#93;</span>
&nbsp;
  0.<span style="color:#9900CC;">upto</span><span style="color:#006600; font-weight:bold;">&#40;</span>length<span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>i<span style="color:#006600; font-weight:bold;">|</span>
    primes <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> <span style="color:#006600; font-weight:bold;">&#40;</span>i <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">+</span><span style="color:#006666;">3</span> <span style="color:#9966CC; font-weight:bold;">if</span> sieve<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  primes
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p>Die Vorgehensweise hier ist erst einmal ein <strong>Array</strong> mit <strong>&#8220;max&#8221;</strong> Keys mit <strong>true-Werten</strong> zu füllen. In der Schleife werden mit einer weiteren <strong>inneren Schleife</strong> durch die Benutzung von <em><strong>step</strong></em> die <strong>Vielfachen</strong> ausradiert und anschliessend befüllt man das Ergebnisarray mit den Zahlen für denen die true-Werte im Siebarray <strong>übrig</strong> geblieben sind.  Diese Version ist wesentlich umfangreicher als die des C-Programmierers, jedoch versteht man die Logik eher. </p>
<p>Wobei wir auch schon beim <strong>PHP-Programmierer</strong> ankommen</p>
<p>Er denkt ähnlich wie der Java-Programmierer, wobei er es nicht so mit komplexen Iteratoren hat. Da man ihn jedoch bei Ruby seiner geliebten C-ähnlichen for-Schleife beraubt hat, muss er sich wohl oder übel mit <em><strong>step</strong></em> auseinandersetzen, was er jedoch schnell intus hat.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> prim_erat2<span style="color:#006600; font-weight:bold;">&#40;</span>max<span style="color:#006600; font-weight:bold;">&#41;</span>
  sieve = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">for</span> i <span style="color:#9966CC; font-weight:bold;">in</span> <span style="color:#006666;">2</span> .. <span style="color:#9900CC;">max</span>
    sieve<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span> = i
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">for</span> i <span style="color:#9966CC; font-weight:bold;">in</span> <span style="color:#006666;">2</span> .. <span style="color:#CC00FF; font-weight:bold;">Math</span>.<span style="color:#9900CC;">sqrt</span><span style="color:#006600; font-weight:bold;">&#40;</span>max<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">next</span> <span style="color:#9966CC; font-weight:bold;">unless</span> sieve<span style="color:#006600; font-weight:bold;">&#91;</span>i<span style="color:#006600; font-weight:bold;">&#93;</span>       
&nbsp;
    <span style="color:#006600; font-weight:bold;">&#40;</span>i<span style="color:#006600; font-weight:bold;">*</span>i<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">step</span><span style="color:#006600; font-weight:bold;">&#40;</span>max, i<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>j<span style="color:#006600; font-weight:bold;">|</span>
      sieve<span style="color:#006600; font-weight:bold;">&#91;</span>j<span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#0000FF; font-weight:bold;">nil</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
  sieve.<span style="color:#9900CC;">compact</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p>Auch diese Lösung implementiert das Sieb wie es ursprünglich gedacht war. Nur wird hier direkt auf dem Array operiert, das <strong>alle</strong> Zahlen bis <strong>max</strong> enthält. Gestrichene Werte werden durch <em><strong>nil</strong></em> ausradiert und das Array wird anschliessend wieder komprimiert. </p>
<p><strong>Objective-C</strong></p>
<p>Der Homo Sapiens Cocoaensis, auch Objective C Mensch genannt, ist es gewöhnt C mit funktionalen Elementen zu mischen und dabei mehr drauf zu achten, dass man große Teile des Algorithmus möglichst singen kann. Die Performance wird erst nachträglich über Tools wie XCode Instruments angepasst.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> prim_asearch<span style="color:#006600; font-weight:bold;">&#40;</span>max<span style="color:#006600; font-weight:bold;">&#41;</span> 
  a=<span style="color:#CC0066; font-weight:bold;">Array</span>.<span style="color:#9900CC;">new</span>
  <span style="color:#9966CC; font-weight:bold;">for</span> i <span style="color:#9966CC; font-weight:bold;">in</span> 2..<span style="color:#9900CC;">max</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    a <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> i <span style="color:#9966CC; font-weight:bold;">unless</span> <span style="color:#006600; font-weight:bold;">&#40;</span>2..<span style="color:#9900CC;">i</span><span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">find</span> <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">|</span>j<span style="color:#006600; font-weight:bold;">|</span> i <span style="color:#006600; font-weight:bold;">%</span> j == <span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#125;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
  a
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p>Ganz brutal werden hier mittles der <em><strong>find</strong></em> Methode für jede Zahl <strong>i</strong> zwischen <strong>2 und max</strong> die Werte über ein <strong>anonymes Array</strong> mit dem <strong>Blockiterator j</strong> gefunden, für die <strong>i modulo j gleich 0</strong> zutrifft. Es funktioniert, jedoch ist die Performanz suboptimal. </p>
<p><strong>Smalltalk</strong></p>
<p>Der Smalltalk Typus liebt es untypisiert und objektorientiert und packt das ganze am liebsten in eine Zeile. Er steht in der Evolutionsstufe noch über dem Objective-C Menschen. Dabei ist es ihm sogar egal, ob er selbst den Code noch lesen kann und singen wird er ihn gleich zweimal nicht. Es stellt eher eine Art Gebet dar.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> prim_inject<span style="color:#006600; font-weight:bold;">&#40;</span>max<span style="color:#006600; font-weight:bold;">&#41;</span> 
  <span style="color:#006600; font-weight:bold;">&#40;</span>2..<span style="color:#9900CC;">max</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">inject</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#40;</span>2..<span style="color:#9900CC;">max</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">to_a</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">|</span>res, i<span style="color:#006600; font-weight:bold;">|</span> res.<span style="color:#CC0066; font-weight:bold;">select</span><span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">|</span>n<span style="color:#006600; font-weight:bold;">|</span>n==i<span style="color:#006600; font-weight:bold;">||</span>n<span style="color:#006600; font-weight:bold;">%</span>i!=<span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p>Hier muss man zweimal hinschauen um zu verstehen was passiert. Das <em><strong>inject</strong></em> erhält als <strong>Initialwert ein Array</strong> mit der gleichen Range. Im Block ist nun jeder <strong>Memowert</strong> gleich dem <strong>Array</strong>. Aus diesem werden alle Werte <strong>selektiert</strong> für die der Ausdruck im Bock <em><strong>false</strong></em> ergibt. Hier verwirren die vielen <strong>Pipes</strong> etwas. Das <em><strong>|n</strong></em>| ist schlicht der <strong>Blockiterator</strong> und die zwei Pipes in der Mitte stellen eine <strong>oder-Verküpfung</strong> dar. Das <em><strong>select</strong></em> liefert einen Wert zurück, wenn der Ausdruck <em><strong>true</strong></em> ergibt. Dies trifft zu, wenn der <strong>Iterator <em>i</em></strong> gleich dem Iterator <strong>n</strong> oder <strong>n modulo i ungleich 0</strong> ist also für die Fälle dass die <strong>&#8220;innere&#8221; Schleife</strong> durchlaufen ist oder der innere Schleifenwert <strong>modulo</strong> äusserer Schleifenwert über einen <strong>Teilerrest</strong> verfügen. </p>
<p>Sehr ineffizent in diesem Beispiel ist die Tatsache, dass hier der Initalwert des <em><strong>injects</strong></em> als Schleife missbraucht wird und dieser dann auch  im <strong>memo-Tei</strong>l des Blocks landet. Wie bei allen Lösungen mit Doppelschleifen steigert sich die Laufzeit proportional zu der Range. Bei dieser Funktion ist es jedoch noch schlimmer, da hier ganze Arrays als Parameter übergeben werden was auch sehr schnell zu einem Stackproblem führen wird. </p>
<p>Dass es noch kryptischer und lastreicher gehen kann soll uns das letzte Exempel zeigen.</p>
<p><strong>Der Perl-Programmierer</strong></p>
<p>Er ist der Meister der Skripte wenn es um das schnelle Verarbeiten von Listen, Texten geht, ganz gleich welchem Format sie auch ganz oder teilweise unterliegen mögen. Er kann das weil er das mächtigste Werkzeug aller sein Eigen nennt: den regulären Ausdruck. Diese Genies der Musterkennung bestehen den Turingtest mit Leichtigkeit und es gibt nichts was man damit nicht lösen kann. Nicht einmal das Finden von Primzahlen. Das glauben Sie nicht? Dann sehen und staunen Sie:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> prim_regex<span style="color:#006600; font-weight:bold;">&#40;</span>max<span style="color:#006600; font-weight:bold;">&#41;</span>
  a=<span style="color:#CC0066; font-weight:bold;">Array</span>.<span style="color:#9900CC;">new</span>
  2.<span style="color:#9900CC;">upto</span><span style="color:#006600; font-weight:bold;">&#40;</span>max<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>n<span style="color:#006600; font-weight:bold;">|</span> 
    a <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> n <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;1&quot;</span> <span style="color:#006600; font-weight:bold;">*</span> n<span style="color:#006600; font-weight:bold;">&#41;</span> !~ <span style="color:#006600; font-weight:bold;">/</span>^<span style="color:#006666;">1</span>?$<span style="color:#006600; font-weight:bold;">|</span>^<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">11</span><span style="color:#006600; font-weight:bold;">+</span>?<span style="color:#006600; font-weight:bold;">&#41;</span>\<span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">+</span>$<span style="color:#006600; font-weight:bold;">/</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
  a  
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p>Obiges ist zugegebenermassen die nerdigste Umsetzung des Siebs und auch die langsamste. Die Regular Expression macht sich hier die Möglichkeit des <strong>Backreferencing</strong> zu eigen. Erst wird ein String mit einer Anzahl von <strong>Einsen</strong> erzeugt, die dem momentanen <strong>Interatorwert n</strong> entspricht. Die RegEx matcht <strong>links</strong> wenn der String leer ist oder eine 1 enthält. In diesem Fall handelt es sich nicht um eine Primzahl (weil !~ den Match negiert). Jetzt kommt der <strong>zweite Teil</strong>. Der Teil in den Klammern prüft erst ob <strong>&#8220;11&#8243;+?</strong> matcht. Das ist der Fall und es wird <strong>&#8220;11&#8243; in die Backrefvariable \1</strong> geschrieben. Dort wird jetzt geschaut ob <strong>&#8220;11&#8243;+</strong>, also ein oder mehrere Vorkommnisse den String matchen. Ist das nicht der  Fall. Dann wird <strong>nochmal der gesamte Rechte Teil</strong> geprüft, wobei jetzt der Klammernteil <strong>mit &#8220;111&#8243;+?</strong> matchen muss (was er <strong>immer</strong> tut, weil <strong>ganz oder gar</strong> nicht gegeben ist) und der hintere Teil mit <strong>&#8220;111&#8243;+</strong>. Dadurch erreicht man die Prüfung auf Vielfache und somit die Umsetzung des Siebs, wenn auch auf Kosten von sehr langen Ausführungszeiten. </p>
<p><strong>Benchmarks</strong></p>
<p>Führt man nun einen Bechmarktest aus und vergleicht die Laufzeiten, so kommt man sehr schnell zu einem Schluss. Alle Varianten, die zwei verschachtelte Schleifen benötigen sind der korrekten Umsetzung des Siebs, also der wirklichen Bereinigung eines Arrays weit unterlegen. Am stärksten schlägt hier die <strong>Injectionmethode</strong> zu buche. Sie wird nur noch von der <strong>RegEx-Variante</strong> getoppt, wobei man die nicht wirklich ernsthaft ins Rennen schicken darf, da die Ausführgeschwindigkeit stark von der Implementierungsart ihres Algorithmuses abhängt. Die <strong>&#8220;C-Variante&#8221;</strong> ist nur deshalb so schnell, weil sie nicht das Sieb implementiert wird aber wegen des exponentiellen Anstiegs des Dividenden schnell zum Überlauf führen. <strong>asrc</strong> und <strong>inj</strong> haben zusätzlich zu den vielen Arrayoperationen das Problem eines teueren Modulos auf das <strong>er1</strong> und <strong>er2</strong> gewinnbringend verzichten konnten.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="" style="font-family:monospace;">           user     system      total        real
reg    <span style="">3.070000</span>   <span style="">0.260000</span>   <span style="">3.330000</span> <span class="br0">&#40;</span>  <span style="">3.354881</span><span class="br0">&#41;</span>
er1    <span style="">0.000000</span>   <span style="">0.000000</span>   <span style="">0.000000</span> <span class="br0">&#40;</span>  <span style="">0.002403</span><span class="br0">&#41;</span>
er2    <span style="">0.000000</span>   <span style="">0.000000</span>   <span style="">0.000000</span> <span class="br0">&#40;</span>  <span style="">0.004381</span><span class="br0">&#41;</span>
c      <span style="">0.240000</span>   <span style="">0.000000</span>   <span style="">0.240000</span> <span class="br0">&#40;</span>  <span style="">0.244020</span><span class="br0">&#41;</span>
asrc   <span style="">0.910000</span>   <span style="">0.000000</span>   <span style="">0.910000</span> <span class="br0">&#40;</span>  <span style="">0.929468</span><span class="br0">&#41;</span>
inj    <span style="">2.320000</span>   <span style="">0.020000</span>   <span style="">2.340000</span> <span class="br0">&#40;</span>  <span style="">2.362957</span><span class="br0">&#41;</span></pre></td></tr></table></div>

<p><strong>Meine Lösung</strong></p>
<p>Wenn der/die Leser/in jetzt ein Glanzstück an Effizienz und Geschwindigkeit erwartet, so muss ich ihn/sie leider enttäuschen. Über das schon zu oft benannte weil synonymlose Sieb des Eratosthenes habe ich mir einfach zu oft den Kopf zerbrochen. Daher wird genommen was man geboten bekommt.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'mathn'</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">def</span> prime_mine<span style="color:#006600; font-weight:bold;">&#40;</span>max<span style="color:#006600; font-weight:bold;">&#41;</span> 
  pa=<span style="color:#CC0066; font-weight:bold;">Array</span>.<span style="color:#9900CC;">new</span>
  pn=<span style="color:#006666;">0</span>;
  <span style="color:#CC0066; font-weight:bold;">p</span>=Prime.<span style="color:#9900CC;">new</span>
  pa <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> pn <span style="color:#9966CC; font-weight:bold;">while</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#40;</span>pn=<span style="color:#CC0066; font-weight:bold;">p</span>.<span style="color:#9966CC; font-weight:bold;">next</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&lt;</span> max<span style="color:#006600; font-weight:bold;">&#41;</span>
  pa
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p>Was den Benchmark angeht, der liegt irgendwo zwischen <strong>c</strong> und <strong>asrc</strong>. Der Alorithmus, der hier benutzt wird ist mir leider nicht bekannt. Wer jetzt Lust verspürt es herauszufinden und gegebenenfalls sogar zu optimieren, der möge bitte walten und darf auch gerne einen Kommentar hierzu hinterlassen.</p>
<p><strong>Fazit</strong></p>
<p><strong>Welche</strong> Lösung <strong>gewinnt</strong> jetzt eigentlich? Natürlich jede, denn <strong>jede ist funktionierender Ruby Code</strong>. <img src='http://railsmagazin.de/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ) Scherz beiseite, hier geht es natürlich nicht um <strong>Gewinner</strong> und Verlierer. Es soll lediglich klar gemacht werden, dass die <strong>Lernkurve</strong> bei Ruby dank der <strong>Flexibilität</strong> in der Syntax sehr niedrig gehalten ist. Auch wird verdeutlicht, dass man mit Ruby sehr <strong>effizienten und schnellen Code</strong> liefern kann und das bei <strong>guter Lesbarkeit</strong>.</p>
<div id="crp_related"><h3>Ähnliche Artikel</h3><ul><li><a href="http://railsmagazin.de/cursors_in_rails-214" rel="bookmark">(Fake-) Cursors f&uuml;r ActiveRecord (Rails 2.3)</a></li><li><a href="http://railsmagazin.de/domanenspezifische-sprachen-und-ruby-422" rel="bookmark">Dom&auml;nenspezifische Sprachen und Ruby</a></li><li><a href="http://railsmagazin.de/refactoring-von-rails-anwendungen-was-tun-wenn-der-laufsteg-durchbricht-450" rel="bookmark">Refactoring von Rails-Anwendungen: Was tun wenn der Laufsteg durchbricht?</a></li><li><a href="http://railsmagazin.de/logfile-rotation-fur-phusion-passenger-292" rel="bookmark">Logfile Rotation f&uuml;r Phusion Passenger</a></li><li><a href="http://railsmagazin.de/geokit-rails-und-google-maps-teil-1-552" rel="bookmark">Geokit: Rails und Google Maps - Teil 1</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://railsmagazin.de/prima-losungen-in-ruby-490/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Domänenspezifische Sprachen und Ruby</title>
		<link>http://railsmagazin.de/domanenspezifische-sprachen-und-ruby-422</link>
		<comments>http://railsmagazin.de/domanenspezifische-sprachen-und-ruby-422#comments</comments>
		<pubDate>Mon, 02 Mar 2009 13:00:27 +0000</pubDate>
		<dc:creator>Peter Schrammel</dc:creator>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[Entwickler]]></category>
		<category><![CDATA[DSL]]></category>

		<guid isPermaLink="false">http://www.railsmagazin.de/?p=422</guid>
		<description><![CDATA[Domänenspezifische Sprachen (DSL) sind in der IT- und Ruby-Welt sehr verbreitet und werden (teilweise unbewusst) täglich benutzt. Man denke an Make, Rake, acts_as_state_maschine und rSpec. An einem kleinen Beispiel soll gezeigt werden wie man selbst einfach DSL bauen kann.]]></description>
			<content:encoded><![CDATA[<p><img src="/wp-content/uploads/2009/03/peter_dsl.png" alt="peter_dsl" title="peter_dsl" width="180" height="121" class="alignleft size-full wp-image-889" /><a title="Domänenspezifische Sprachen" href="http://de.wikipedia.org/wiki/Domänenspezifische_Programmiersprache" target="_blank">Domänenspezifische Sprachen</a>, domain specific languages (DSLs) sind in der IT- und Ruby-Welt sehr verbreitet und werden (teilweise unbewusst) täglich benutzt. Man denke an Make, Rake, acts_as_state_machine und rSpec. An einem kleinen Beispiel soll gezeigt werden wie man selbst einfach DSLs bauen kann.</p>
<p><span id="more-422"></span></p>
<p>Mit DSLs will man folgende Ziele erreichen:</p>
<ul>
<li>weniger Redundanz</li>
<li>deklarative Beschreibung eines Sachverhaltes</li>
<li>bessere Lesbarkeit</li>
<li>weniger technischer Code</li>
<li>leichte Erlernbarkeit aufgrund des beschränkten Umfangs</li>
</ul>
<p>Die DSLs lassen sich grob in zwei Klassen unterteilen:</p>
<p><strong>Externe DSLs</strong> werden durch einen, meist speziell dafür geschriebenen, Parser eingelesen und dann interpretiert.</p>
<p>Vorteile:</p>
<ol>
<li>Die DSL kann vollkommen frei aufgebaut werden.</li>
<li>Ein Dokument der DSL wird Interpretiert (gelangt also nicht direkt zur Ausführung) wodurch mögliche Sicherheitslücken vermieden werden.</li>
</ol>
<p>Nachteile:</p>
<ol>
<li> Für jede DSL muss ein Parser geschrieben werden.</li>
<li>Enthält das Dokument dynamische Elemente müssen diese ebenfalls geparst und interpretiert werden.</li>
</ol>
<p>Beispiele für DSLs sind eine Reihe von Konfigurationsdateien:<br />
crontab, Makefile ,&#8230;<br />
Neuere Systeme gehen dazu über die DSL in From von XML Dateien zu verarbeiten. Das hat den Vorteil, dass ein gewöhnlicher XML-Parser verwendet werden kann. Der Nachteil ist, dass die DSL nicht mehr frei ist und evtl. mehr Tipparbeit erforderlich ist (hohe Redundanz). Dynamische Inhalte müssen ebenfalls nachträglich interpretiert werden.</p>
<p><strong>Interne DSL</strong> benutzen Komponenten der Wirtssprache  um die DSL zu parsen und auszuwerten. Die Vor/Nachteile sind genau umgekehrt zu den externen DSL.</p>
<p>In der Ruby Gemeinschaft werden, da Ruby selbst eine sehr freie Syntax hat, meist interne DSLs verwendet. An einem Beispiel soll die Implementierung einer DSL erläutert werden.</p>
<p>Der folgende Code stellt die Klassen Lexicon, Word und Wordform zur Verfügung. Damit soll der Aufbau eines einfachen Lexikons möglich sein.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> Lexicon
  <span style="color:#9966CC; font-weight:bold;">def</span> initialize
    <span style="color:#0066ff; font-weight:bold;">@words</span>=<span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> add_word<span style="color:#006600; font-weight:bold;">&#40;</span>word<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@words</span><span style="color:#006600; font-weight:bold;">&#91;</span>word.<span style="color:#9900CC;">uname</span><span style="color:#006600; font-weight:bold;">&#93;</span>=word
  <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> show
    <span style="color:#0066ff; font-weight:bold;">@words</span>.<span style="color:#9900CC;">each_value</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>word<span style="color:#006600; font-weight:bold;">|</span>
      <span style="color:#CC0066; font-weight:bold;">puts</span> word
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> Word
  attr_reader <span style="color:#ff3333; font-weight:bold;">:uname</span>, <span style="color:#ff3333; font-weight:bold;">:forms</span>, <span style="color:#ff3333; font-weight:bold;">:categories</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span>uname<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@uname</span>=uname
    <span style="color:#0066ff; font-weight:bold;">@forms</span>=<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> add_form<span style="color:#006600; font-weight:bold;">&#40;</span>form<span style="color:#006600; font-weight:bold;">&#41;</span>
    @forms <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> form
  <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> to_s
    forms.<span style="color:#9900CC;">inject</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;#{uname}:<span style="color:#000099;">\n</span>&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>out, form<span style="color:#006600; font-weight:bold;">|</span>
      out <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> form.<span style="color:#9900CC;">to_s</span> <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> <span style="color:#996600;">&quot;<span style="color:#000099;">\n</span>&quot;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> WordForm
  attr_reader <span style="color:#ff3333; font-weight:bold;">:form</span>, <span style="color:#ff3333; font-weight:bold;">:categories</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span>form, categories<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@form</span>=form
    <span style="color:#0066ff; font-weight:bold;">@categories</span>=categories
  <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> is?<span style="color:#006600; font-weight:bold;">&#40;</span>value<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@categroies</span>.<span style="color:#9900CC;">values</span>.<span style="color:#9966CC; font-weight:bold;">include</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>value.<span style="color:#9900CC;">to_s</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> to_s
    <span style="color:#996600;">&quot;#{form} - #{categories.inspect}&quot;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Ein Lexikon lässt sich wie folgt aufbauen:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">l=Lexicon.<span style="color:#9900CC;">new</span>
w=Word.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'gehen'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
wf=WordForm.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'ging'</span>, <span style="color:#ff3333; font-weight:bold;">:tempus</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:imperfect</span>, <span style="color:#ff3333; font-weight:bold;">:numerus</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:sg3</span>, <span style="color:#ff3333; font-weight:bold;">:genus</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:m</span><span style="color:#006600; font-weight:bold;">&#41;</span>
wf2=WordForm.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'ging'</span>, <span style="color:#ff3333; font-weight:bold;">:tempus</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:imperfect</span>, <span style="color:#ff3333; font-weight:bold;">:numerus</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:sg1</span><span style="color:#006600; font-weight:bold;">&#41;</span>
w.<span style="color:#9900CC;">add_form</span> wf
w.<span style="color:#9900CC;">add_form</span> wf2
l.<span style="color:#9900CC;">add_word</span><span style="color:#006600; font-weight:bold;">&#40;</span>w<span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>Zum Testen:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">l.<span style="color:#9900CC;">show</span>
&nbsp;
gehen:
ging <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#ff3333; font-weight:bold;">:tempus</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:imperfect</span>, <span style="color:#ff3333; font-weight:bold;">:numerus</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:sg3</span>, <span style="color:#ff3333; font-weight:bold;">:genus</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:m</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
ging <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#ff3333; font-weight:bold;">:tempus</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:imperfect</span>, <span style="color:#ff3333; font-weight:bold;">:numerus</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:sg1</span> <span style="color:#006600; font-weight:bold;">&#125;</span></pre></div></div>

<h2>Der erste Ansatz</h2>
<p>Der erste Schritt zur Vereinfachung des Aufbaus soll wie folgt aussehen:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">l=Lexicon.<span style="color:#9900CC;">new</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>lex<span style="color:#006600; font-weight:bold;">|</span>
  lex.<span style="color:#9900CC;">word</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'gehen'</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>word<span style="color:#006600; font-weight:bold;">|</span>
    word.<span style="color:#9900CC;">form</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'ging'</span>, <span style="color:#ff3333; font-weight:bold;">:tempus</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:imperfect</span>, <span style="color:#ff3333; font-weight:bold;">:numerus</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:sg3</span>, <span style="color:#ff3333; font-weight:bold;">:genus</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:m</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    word.<span style="color:#9900CC;">form</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'ging'</span>, <span style="color:#ff3333; font-weight:bold;">:tempus</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:imperfect</span>, <span style="color:#ff3333; font-weight:bold;">:numerus</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:sg1</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Dafür müssen die Klassen erweitert/ergänzt werden:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> Lexicon
  <span style="color:#9966CC; font-weight:bold;">def</span> initialize
   <span style="color:#0066ff; font-weight:bold;">@words</span>=<span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span>
   <span style="color:#9966CC; font-weight:bold;">yield</span> <span style="color:#0000FF; font-weight:bold;">self</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> word<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">*</span>attr<span style="color:#006600; font-weight:bold;">&#41;</span>
    wrd=Word.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">*</span>attr<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">yield</span> wrd
    add_word<span style="color:#006600; font-weight:bold;">&#40;</span>wrd<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">class</span> Word
  <span style="color:#9966CC; font-weight:bold;">def</span> form<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">*</span>attr<span style="color:#006600; font-weight:bold;">&#41;</span>
    frm=WordForm.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">*</span>attr<span style="color:#006600; font-weight:bold;">&#41;</span>
    add_form<span style="color:#006600; font-weight:bold;">&#40;</span>frm<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Drei Dinge sind an diesem Ansatz &#8220;unvorteilhaft&#8221;:</p>
<ol>
<li>Die Verknüpfung der Klassen untereinander durch Aufruf der Konstruktoren (Lexikon &lt;-&gt; Word und Word &lt;-&gt; WordForm). Der Nachteil wird bei der Vererbung der Klassen sehr deutlich.</li>
<li>Die klare Struktur der Klassen wurde durch die Methoden, die für die DSL benötigt werden verunreinigt. Die DSL sollte auf dem Model aufsetzen und diese so wenig wie möglich beeinflussen.</li>
<li>Die DSL ist noch immer &#8220;unschön&#8221;. Am besten wäre es, wenn das Lexikon sich wie folgt aufbauen liesse:</li>
</ol>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">l=lexicon <span style="color:#9966CC; font-weight:bold;">do</span>
  word <span style="color:#996600;">'gehen'</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    form <span style="color:#996600;">'ging'</span>, <span style="color:#ff3333; font-weight:bold;">:tempus</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:imperfect</span>, <span style="color:#ff3333; font-weight:bold;">:numerus</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:sg3</span>, <span style="color:#ff3333; font-weight:bold;">:genus</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:m</span>
    form <span style="color:#996600;">'ging'</span>, <span style="color:#ff3333; font-weight:bold;">:tempus</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:imperfect</span>, <span style="color:#ff3333; font-weight:bold;">:numerus</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:sg1</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<h2>Der richtige Weg</h2>
<p>Wir wenden uns also wieder der ursprünglichen Form zu und führen eine neue Klasse LexiconBuilder ein:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> LexiconBuilder
  attr_reader <span style="color:#ff3333; font-weight:bold;">:lexicon</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span>lexicon<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@lexicon</span>=lexicon
  <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> word<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">*</span>attr<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@word</span>=Word.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">*</span>attr<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">yield</span>
    <span style="color:#0066ff; font-weight:bold;">@lexicon</span>.<span style="color:#9900CC;">add_word</span><span style="color:#006600; font-weight:bold;">&#40;</span>@word<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0000FF; font-weight:bold;">nil</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> form<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">*</span>attr<span style="color:#006600; font-weight:bold;">&#41;</span>
    frm=WordForm.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">*</span>attr<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@word</span>.<span style="color:#9900CC;">add_form</span><span style="color:#006600; font-weight:bold;">&#40;</span>frm<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0000FF; font-weight:bold;">nil</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Dann benötigen wir noch die Definition von lexicon:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> lexicon<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&amp;</span>block<span style="color:#006600; font-weight:bold;">&#41;</span>
  lexikon=Lexicon.<span style="color:#9900CC;">new</span>
  builder=LexiconBuilder.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>lexikon<span style="color:#006600; font-weight:bold;">&#41;</span>
  builder.<span style="color:#9900CC;">instance_eval</span> <span style="color:#006600; font-weight:bold;">&amp;</span>block
  lexikon
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Hier liegt ein wenig Ruby Magie in der Luft. Nachdem das Lexicon und der LexiconBuilder erzeugt werden, wird der übergebene Block im Kontext des Builders ausgeführt. Jegliche Methodenaufrufe erfolgen also auf der Instanz von LexiconBuilder.</p>
<p>LexiconBuilder übernimmt hier die Rolle des Parsers. Es stellt alle (word, form) syntaktischen Elemente der DSL bereit und baut die Struktur wie gewünscht auf.</p>
<p>Die Vorteile liegen auf der Hand:</p>
<ol>
<li> Keine Einführung neuer Abhängigkeiten in bestehenden Klassen</li>
<li>Alle Ahängigkeiten sind in LexiconBuilder gekappselt, LexiconBuilder lässt sich austauschen um eine andere DSL zu unterstützen.</li>
</ol>
<p>Dieser relativ einfache Builder hat den Nachteil, dass es die &#8220;Syntax&#8221;, in unserem Fall die Abfolge der Methodenaufrufe, nicht überprüft. So wäre das folgende Programm durchaus korrekt, würde aber falsche Ergebnisse liefern:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">l=lexicon <span style="color:#9966CC; font-weight:bold;">do</span>
  word <span style="color:#996600;">'gehen'</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    word <span style="color:#996600;">'foobar'</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      form <span style="color:#996600;">'ging'</span>,:tempus <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:imperfect</span>, <span style="color:#ff3333; font-weight:bold;">:numerus</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:sg3</span>, <span style="color:#ff3333; font-weight:bold;">:genus</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:m</span>
      form <span style="color:#996600;">'ging'</span>,:tempus <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:imperfect</span>, <span style="color:#ff3333; font-weight:bold;">:numerus</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:sg1</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Wie man sieht, ist der Aufbau von DSLs keine Raketenwissenschaft und sollte, wenn der Code &#8220;häßlich&#8221; wird, auf jeden Fall in Betracht gezogen werden.</p>
<div id="crp_related"><h3>Ähnliche Artikel</h3><ul><li><a href="http://railsmagazin.de/refactoring-von-rails-anwendungen-was-tun-wenn-der-laufsteg-durchbricht-450" rel="bookmark">Refactoring von Rails-Anwendungen: Was tun wenn der Laufsteg durchbricht?</a></li><li><a href="http://railsmagazin.de/dusseldorf-on-rails-ladt-ein-2-1441" rel="bookmark">D&uuml;sseldorf on Rails l&auml;dt ein!</a></li><li><a href="http://railsmagazin.de/besuch-der-railswaycon-1393" rel="bookmark">Besuch der RailsWayCon</a></li><li><a href="http://railsmagazin.de/logfile-rotation-fur-phusion-passenger-292" rel="bookmark">Logfile Rotation f&uuml;r Phusion Passenger</a></li><li><a href="http://railsmagazin.de/cursors_in_rails-214" rel="bookmark">(Fake-) Cursors f&uuml;r ActiveRecord (Rails 2.3)</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://railsmagazin.de/domanenspezifische-sprachen-und-ruby-422/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Geokit: Rails und Google Maps &#8211; Teil 1</title>
		<link>http://railsmagazin.de/geokit-rails-und-google-maps-teil-1-552</link>
		<comments>http://railsmagazin.de/geokit-rails-und-google-maps-teil-1-552#comments</comments>
		<pubDate>Sun, 01 Mar 2009 15:47:59 +0000</pubDate>
		<dc:creator>Jochen Kächelin</dc:creator>
				<category><![CDATA[Entwickler]]></category>
		<category><![CDATA[Neue Gems]]></category>
		<category><![CDATA[Tipps]]></category>
		<category><![CDATA[geokit]]></category>
		<category><![CDATA[google maps]]></category>

		<guid isPermaLink="false">http://www.railsmagazin.de/?p=552</guid>
		<description><![CDATA[In Teil 1 zeige ich die Installation von Geokit und ein paar einfache Abfragen über die Google Maps-API in der interaktiven irb Konsole. In den weiteren Teilen folgt die Einbindung in ein eigenständiges Rails Projekt.
Geokit macht das Erstellen von Location-Based-Applikationen sehr einfach. Es stellt mittels einer sehr klar strukturierten API nützliche Funktionen zum Ermitteln eines [...]]]></description>
			<content:encoded><![CDATA[<p>In Teil 1 zeige ich die Installation von <a title="http://github.com/andre/geokit-gem/tree/master" href="http://github.com/andre/geokit-gem/tree/master" target="_blank">Geokit</a> und ein paar einfache Abfragen über die Google Maps-API in der interaktiven <strong>irb</strong> Konsole. In den weiteren Teilen folgt die Einbindung in ein eigenständiges Rails Projekt.</p>
<p>Geokit macht das Erstellen von Location-Based-Applikationen sehr einfach. Es stellt mittels einer sehr klar strukturierten API nützliche Funktionen zum Ermitteln eines Standortes, Entfernungsberechnungen und Rückwärtsberechnungen zur Verfügung.</p>
<p>In einem aktuellen Projekt verwenden wir Geokit um auf einer Landkarte die Herkunft unserer Besucher darzustellen und um den Aufbau einer Community zu fördern. „Befindet sich in der näheren Umgebung jemand mit den gleichen Interessen?“</p>
<p><span id="more-552"></span><br />
1. Falls noch nicht geschehen müssen wir unserem System zuerst mitteilen wo es das <strong>Geokit gem</strong> finden kann:</p>

<div class="wp_syntax"><div class="code"><pre class="language" style="font-family:monospace;">gem sources -a http://gems.github.com</pre></div></div>

<p>2. Installation des Geokit gems:</p>

<div class="wp_syntax"><div class="code"><pre class="language" style="font-family:monospace;">sudo gem install andre-geokit</pre></div></div>

<p>3. Erstellen einer neuen Rails Applikation:</p>

<div class="wp_syntax"><div class="code"><pre class="language" style="font-family:monospace;">rails -d mysql geokit &amp;&amp; cd geokit</pre></div></div>

<p>4. Die interaktive irb Konsole starten:</p>

<div class="wp_syntax"><div class="code"><pre class="language" style="font-family:monospace;">irb</pre></div></div>

<p>5. Das Geokit gem einbinden:</p>

<div class="wp_syntax"><div class="code"><pre class="1" style="font-family:monospace;">require &quot;rubygems&quot;
require &quot;geokit&quot;</pre></div></div>

<p>Bei einer erfolgreichen Einbindung sollten folgende Zeilen zu sehen sein:</p>

<div class="wp_syntax"><div class="code"><pre class="language" style="font-family:monospace;">&gt;&gt; require &quot;rubygems&quot;
=&gt; true
&gt;&gt; require &quot;geokit&quot;
=&gt; true
&gt;&gt;</pre></div></div>

<p>Als erstes teile ich Google mit wo ich mich momentan befinde:</p>

<div class="wp_syntax"><div class="code"><pre class="language" style="font-family:monospace;">hier = Geokit::Geocoders::MultiGeocoder.geocode(&quot;Hauptstrasse 86, Eislingen&quot;)
&nbsp;
#&lt;Geokit::GeoLoc:0x127b9a0 @city=&quot;Eislingen&quot;, @lng=9.7082073, @country_code=&quot;DE&quot;, @provider=&quot;google&quot;, @street_address=&quot;Hauptstra\303\237e 86&quot;, @lat=48.7015365, @full_address=&quot;Hauptstra\303\237e 86, 73054 Eislingen, Germany&quot;, @zip=&quot;73054&quot;, @precision=&quot;address&quot;, @state=&quot;Baden-W\303\274rttemberg&quot;, @success=true&gt;</pre></div></div>

<p>Dann sage ich Google wo sich mein Büro befindet:</p>

<div class="wp_syntax"><div class="code"><pre class="language" style="font-family:monospace;">office = Geokit::Geocoders::MultiGeocoder.geocode(&quot;Stuttgarter strasse 177, uhingen&quot;)
&nbsp;
#&lt;Geokit::GeoLoc:0x121798c @city=&quot;Uhingen&quot;, @lng=9.5676341, @country_code=&quot;DE&quot;, @provider=&quot;google&quot;, @street_address=&quot;Stuttgarter Stra\303\237e 177&quot;, @lat=48.7137968, @full_address=&quot;Stuttgarter Stra\303\237e 177, 73066 Uhingen, Germany&quot;, @zip=&quot;73066&quot;, @precision=&quot;address&quot;, @state=&quot;Baden-W\303\274rttemberg&quot;, @success=true&gt;</pre></div></div>

<p>Übersichtlicher wird das ganze mit folgendem Aufruf:</p>

<div class="wp_syntax"><div class="code"><pre class="language" style="font-family:monospace;">&gt;&gt; office.display
Provider: google
Street: Stuttgarter Straße 177
City: Uhingen
State: Baden-Württemberg
Zip: 73066
Latitude: 48.7137968
Longitude: 9.5676341
Country: DE</pre></div></div>

<p>Wenn ich &#8220;nur&#8221; die Angaben zu den Breiten- und Längengraden habe kann ich auch eine Rückwärtsabfrage durchführen um die Andresse zu ermitteln:</p>

<div class="wp_syntax"><div class="code"><pre class="language" style="font-family:monospace;">reverse = Geokit::Geocoders::GoogleGeocoder.reverse_geocode &quot;48.7137968,9.5676341&quot;</pre></div></div>

<p>und ich erhalte wieder die Adresse meines Büros:</p>

<div class="wp_syntax"><div class="code"><pre class="language" style="font-family:monospace;">#&lt;Geokit::GeoLoc:0x1280838 @city=&quot;Uhingen&quot;, @lng=9.5676341, @country_code=&quot;DE&quot;, @provider=&quot;google&quot;, @street_address=&quot;Stuttgarter Stra\303\237e 177&quot;, @lat=48.7137968, @full_address=&quot;Stuttgarter Stra\303\237e 177, 73066 Uhingen, Germany&quot;, @zip=&quot;73066&quot;, @precision=&quot;address&quot;, @state=&quot;Baden-W\303\274rttemberg&quot;, @success=true&gt;</pre></div></div>

<p>Wenn ich nun wissen will wie weit mein momentaner Standort von meinem Büro entfernt ist benutze ich folgendes:</p>

<div class="wp_syntax"><div class="code"><pre class="language" style="font-family:monospace;">&gt;&gt; hier.distance_to(office)
=&gt; 6.47237916523715</pre></div></div>

<p>Ich muss als jeden Tag ca. 6.5 Kilometer fahren um ins Büro zu kommen.</p>
<p>So, hier ist der Teil 1 auch schon zu Ende. In den nächsten Teilen bauen wir uns Stück für Stück eine eigenständige Rails Applikation welche intensiv mit Google Maps arbeitet. Bis denne.</p>
<div id="crp_related"><h3>Ähnliche Artikel</h3><ul><li><a href="http://railsmagazin.de/logfile-rotation-fur-phusion-passenger-292" rel="bookmark">Logfile Rotation f&uuml;r Phusion Passenger</a></li><li><a href="http://railsmagazin.de/google_gdata_rails-238" rel="bookmark">Google ver&ouml;ffentlicht gem f&uuml;r diverse APIs</a></li><li><a href="http://railsmagazin.de/refactoring-von-rails-anwendungen-was-tun-wenn-der-laufsteg-durchbricht-450" rel="bookmark">Refactoring von Rails-Anwendungen: Was tun wenn der Laufsteg durchbricht?</a></li><li><a href="http://railsmagazin.de/success-story-globagocom-1334" rel="bookmark">Success Story: globago.com</a></li><li><a href="http://railsmagazin.de/besuch-der-railswaycon-1393" rel="bookmark">Besuch der RailsWayCon</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://railsmagazin.de/geokit-rails-und-google-maps-teil-1-552/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>
