<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><!-- generator="wordpress/2.0.3" --><rss 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:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>kjempekjekt.com</title>
	<link>http://blog.kjempekjekt.com</link>
	<description>om livet som .net utvikler</description>
	<pubDate>Tue, 09 Mar 2010 05:54:11 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.0.3</generator>
	<language>en</language>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/kjempekjektcom" /><feedburner:info uri="kjempekjektcom" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId>kjempekjektcom</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><feedburner:feedFlare href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Ffeeds.feedburner.com%2Fkjempekjektcom" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fkjempekjektcom" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare href="http://www.bloglines.com/sub/http://feeds.feedburner.com/kjempekjektcom" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fkjempekjektcom" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fkjempekjektcom" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fkjempekjektcom" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare><feedburner:feedFlare href="http://www.plusmo.com/add?url=http%3A%2F%2Ffeeds.feedburner.com%2Fkjempekjektcom" src="http://plusmo.com/res/graphics/fbplusmo.gif">Subscribe with Plusmo</feedburner:feedFlare><feedburner:feedFlare href="http://www.thefreedictionary.com/_/hp/AddRSS.aspx?http%3A%2F%2Ffeeds.feedburner.com%2Fkjempekjektcom" src="http://img.tfd.com/hp/addToTheFreeDictionary.gif">Subscribe with The Free Dictionary</feedburner:feedFlare><feedburner:feedFlare href="http://www.bitty.com/manual/?contenttype=rssfeed&amp;contentvalue=http%3A%2F%2Ffeeds.feedburner.com%2Fkjempekjektcom" src="http://www.bitty.com/img/bittychicklet_91x17.gif">Subscribe with Bitty Browser</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsalloy.com/?rss=http%3A%2F%2Ffeeds.feedburner.com%2Fkjempekjektcom" src="http://www.newsalloy.com/subrss3.gif">Subscribe with NewsAlloy</feedburner:feedFlare><feedburner:feedFlare href="http://www.live.com/?add=http%3A%2F%2Ffeeds.feedburner.com%2Fkjempekjektcom" src="http://tkfiles.storage.msn.com/x1piYkpqHC_35nIp1gLE68-wvzLZO8iXl_JMledmJQXP-XTBOLfmQv4zhj4MhcWEJh_GtoBIiAl1Mjh-ndp9k47If7hTaFno0mxW9_i3p_5qQw">Subscribe with Live.com</feedburner:feedFlare><feedburner:feedFlare href="http://mix.excite.eu/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fkjempekjektcom" src="http://image.excite.co.uk/mix/addtomix.gif">Subscribe with Excite MIX</feedburner:feedFlare><feedburner:feedFlare href="http://download.attensa.com/app/get_attensa.html?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fkjempekjektcom" src="http://www.attensa.com/blogs/attensa/WindowsLiveWriter/BadgeredintoBadges_10C02/attensa_feed_button5.gif">Subscribe with Attensa for Outlook</feedburner:feedFlare><feedburner:feedFlare href="http://www.webwag.com/wwgthis.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fkjempekjektcom" src="http://www.webwag.com/images/wwgthis.gif">Subscribe with Webwag</feedburner:feedFlare><feedburner:feedFlare href="http://www.podcastready.com/oneclick_bookmark.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fkjempekjektcom" src="http://www.podcastready.com/images/podcastready_button.gif">Subscribe with Podcast Ready</feedburner:feedFlare><feedburner:feedFlare href="http://www.flurry.com/pushRssFeed.do?r=fb&amp;url=http%3A%2F%2Ffeeds.feedburner.com%2Fkjempekjektcom" src="http://www.flurry.com/images/flurry_rss_logo2.gif">Subscribe with Flurry</feedburner:feedFlare><feedburner:feedFlare href="http://www.wikio.com/subscribe?url=http%3A%2F%2Ffeeds.feedburner.com%2Fkjempekjektcom" src="http://www.wikio.com/shared/img/add2wikio.gif">Subscribe with Wikio</feedburner:feedFlare><feedburner:feedFlare href="http://www.dailyrotation.com/index.php?feed=http%3A%2F%2Ffeeds.feedburner.com%2Fkjempekjektcom" src="http://www.dailyrotation.com/rss-dr2.gif">Subscribe with Daily Rotation</feedburner:feedFlare><item>
		<title>Events i Ruby</title>
		<link>http://feedproxy.google.com/~r/kjempekjektcom/~3/cdhirV984P0/</link>
		<comments>http://blog.kjempekjekt.com/2010/03/09/events-i-ruby/#comments</comments>
		<pubDate>Tue, 09 Mar 2010 05:54:09 +0000</pubDate>
		<dc:creator>Torbjørn</dc:creator>
		
	<category>Ruby</category>
		<guid isPermaLink="false">http://blog.kjempekjekt.com/2010/03/09/events-i-ruby/</guid>
		<description><![CDATA[Ruby har ikke events slik som vi er vandt med fra .Net. Det er derimot ikke særlig vanskelig å implementere noe som ligner. Jeg begynte å eksperimentere litt, og her følger en slags log over hva jeg har forsøkt. Jeg har ikke landet på noen &#8220;best practice&#8221;, og det er heller ikke noe rocket science [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.ruby-lang.org/en/" target="_blank">Ruby</a> har ikke events slik som vi er vandt med fra .Net. Det er derimot ikke særlig vanskelig å implementere noe som ligner. Jeg begynte å eksperimentere litt, og her følger en slags log over hva jeg har forsøkt. Jeg har ikke landet på noen &#8220;best practice&#8221;, og det er heller ikke noe <em>rocket science</em> her - men jeg tror følgende kodesnutter kan være insteressante, særlig om man ikke er så veldig erfaren med Ruby enda.</p>
<h4>Iterasjon 1</h4>
<p>Jeg ønsker å implementere en Counter-klasse. Den skal ha en metode som heter <em>increment</em> som jeg kan kalle x antall ganger, hvor x er en limit jeg setter. Når limiten er nådd vil jeg at Counter-objektet informerer meg om dette ved å fyre av et event. Her er koden for klassen, samt litt kode som viser hvordan den brukes:</p>
<div style="background-color: #000000; padding-left: 15px; margin-bottom: 20px; color: #f6f3e8"><font face="monospace"><span style="background-color: #000000"><font color="#3d3d3d">1 </font></span><font color="#96cbfe">class</font>&nbsp;<font color="#ffffb6">Counter</font><br /><span style="background-color: #000000"><font color="#3d3d3d">2 </font></span>&nbsp; <font color="#96cbfe">def</font>&nbsp;<font color="#ffd2a7">initialize</font> limit<br /><span style="background-color: #000000"><font color="#3d3d3d">3 </font></span>&nbsp;&nbsp;&nbsp; <font color="#c6c5fe">@limit</font> = limit<br /><span style="background-color: #000000"><font color="#3d3d3d">4 </font></span>&nbsp;&nbsp;&nbsp; <font color="#c6c5fe">@count</font> = <font color="#ff73fd">0</font><br /><span style="background-color: #000000"><font color="#3d3d3d">5 </font></span>&nbsp; <font color="#96cbfe">end</font><br /><span style="background-color: #000000"><font color="#3d3d3d">6 </font></span>&nbsp; <font color="#96cbfe">def</font>&nbsp;<font color="#ffd2a7">on_limit_reached=</font> delegate<br /><span style="background-color: #000000"><font color="#3d3d3d">7 </font></span>&nbsp;&nbsp;&nbsp; <font color="#c6c5fe">@on_limit_reached_delegate</font> = delegate<br /><span style="background-color: #000000"><font color="#3d3d3d">8 </font></span>&nbsp; <font color="#96cbfe">end</font><br /><span style="background-color: #000000"><font color="#3d3d3d">9 </font></span>&nbsp; <font color="#96cbfe">def</font>&nbsp;<font color="#ffd2a7">increment</font><br /><span style="background-color: #000000"><font color="#3d3d3d">10 </font></span>&nbsp;&nbsp;&nbsp; <font color="#c6c5fe">@count</font> += <font color="#ff73fd">1</font><br /><span style="background-color: #000000"><font color="#3d3d3d">11 </font></span>&nbsp;&nbsp;&nbsp; <font color="#c6c5fe">@on_limit_reached_delegate</font>.call <font color="#6699cc">if</font>&nbsp;<font color="#c6c5fe">@count</font> == <font color="#c6c5fe">@limit</font><br /><span style="background-color: #000000"><font color="#3d3d3d">12 </font></span>&nbsp; <font color="#96cbfe">end</font><br /><span style="background-color: #000000"><font color="#3d3d3d">13 </font></span><font color="#96cbfe">end</font><br /><span style="background-color: #000000"><font color="#3d3d3d">14 </font></span><br /><span style="background-color: #000000"><font color="#3d3d3d">15 </font></span>c = <font color="#ffffb6">Counter</font>.new(<font color="#ff73fd">5</font>) <font color="#7c7c7c"># create a new counter</font><br /><span style="background-color: #000000"><font color="#3d3d3d">16 </font></span>c.on_limit_reached = <font color="#96cbfe">lambda</font>{ puts <font color="#336633">&#8216;</font><font color="#a8ff60">Limit reached</font><font color="#336633">&#8216;</font> }<br /><span style="background-color: #000000"><font color="#3d3d3d">17 </font></span><font color="#ff73fd">4</font>.times { c.increment } <font color="#7c7c7c"># count up to limit -1</font><br /><span style="background-color: #000000"><font color="#3d3d3d">18 </font></span>puts <font color="#336633">&#8216;</font><font color="#a8ff60">Limit not reached yet</font><font color="#336633">&#8216;</font><br /><span style="background-color: #000000"><font color="#3d3d3d">19 </font></span>c.increment <font color="#7c7c7c"># one more time, limit is now reached</font><br /></font></div>
<div style="margin-bottom: 20px"><font face="monospace">Output:<br />
<div style="padding-bottom: 5px; background-color: #000000; padding-left: 15px; color: lightgreen; padding-top: 5px">Limit not reached yet<br />Limit reached</div>
<p></font></div>
<p>Løsninger er altså at vi lager en closure i linje 16 (også kalt lambda, kodeblokk, anonym metode, etc) som man sender til on_limit_reached= metoden. Counter-klassen tar vare på en referanse til denne closuren. Når limiten er nådd eksekveres den så i linje 11.</p>
<p>Merk at jeg glemte å legge til en test for om delegaten er satt, så koden i linje 11 vil feile om den ikke har noen lyttere (<em>lover å skjerpe meg</em>).</p>
<h4>Iterasjon 2</h4>
<p>Løsningen i iterasjon 1 støtter bare én lytter – hvis flere legges til vil den bare erstatte den første. Jeg ønsker derfor å utvide Counter for dette, og denne gangen husket jeg å legge til en test for om det er noen som lytter før jeg &#8220;fyrer av eventet&#8221;:</p>
<div style="background-color: #000000; padding-left: 15px; margin-bottom: 20px; color: #f6f3e8"><font face="monospace"><span style="background-color: #000000"><font color="#3d3d3d">1 </font></span><font color="#96cbfe">class</font>&nbsp;<font color="#ffffb6">Counter</font><br /><span style="background-color: #000000"><font color="#3d3d3d">2 </font></span>&nbsp; <font color="#96cbfe">def</font>&nbsp;<font color="#ffd2a7">initialize</font> limit<br /><span style="background-color: #000000"><font color="#3d3d3d">3 </font></span>&nbsp;&nbsp;&nbsp; <font color="#c6c5fe">@limit</font> = limit<br /><span style="background-color: #000000"><font color="#3d3d3d">4 </font></span>&nbsp;&nbsp;&nbsp; <font color="#c6c5fe">@count</font> = <font color="#ff73fd">0</font><br /><span style="background-color: #000000"><font color="#3d3d3d">5 </font></span>&nbsp; <font color="#96cbfe">end</font><br /><span style="background-color: #000000"><font color="#3d3d3d">6 </font></span>&nbsp; <font color="#96cbfe">def</font>&nbsp;<font color="#ffd2a7">on_limit_reached=</font> delegate<br /><span style="background-color: #000000"><font color="#3d3d3d">7 </font></span>&nbsp;&nbsp;&nbsp; <font color="#c6c5fe">@limit_reached_delegates</font> ||= []<br /><span style="background-color: #000000"><font color="#3d3d3d">8 </font></span>&nbsp;&nbsp;&nbsp; <font color="#c6c5fe">@limit_reached_delegates</font> &lt;&lt; delegate<br /><span style="background-color: #000000"><font color="#3d3d3d">9 </font></span>&nbsp; <font color="#96cbfe">end</font><br /><span style="background-color: #000000"><font color="#3d3d3d">10 </font></span>&nbsp; <font color="#96cbfe">def</font>&nbsp;<font color="#ffd2a7">increment</font><br /><span style="background-color: #000000"><font color="#3d3d3d">11 </font></span>&nbsp;&nbsp;&nbsp; <font color="#c6c5fe">@count</font> += <font color="#ff73fd">1</font><br /><span style="background-color: #000000"><font color="#3d3d3d">12 </font></span>&nbsp;&nbsp;&nbsp; <font color="#6699cc">if</font>&nbsp;<font color="#c6c5fe">@count</font> == <font color="#c6c5fe">@limit</font><br /><span style="background-color: #000000"><font color="#3d3d3d">13 </font></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font color="#c6c5fe">@limit_reached_delegates</font>.each {|<font color="#c6c5fe">d</font>| d.call } <font color="#6699cc">if</font>&nbsp;<font color="#c6c5fe">@limit_reached_delegates</font><br /><span style="background-color: #000000"><font color="#3d3d3d">14 </font></span>&nbsp;&nbsp;&nbsp; <font color="#6699cc">end</font><br /><span style="background-color: #000000"><font color="#3d3d3d">15 </font></span>&nbsp; <font color="#96cbfe">end</font><br /><span style="background-color: #000000"><font color="#3d3d3d">16 </font></span><font color="#96cbfe">end</font><br /><span style="background-color: #000000"><font color="#3d3d3d">17 </font></span><br /><span style="background-color: #000000"><font color="#3d3d3d">18 </font></span>c = <font color="#ffffb6">Counter</font>.new(<font color="#ff73fd">5</font>) <font color="#7c7c7c"># create a new counter</font><br /><span style="background-color: #000000"><font color="#3d3d3d">19 </font></span>c.on_limit_reached = <font color="#96cbfe">lambda</font>{ puts <font color="#336633">&#8216;</font><font color="#a8ff60">I was informed about limit reached</font><font color="#336633">&#8216;</font> }<br /><span style="background-color: #000000"><font color="#3d3d3d">20 </font></span>c.on_limit_reached = <font color="#96cbfe">lambda</font>{ puts <font color="#336633">&#8216;</font><font color="#a8ff60">I was also informed about limit reached</font><font color="#336633">&#8216;</font> }<br /><span style="background-color: #000000"><font color="#3d3d3d">21 </font></span><font color="#ff73fd">4</font>.times { c.increment } <font color="#7c7c7c"># count up to limit -1</font><br /><span style="background-color: #000000"><font color="#3d3d3d">22 </font></span>puts <font color="#336633">&#8216;</font><font color="#a8ff60">Limit not reached yet</font><font color="#336633">&#8216;</font><br /><span style="background-color: #000000"><font color="#3d3d3d">23 </font></span>c.increment <font color="#7c7c7c"># one more time, limit is now reached</font><br /></font></div>
<div style="margin-bottom: 20px"><font face="monospace">Output:<br />
<div style="padding-bottom: 5px; background-color: #000000; padding-left: 15px; color: lightgreen; padding-top: 5px">Limit not reached yet<br />I was informed about limit reached<br />I was also informed about limit reached</div>
<p></font></div>
<p>Counter har nå et array av delegater: @limit_reached_delegates. Når limiten er nådd kaller jeg alle sammen. Jeg fikk desverre ikke til å bruke += for å legge til eventer, noe som ville ha virket riktigere for C#-utviklere.</p>
<h4>Iterasjon 3</h4>
<p>Det er på tide å legge opp støtte for flere eventer; jeg ønsker nå å bli fortalt hver gang telleren inkrementeres, og legger derfor opp en on_increment= metode. Jeg vil også sende med verdien på counteren i eventet.</p>
<div style="background-color: #000000; padding-left: 15px; margin-bottom: 20px; color: #f6f3e8"><font face="monospace"><span style="background-color: #000000"><font color="#3d3d3d">1 </font></span><font color="#96cbfe">class</font>&nbsp;<font color="#ffffb6">Counter</font><br /><span style="background-color: #000000"><font color="#3d3d3d">2 </font></span>&nbsp; <font color="#96cbfe">def</font>&nbsp;<font color="#ffd2a7">initialize</font> limit<br /><span style="background-color: #000000"><font color="#3d3d3d">3 </font></span>&nbsp;&nbsp;&nbsp; <font color="#c6c5fe">@count</font>, <font color="#c6c5fe">@limit</font> = <font color="#ff73fd">0</font>, limit<br /><span style="background-color: #000000"><font color="#3d3d3d">4 </font></span>&nbsp;&nbsp;&nbsp; <font color="#c6c5fe">@event_handlers</font> = {}<br /><span style="background-color: #000000"><font color="#3d3d3d">5 </font></span>&nbsp; <font color="#96cbfe">end</font><br /><span style="background-color: #000000"><font color="#3d3d3d">6 </font></span>&nbsp; <font color="#96cbfe">def</font>&nbsp;<font color="#ffd2a7">on_limit_reached=</font> delegate<br /><span style="background-color: #000000"><font color="#3d3d3d">7 </font></span>&nbsp;&nbsp;&nbsp; (<font color="#c6c5fe">@event_handlers</font>[<font color="#99cc99">:limit_reached</font>] ||= []) &lt;&lt; delegate<br /><span style="background-color: #000000"><font color="#3d3d3d">8 </font></span>&nbsp; <font color="#96cbfe">end</font><br /><span style="background-color: #000000"><font color="#3d3d3d">9 </font></span>&nbsp; <font color="#96cbfe">def</font>&nbsp;<font color="#ffd2a7">on_increment=</font> delegate<br /><span style="background-color: #000000"><font color="#3d3d3d">10 </font></span>&nbsp;&nbsp;&nbsp; (<font color="#c6c5fe">@event_handlers</font>[<font color="#99cc99">:increment</font>] ||= []) &lt;&lt; delegate<br /><span style="background-color: #000000"><font color="#3d3d3d">11 </font></span>&nbsp; <font color="#96cbfe">end</font><br /><span style="background-color: #000000"><font color="#3d3d3d">12 </font></span>&nbsp; <font color="#96cbfe">def</font>&nbsp;<font color="#ffd2a7">increment</font><br /><span style="background-color: #000000"><font color="#3d3d3d">13 </font></span>&nbsp;&nbsp;&nbsp; <font color="#c6c5fe">@count</font> += <font color="#ff73fd">1</font><br /><span style="background-color: #000000"><font color="#3d3d3d">14 </font></span>&nbsp;&nbsp;&nbsp; <font color="#c6c5fe">@event_handlers</font>[<font color="#99cc99">:increment</font>].each {|<font color="#c6c5fe">d</font>| d.call(<font color="#c6c5fe">@count</font>) } <font color="#6699cc">if</font>&nbsp;<font color="#c6c5fe">@event_handlers</font>[<font color="#99cc99">:increment</font>]<br /><span style="background-color: #000000"><font color="#3d3d3d">15 </font></span>&nbsp;&nbsp;&nbsp; <font color="#6699cc">if</font>&nbsp;<font color="#c6c5fe">@count</font> == <font color="#c6c5fe">@limit</font><br /><span style="background-color: #000000"><font color="#3d3d3d">16 </font></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font color="#c6c5fe">@event_handlers</font>[<font color="#99cc99">:limit_reached</font>].each {|<font color="#c6c5fe">d</font>| d.call } <font color="#6699cc">if</font>&nbsp;<font color="#c6c5fe">@event_handlers</font>[<font color="#99cc99">:limit_reached</font>]<br /><span style="background-color: #000000"><font color="#3d3d3d">17 </font></span>&nbsp;&nbsp;&nbsp; <font color="#6699cc">end</font><br /><span style="background-color: #000000"><font color="#3d3d3d">18 </font></span>&nbsp; <font color="#96cbfe">end</font><br /><span style="background-color: #000000"><font color="#3d3d3d">19 </font></span><font color="#96cbfe">end</font><br /><span style="background-color: #000000"><font color="#3d3d3d">20 </font></span><br /><span style="background-color: #000000"><font color="#3d3d3d">21 </font></span>c = <font color="#ffffb6">Counter</font>.new(<font color="#ff73fd">5</font>) <font color="#7c7c7c"># create a new counter</font><br /><span style="background-color: #000000"><font color="#3d3d3d">22 </font></span>c.on_limit_reached = <font color="#96cbfe">lambda</font>{ puts <font color="#336633">&#8216;</font><font color="#a8ff60">Limit reached</font><font color="#336633">&#8216;</font> }<br /><span style="background-color: #000000"><font color="#3d3d3d">23 </font></span>c.on_increment = <font color="#96cbfe">lambda</font>{|<font color="#c6c5fe">count</font>| puts <font color="#336633">&#8220;</font><font color="#a8ff60">Counter was incremented to </font><font color="#00a0a0">#{</font>count<font color="#00a0a0">}</font><font color="#336633">&#8220;</font> }<br /><span style="background-color: #000000"><font color="#3d3d3d">24 </font></span><font color="#ff73fd">5</font>.times { c.increment }<br /></font></div>
<div style="margin-bottom: 20px"><font face="monospace">Output:<br />
<div style="padding-bottom: 5px; background-color: #000000; padding-left: 15px; color: lightgreen; padding-top: 5px">Counter was incremented to 1<br />Counter was incremented to 2<br />Counter was incremented to 3<br />Counter was incremented to 4<br />Counter was incremented to 5<br />Limit reached</div>
<p></font></div>
<p>Jeg har nå brukt en Hash(-tabell) til å holde rede på alle handlerne – denne opprettes i linje 4. Den litt hårete syntaksen på linje 7 og 10 legger inn en ny array for en gitt event-nøkkel om arrayet ikke finnes enda, før den legger delegaten til arrayet. Deretter kan jeg trigge increment-eventet hver gang increment kalles (linje 14). Legg merke til at jeg sender inn @count når jeg kaller delegaten, og kan derfor bruke den i closuren i linje 23. </p>
<h4>Iterasjon 4</h4>
<p>Det ble litt mye &#8220;bråk&#8221; i Counter-klassen for å holde rede på event-handlerene i iterasjon 3, og jeg forsøker derfor å trekke ut denne logikken (<em>Single Responsibility Principle</em>). Jeg lager en Ruby-modul som jeg kan mikse inn i Counter (vi kaller det en <em>mixin</em>, som er Ruby&#8217;s løsning på multippel arv, noe vi ikke har i .Net). Modulen har nå handler-hashen, og brukes også til å trigge eventene:</p>
<div style="background-color: #000000; padding-left: 15px; margin-bottom: 20px; color: #f6f3e8"><font face="monospace"><span style="background-color: #000000"><font color="#3d3d3d">1 </font></span><font color="#96cbfe">module</font>&nbsp;<font color="#ffffb6">Events</font><br /><span style="background-color: #000000"><font color="#3d3d3d">2 </font></span>&nbsp; <font color="#96cbfe">def</font>&nbsp;<font color="#ffd2a7">add_handler</font> event, delegate<br /><span style="background-color: #000000"><font color="#3d3d3d">3 </font></span>&nbsp;&nbsp;&nbsp; <font color="#c6c5fe">@event_handlers</font> ||= {}<br /><span style="background-color: #000000"><font color="#3d3d3d">4 </font></span>&nbsp;&nbsp;&nbsp; (<font color="#c6c5fe">@event_handlers</font>[event] ||= []) &lt;&lt; delegate<br /><span style="background-color: #000000"><font color="#3d3d3d">5 </font></span>&nbsp; <font color="#96cbfe">end</font><br /><span style="background-color: #000000"><font color="#3d3d3d">6 </font></span>&nbsp; <font color="#96cbfe">def</font>&nbsp;<font color="#ffd2a7">raise_event</font> event, *args<br /><span style="background-color: #000000"><font color="#3d3d3d">7 </font></span>&nbsp;&nbsp;&nbsp; <font color="#c6c5fe">@event_handlers</font>[event].each {|<font color="#c6c5fe">d</font>| d.call(*args) } <font color="#6699cc">if</font>&nbsp;<font color="#c6c5fe">@event_handlers</font>[event]<br /><span style="background-color: #000000"><font color="#3d3d3d">8 </font></span>&nbsp; <font color="#96cbfe">end</font><br /><span style="background-color: #000000"><font color="#3d3d3d">9 </font></span><font color="#96cbfe">end</font><br /><span style="background-color: #000000"><font color="#3d3d3d">10 </font></span><br /><span style="background-color: #000000"><font color="#3d3d3d">11 </font></span><font color="#96cbfe">class</font>&nbsp;<font color="#ffffb6">Counter</font>&nbsp;<br /><span style="background-color: #000000"><font color="#3d3d3d">12 </font></span>&nbsp; <font color="#96cbfe">include</font>&nbsp;<font color="#ffffb6">Events</font><br /><span style="background-color: #000000"><font color="#3d3d3d">13 </font></span>&nbsp; <font color="#6699cc">attr_reader</font>&nbsp;<font color="#99cc99">:limit</font><br /><span style="background-color: #000000"><font color="#3d3d3d">14 </font></span>&nbsp; <font color="#96cbfe">def</font>&nbsp;<font color="#ffd2a7">initialize</font> limit<br /><span style="background-color: #000000"><font color="#3d3d3d">15 </font></span>&nbsp;&nbsp;&nbsp; <font color="#c6c5fe">@count</font>, <font color="#c6c5fe">@limit</font> = <font color="#ff73fd">0</font>, limit<br /><span style="background-color: #000000"><font color="#3d3d3d">16 </font></span>&nbsp; <font color="#96cbfe">end</font><br /><span style="background-color: #000000"><font color="#3d3d3d">17 </font></span>&nbsp; <font color="#96cbfe">def</font>&nbsp;<font color="#ffd2a7">on_limit_reached=</font> delegate<br /><span style="background-color: #000000"><font color="#3d3d3d">18 </font></span>&nbsp;&nbsp;&nbsp; add_handler(<font color="#99cc99">:limit_reached</font>, delegate)<br /><span style="background-color: #000000"><font color="#3d3d3d">19 </font></span>&nbsp; <font color="#96cbfe">end</font><br /><span style="background-color: #000000"><font color="#3d3d3d">20 </font></span>&nbsp; <font color="#96cbfe">def</font>&nbsp;<font color="#ffd2a7">on_increment</font> &amp;delegate<br /><span style="background-color: #000000"><font color="#3d3d3d">21 </font></span>&nbsp;&nbsp;&nbsp; add_handler(<font color="#99cc99">:increment</font>, delegate)<br /><span style="background-color: #000000"><font color="#3d3d3d">22 </font></span>&nbsp; <font color="#96cbfe">end</font><br /><span style="background-color: #000000"><font color="#3d3d3d">23 </font></span>&nbsp; <font color="#96cbfe">def</font>&nbsp;<font color="#ffd2a7">increment</font><br /><span style="background-color: #000000"><font color="#3d3d3d">24 </font></span>&nbsp;&nbsp;&nbsp; <font color="#c6c5fe">@count</font> += <font color="#ff73fd">1</font><br /><span style="background-color: #000000"><font color="#3d3d3d">25 </font></span>&nbsp;&nbsp;&nbsp; raise_event(<font color="#99cc99">:increment</font>, <font color="#99cc99">self</font>, <font color="#c6c5fe">@count</font>)<br /><span style="background-color: #000000"><font color="#3d3d3d">26 </font></span>&nbsp;&nbsp;&nbsp; raise_event(<font color="#99cc99">:limit_reached</font>) <font color="#6699cc">if</font>&nbsp;<font color="#c6c5fe">@count</font> == <font color="#c6c5fe">@limit</font>&nbsp;&nbsp; <br /><span style="background-color: #000000"><font color="#3d3d3d">27 </font></span>&nbsp; <font color="#96cbfe">end</font><br /><span style="background-color: #000000"><font color="#3d3d3d">28 </font></span><font color="#96cbfe">end</font><br /><span style="background-color: #000000"><font color="#3d3d3d">29 </font></span><br /><span style="background-color: #000000"><font color="#3d3d3d">30 </font></span>c = <font color="#ffffb6">Counter</font>.new(<font color="#ff73fd">5</font>) <font color="#7c7c7c"># create a new counter</font><br /><span style="background-color: #000000"><font color="#3d3d3d">31 </font></span>c.on_limit_reached = <font color="#96cbfe">lambda</font>{ puts <font color="#336633">&#8216;</font><font color="#a8ff60">Limit reached</font><font color="#336633">&#8216;</font> }<br /><span style="background-color: #000000"><font color="#3d3d3d">32 </font></span>c.on_increment <font color="#6699cc">do</font> |<font color="#c6c5fe">sender</font>, <font color="#c6c5fe">count</font>| <br /><span style="background-color: #000000"><font color="#3d3d3d">33 </font></span>&nbsp; puts <font color="#336633">&#8220;</font><font color="#a8ff60">Counter was incremented to </font><font color="#00a0a0">#{</font>count<font color="#00a0a0">}</font><font color="#336633">&#8220;</font><br /><span style="background-color: #000000"><font color="#3d3d3d">34 </font></span>&nbsp; puts <font color="#336633">&#8220;</font><font color="#00a0a0">#{</font>sender.limit - count<font color="#00a0a0">}</font><font color="#a8ff60"> left..</font><font color="#336633">&#8220;</font><br /><span style="background-color: #000000"><font color="#3d3d3d">35 </font></span><font color="#6699cc">end</font><br /><span style="background-color: #000000"><font color="#3d3d3d">36 </font></span><font color="#ff73fd">5</font>.times { c.increment }<br /></font></div>
<div style="margin-bottom: 20px"><font face="monospace">Output:<br />
<div style="padding-bottom: 5px; background-color: #000000; padding-left: 15px; color: lightgreen; padding-top: 5px">Counter was incremented to 1<br />4 left..<br />Counter was incremented to 2<br />3 left..<br />Counter was incremented to 3<br />2 left..<br />Counter was incremented to 4<br />1 left..<br />Counter was incremented to 5<br />0 left..<br />Limit reached</div>
<p></font></div>
<p>Jeg valgte også å endre litt på <em>on_increment</em> for å illustrere en annen måte å lage closures på, som nok er mere vanlig i Ruby. I stedet for å bruke lambda-metoden kan jeg nå lage en kodeblokk ved hjelp av &#8216;do&#8217; og &#8216;end&#8217; (do og end kan byttes ut med { og } om man foretrekker det). Jeg sender også med selve counter-objektet som et argument til handleren (&#8217;self&#8217; i linje 25 tilsvarer &#8216;this&#8217; i C#), som jeg så kan bruke til å beregne hvor mange increments som gjenstår – fordi jeg har definert en reader for limit-variabelen (linje 13).</p>
<h4>Iterasjon 5</h4>
<p>En annen approch jeg ville teste ut var å opprette en generisk Event-klasse. Jeg droppet da Events-modulen, selv om jeg kunne ha brukt dem i kombinasjon. I dette eksempelet har jeg sneket inn litt dynamisk evaluering også – se om du skjønner hva jeg gjør på linje 17 og 32.</p>
<div style="background-color: #000000; padding-left: 15px; margin-bottom: 20px; color: #f6f3e8"><font face="monospace"><span style="background-color: #000000"><font color="#3d3d3d">1 </font></span><font color="#96cbfe">class</font>&nbsp;<font color="#ffffb6">Event</font><br /><span style="background-color: #000000"><font color="#3d3d3d">2 </font></span>&nbsp; <font color="#96cbfe">def</font>&nbsp;<font color="#ffd2a7">initialize</font><br /><span style="background-color: #000000"><font color="#3d3d3d">3 </font></span>&nbsp;&nbsp;&nbsp; <font color="#c6c5fe">@handlers</font> = []<br /><span style="background-color: #000000"><font color="#3d3d3d">4 </font></span>&nbsp; <font color="#96cbfe">end</font><br /><span style="background-color: #000000"><font color="#3d3d3d">5 </font></span>&nbsp; <font color="#96cbfe">def</font>&nbsp;<font color="#ffd2a7">raise</font> *args<br /><span style="background-color: #000000"><font color="#3d3d3d">6 </font></span>&nbsp;&nbsp;&nbsp; <font color="#c6c5fe">@handlers</font>.each {|<font color="#c6c5fe">h</font>| h.call(*args)}<br /><span style="background-color: #000000"><font color="#3d3d3d">7 </font></span>&nbsp; <font color="#96cbfe">end</font><br /><span style="background-color: #000000"><font color="#3d3d3d">8 </font></span>&nbsp; <font color="#96cbfe">def</font>&nbsp;<font color="#ffd2a7">&lt;&lt;</font> handler<br /><span style="background-color: #000000"><font color="#3d3d3d">9 </font></span>&nbsp;&nbsp;&nbsp; <font color="#c6c5fe">@handlers</font> &lt;&lt; handler<br /><span style="background-color: #000000"><font color="#3d3d3d">10 </font></span>&nbsp; <font color="#96cbfe">end</font><br /><span style="background-color: #000000"><font color="#3d3d3d">11 </font></span><font color="#96cbfe">end</font><br /><span style="background-color: #000000"><font color="#3d3d3d">12 </font></span><br /><span style="background-color: #000000"><font color="#3d3d3d">13 </font></span><font color="#96cbfe">class</font>&nbsp;<font color="#ffffb6">Counter</font>&nbsp;<br /><span style="background-color: #000000"><font color="#3d3d3d">14 </font></span>&nbsp; <font color="#6699cc">attr_reader</font>&nbsp;<font color="#99cc99">:limit</font><br /><span style="background-color: #000000"><font color="#3d3d3d">15 </font></span>&nbsp; <font color="#96cbfe">def</font>&nbsp;<font color="#ffd2a7">initialize</font> limit<br /><span style="background-color: #000000"><font color="#3d3d3d">16 </font></span>&nbsp;&nbsp;&nbsp; <font color="#c6c5fe">@count</font>, <font color="#c6c5fe">@limit</font> = <font color="#ff73fd">0</font>, limit<br /><span style="background-color: #000000"><font color="#3d3d3d">17 </font></span>&nbsp;&nbsp;&nbsp; events <font color="#99cc99">:limit_reached</font>, <font color="#99cc99">:increment</font><br /><span style="background-color: #000000"><font color="#3d3d3d">18 </font></span>&nbsp; <font color="#96cbfe">end</font><br /><span style="background-color: #000000"><font color="#3d3d3d">19 </font></span>&nbsp; <font color="#96cbfe">def</font>&nbsp;<font color="#ffd2a7">on_limit_reached=</font> delegate<br /><span style="background-color: #000000"><font color="#3d3d3d">20 </font></span>&nbsp;&nbsp;&nbsp; <font color="#c6c5fe">@limit_reached</font> &lt;&lt; delegate<br /><span style="background-color: #000000"><font color="#3d3d3d">21 </font></span>&nbsp; <font color="#96cbfe">end</font><br /><span style="background-color: #000000"><font color="#3d3d3d">22 </font></span>&nbsp; <font color="#96cbfe">def</font>&nbsp;<font color="#ffd2a7">on_increment</font> &amp;delegate<br /><span style="background-color: #000000"><font color="#3d3d3d">23 </font></span>&nbsp;&nbsp;&nbsp; <font color="#c6c5fe">@increment</font> &lt;&lt; delegate<br /><span style="background-color: #000000"><font color="#3d3d3d">24 </font></span>&nbsp; <font color="#96cbfe">end</font><br /><span style="background-color: #000000"><font color="#3d3d3d">25 </font></span>&nbsp; <font color="#96cbfe">def</font>&nbsp;<font color="#ffd2a7">increment</font><br /><span style="background-color: #000000"><font color="#3d3d3d">26 </font></span>&nbsp;&nbsp;&nbsp; <font color="#c6c5fe">@count</font> += <font color="#ff73fd">1</font><br /><span style="background-color: #000000"><font color="#3d3d3d">27 </font></span>&nbsp;&nbsp;&nbsp; <font color="#c6c5fe">@increment</font>.raise(<font color="#99cc99">self</font>, <font color="#c6c5fe">@count</font>)<br /><span style="background-color: #000000"><font color="#3d3d3d">28 </font></span>&nbsp;&nbsp;&nbsp; <font color="#c6c5fe">@limit_reached</font>.raise <font color="#6699cc">if</font>&nbsp;<font color="#c6c5fe">@count</font> == <font color="#c6c5fe">@limit</font>&nbsp;&nbsp;&nbsp; <br /><span style="background-color: #000000"><font color="#3d3d3d">29 </font></span>&nbsp; <font color="#96cbfe">end</font><br /><span style="background-color: #000000"><font color="#3d3d3d">30 </font></span>&nbsp; <font color="#6699cc">private</font><br /><span style="background-color: #000000"><font color="#3d3d3d">31 </font></span>&nbsp; <font color="#96cbfe">def</font>&nbsp;<font color="#ffd2a7">events</font> *attr<br /><span style="background-color: #000000"><font color="#3d3d3d">32 </font></span>&nbsp;&nbsp;&nbsp; attr.each {|<font color="#c6c5fe">e</font>| <font color="#6699cc">eval</font>(<font color="#336633">&#8220;</font><font color="#a8ff60">@</font><font color="#00a0a0">#{</font>e<font color="#00a0a0">}</font><font color="#a8ff60"> = Event.new</font><font color="#336633">&#8220;</font>)}<br /><span style="background-color: #000000"><font color="#3d3d3d">33 </font></span>&nbsp; <font color="#96cbfe">end</font><br /><span style="background-color: #000000"><font color="#3d3d3d">34 </font></span><font color="#96cbfe">end</font><br /><span style="background-color: #000000"><font color="#3d3d3d">35 </font></span><br /><span style="background-color: #000000"><font color="#3d3d3d">36 </font></span>c = <font color="#ffffb6">Counter</font>.new(<font color="#ff73fd">5</font>) <font color="#7c7c7c"># create a new counter</font><br /><span style="background-color: #000000"><font color="#3d3d3d">37 </font></span>c.on_limit_reached = <font color="#96cbfe">lambda</font>{ puts <font color="#336633">&#8216;</font><font color="#a8ff60">Limit reached</font><font color="#336633">&#8216;</font> }<br /><span style="background-color: #000000"><font color="#3d3d3d">38 </font></span>c.on_increment <font color="#6699cc">do</font> |<font color="#c6c5fe">sender</font>, <font color="#c6c5fe">count</font>| <br /><span style="background-color: #000000"><font color="#3d3d3d">39 </font></span>&nbsp; puts <font color="#336633">&#8220;</font><font color="#a8ff60">Counter was incremented to </font><font color="#00a0a0">#{</font>count<font color="#00a0a0">}</font><font color="#336633">&#8220;</font><br /><span style="background-color: #000000"><font color="#3d3d3d">40 </font></span>&nbsp; puts <font color="#336633">&#8220;</font><font color="#00a0a0">#{</font>sender.limit - count<font color="#00a0a0">}</font><font color="#a8ff60"> left..</font><font color="#336633">&#8220;</font><br /><span style="background-color: #000000"><font color="#3d3d3d">41 </font></span><font color="#6699cc">end</font><br /><span style="background-color: #000000"><font color="#3d3d3d">42 </font></span><font color="#ff73fd">5</font>.times { c.increment }<br /></font></div>
<div style="margin-bottom: 20px"><font face="monospace">(Output som i iterasjon 4)</font></div>
<div style="margin-bottom: 20px">Jeg håper dette fungerte som eksempler på hvordan man kan kode med events i Ruby, og at du lærte litt underveis. Spørsmål til koden mottas og besvares med største fornøyelse.</div>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/kjempekjektcom?a=cdhirV984P0:b7YbKQNmcZ8:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/kjempekjektcom?i=cdhirV984P0:b7YbKQNmcZ8:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/kjempekjektcom?a=cdhirV984P0:b7YbKQNmcZ8:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/kjempekjektcom?d=yIl2AUoC8zA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/kjempekjektcom/~4/cdhirV984P0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRSS>http://blog.kjempekjekt.com/2010/03/09/events-i-ruby/feed/</wfw:commentRSS>
		<feedburner:origLink>http://blog.kjempekjekt.com/2010/03/09/events-i-ruby/</feedburner:origLink></item>
		<item>
		<title>Slette/tømme MSMQ-køer med IronRuby</title>
		<link>http://feedproxy.google.com/~r/kjempekjektcom/~3/7HuiYntEOMc/</link>
		<comments>http://blog.kjempekjekt.com/2010/03/07/slettetmme-msmq-ker-med-ironruby/#comments</comments>
		<pubDate>Sun, 07 Mar 2010 20:44:25 +0000</pubDate>
		<dc:creator>Torbjørn</dc:creator>
		
	<category>Jobb</category>
	<category>Ruby</category>
		<guid isPermaLink="false">http://blog.kjempekjekt.com/2010/03/07/slettetmme-msmq-ker-med-ironruby/</guid>
		<description><![CDATA[Utviklingsavdelingen i PSWinCom har akkurat begynt å lære seg Ruby, og jeg har derfor kodet noen scripts som jeg har dokumentert ganske grundig - sånn at det går an å lære noe av å lese dem. Dette er et faktisk IronRuby-script jeg bruker for å slette eller tømme alle private MSMQ-køer på lokal maskin (vi [...]]]></description>
			<content:encoded><![CDATA[<p>Utviklingsavdelingen i <a href="http://pswin.com">PSWinCom</a> har akkurat begynt å lære seg <a href="http://www.ruby-lang.org/en/" target="_blank">Ruby</a>, og jeg har derfor kodet noen scripts som jeg har dokumentert ganske grundig - sånn at det går an å lære noe av å lese dem. Dette er et faktisk IronRuby-script jeg bruker for å slette eller tømme alle private <a href="http://en.wikipedia.org/wiki/Microsoft_Message_Queuing">MSMQ</a>-køer på lokal maskin (vi jobber mye med køer, og trenger ofte å rydde opp miljøet). </p>
<p>Så i tilfelle dette kan hjelpe andre – her er koden:</p>
<div style="padding-bottom: 15px; background-color: #000000; padding-left: 15px; margin-bottom: 20px; color: #f6f3e8"><font face="monospace"><span style="background-color: #000000"><font color="#3d3d3d">&nbsp; 1 </font></span><font color="#7c7c7c">=begin</font><br /><span style="background-color: #000000"><font color="#3d3d3d">&nbsp; 2 </font></span><font color="#7c7c7c">&nbsp; This is a comment <img src='http://blog.kjempekjekt.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </font><br /><span style="background-color: #000000"><font color="#3d3d3d">&nbsp; 3 </font></span><br /><span style="background-color: #000000"><font color="#3d3d3d">&nbsp; 4 </font></span><font color="#7c7c7c">&nbsp; Ruby scans scripts from top to bottom. This means it should make </font><br /><span style="background-color: #000000"><font color="#3d3d3d">&nbsp; 5 </font></span><font color="#7c7c7c">&nbsp; sense when you to read it that way too.</font><br /><span style="background-color: #000000"><font color="#3d3d3d">&nbsp; 6 </font></span><br /><span style="background-color: #000000"><font color="#3d3d3d">&nbsp; 7 </font></span><font color="#7c7c7c">&nbsp; The scull and bones art is contained in something called a </font><br /><span style="background-color: #000000"><font color="#3d3d3d">&nbsp; 8 </font></span><font color="#7c7c7c">&nbsp; here-document. Google it if you want to know more&#8230;</font><br /><span style="background-color: #000000"><font color="#3d3d3d">&nbsp; 9 </font></span><font color="#7c7c7c">&nbsp; </font><br /><span style="background-color: #000000"><font color="#3d3d3d">10 </font></span><font color="#7c7c7c">&nbsp; (I had to escape the backslashes, so it looks a bit off in the</font><br /><span style="background-color: #000000"><font color="#3d3d3d">11 </font></span><font color="#7c7c7c">&nbsp; source, but the output should be nice.)</font><br /><span style="background-color: #000000"><font color="#3d3d3d">12 </font></span><font color="#7c7c7c">=end</font><br /><span style="background-color: #000000"><font color="#3d3d3d">13 </font></span>puts &lt;&lt;<font color="#336633">EOF</font><br /><span style="background-color: #000000"><font color="#3d3d3d">14 </font></span><font color="#a8ff60">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _______________</font><br /><span style="background-color: #000000"><font color="#3d3d3d">15 </font></span><font color="#a8ff60">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font color="#e18964">\\</font><font color="#a8ff60">&nbsp;</font><br /><span style="background-color: #000000"><font color="#3d3d3d">16 </font></span><font color="#a8ff60">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font color="#e18964">\\</font><font color="#a8ff60">&nbsp;</font><br /><span style="background-color: #000000"><font color="#3d3d3d">17 </font></span><font color="#a8ff60">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font color="#e18964">\\</font><font color="#a8ff60">&nbsp;</font><br /><span style="background-color: #000000"><font color="#3d3d3d">18 </font></span><font color="#a8ff60">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp; XXXX&nbsp;&nbsp;&nbsp;&nbsp; XXXX&nbsp;&nbsp; | </font><br /><span style="background-color: #000000"><font color="#3d3d3d">19 </font></span><font color="#a8ff60">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp; XXXX&nbsp;&nbsp;&nbsp;&nbsp; XXXX&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PSWinCom MSMQ IronRuby script</font><br /><span style="background-color: #000000"><font color="#3d3d3d">20 </font></span><font color="#a8ff60">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp; XXX&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XXX&nbsp;&nbsp; | </font><br /><span style="background-color: #000000"><font color="#3d3d3d">21 </font></span><font color="#a8ff60">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; X&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;</font><br /><span style="background-color: #000000"><font color="#3d3d3d">22 </font></span><font color="#a8ff60">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font color="#e18964">\\</font><font color="#a8ff60">__&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XXX&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; __/</font><br /><span style="background-color: #000000"><font color="#3d3d3d">23 </font></span><font color="#a8ff60">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |</font><font color="#e18964">\\</font><font color="#a8ff60">&nbsp;&nbsp;&nbsp;&nbsp; XXX&nbsp;&nbsp;&nbsp;&nbsp; /|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A L L&nbsp;&nbsp; Q U E U E S</font><br /><span style="background-color: #000000"><font color="#3d3d3d">24 </font></span><font color="#a8ff60">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | |</font><br /><span style="background-color: #000000"><font color="#3d3d3d">25 </font></span><font color="#a8ff60">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | I I I I I I I |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;</font><br /><span style="background-color: #000000"><font color="#3d3d3d">26 </font></span><font color="#a8ff60">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp; I I I I I I&nbsp; |</font><br /><span style="background-color: #000000"><font color="#3d3d3d">27 </font></span><font color="#a8ff60">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font color="#e18964">\\</font><font color="#a8ff60">_&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _/&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Hope you know what you&#8217;re doing</font><br /><span style="background-color: #000000"><font color="#3d3d3d">28 </font></span><font color="#a8ff60">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font color="#e18964">\\</font><font color="#a8ff60">_&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _/</font><br /><span style="background-color: #000000"><font color="#3d3d3d">29 </font></span><font color="#a8ff60">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font color="#e18964">\\</font><font color="#a8ff60">_______/</font><br /><span style="background-color: #000000"><font color="#3d3d3d">30 </font></span><font color="#a8ff60">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XXX&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XXX</font><br /><span style="background-color: #000000"><font color="#3d3d3d">31 </font></span><font color="#a8ff60">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XXXXX&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XXXXX</font><br /><span style="background-color: #000000"><font color="#3d3d3d">32 </font></span><font color="#a8ff60">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XXXXXXXXX&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XXXXXXXXXX</font><br /><span style="background-color: #000000"><font color="#3d3d3d">33 </font></span><font color="#a8ff60">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XXXXX&nbsp;&nbsp; XXXXX</font><br /><span style="background-color: #000000"><font color="#3d3d3d">34 </font></span><font color="#a8ff60">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XXXXXXX</font><br /><span style="background-color: #000000"><font color="#3d3d3d">35 </font></span><font color="#a8ff60">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XXXXX&nbsp;&nbsp; XXXXX</font><br /><span style="background-color: #000000"><font color="#3d3d3d">36 </font></span><font color="#a8ff60">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XXXXXXXXX&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XXXXXXXXXX</font><br /><span style="background-color: #000000"><font color="#3d3d3d">37 </font></span><font color="#a8ff60">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XXXXX&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XXXXX</font><br /><span style="background-color: #000000"><font color="#3d3d3d">38 </font></span><font color="#a8ff60">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XXX&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XXX</font><br /><span style="background-color: #000000"><font color="#3d3d3d">39 </font></span><br /><span style="background-color: #000000"><font color="#3d3d3d">40 </font></span><font color="#336633">EOF</font><br /><span style="background-color: #000000"><font color="#3d3d3d">41 </font></span><br /><span style="background-color: #000000"><font color="#3d3d3d">42 </font></span><font color="#7c7c7c">=begin</font><br /><span style="background-color: #000000"><font color="#3d3d3d">43 </font></span><font color="#7c7c7c">&nbsp; The Actions class contains a method for each of the available</font><br /><span style="background-color: #000000"><font color="#3d3d3d">44 </font></span><font color="#7c7c7c">&nbsp; command line options. To add another option it should be enough</font><br /><span style="background-color: #000000"><font color="#3d3d3d">45 </font></span><font color="#7c7c7c">&nbsp; to expand this class with a new method.</font><br /><span style="background-color: #000000"><font color="#3d3d3d">46 </font></span><font color="#7c7c7c">=end</font><br /><span style="background-color: #000000"><font color="#3d3d3d">47 </font></span><font color="#96cbfe">class</font>&nbsp;<font color="#ffffb6">Actions</font><br /><span style="background-color: #000000"><font color="#3d3d3d">48 </font></span>&nbsp; <font color="#7c7c7c"># You create &#8220;static&#8221; methods (we actually call it class methods) </font><br /><span style="background-color: #000000"><font color="#3d3d3d">49 </font></span>&nbsp; <font color="#7c7c7c"># by applying &#8217;self.&#8217; in front of the method name. Here self refer</font><br /><span style="background-color: #000000"><font color="#3d3d3d">50 </font></span>&nbsp; <font color="#7c7c7c"># to the class, and it could also be written ClassName.method_name.</font><br /><span style="background-color: #000000"><font color="#3d3d3d">51 </font></span>&nbsp; <font color="#96cbfe">def</font>&nbsp;<font color="#99cc99">self</font>.<font color="#ffd2a7">list</font> queue <font color="#7c7c7c"># method named &#8220;list&#8221;, takes one argument &#8220;queue&#8221; </font><br /><span style="background-color: #000000"><font color="#3d3d3d">52 </font></span>&nbsp;&nbsp;&nbsp; puts queue.path<br /><span style="background-color: #000000"><font color="#3d3d3d">53 </font></span>&nbsp; <font color="#96cbfe">end</font><br /><span style="background-color: #000000"><font color="#3d3d3d">54 </font></span>&nbsp; <font color="#96cbfe">def</font>&nbsp;<font color="#99cc99">self</font>.<font color="#ffd2a7">delete</font> queue<br /><span style="background-color: #000000"><font color="#3d3d3d">55 </font></span>&nbsp;&nbsp;&nbsp; puts <font color="#336633">&#8220;</font><font color="#a8ff60">Deleting </font><font color="#00a0a0">#{</font>queue.path<font color="#00a0a0">}</font><font color="#a8ff60">..</font><font color="#336633">&#8220;</font><br /><span style="background-color: #000000"><font color="#3d3d3d">56 </font></span>&nbsp;&nbsp;&nbsp; <font color="#ffffb6">MessageQueue</font>.delete queue.path<br /><span style="background-color: #000000"><font color="#3d3d3d">57 </font></span>&nbsp; <font color="#96cbfe">end</font><br /><span style="background-color: #000000"><font color="#3d3d3d">58 </font></span>&nbsp; <font color="#96cbfe">def</font>&nbsp;<font color="#99cc99">self</font>.<font color="#ffd2a7">purge</font> queue<br /><span style="background-color: #000000"><font color="#3d3d3d">59 </font></span>&nbsp;&nbsp;&nbsp; puts <font color="#336633">&#8220;</font><font color="#a8ff60">Purging </font><font color="#00a0a0">#{</font>queue.path<font color="#00a0a0">}</font><font color="#a8ff60">..</font><font color="#336633">&#8220;</font><br /><span style="background-color: #000000"><font color="#3d3d3d">60 </font></span>&nbsp;&nbsp;&nbsp; queue.purge<br /><span style="background-color: #000000"><font color="#3d3d3d">61 </font></span>&nbsp; <font color="#96cbfe">end</font><br /><span style="background-color: #000000"><font color="#3d3d3d">62 </font></span>&nbsp; <font color="#96cbfe">def</font>&nbsp;<font color="#99cc99">self</font>.<font color="#ffd2a7">exit</font><br /><span style="background-color: #000000"><font color="#3d3d3d">63 </font></span>&nbsp;&nbsp;&nbsp; puts <font color="#336633">&#8220;</font><font color="#a8ff60">Usage: ir all_queues.rb action</font><font color="#336633">&#8220;</font><br /><span style="background-color: #000000"><font color="#3d3d3d">64 </font></span>&nbsp;&nbsp;&nbsp; puts <font color="#336633">&#8220;</font><font color="#a8ff60">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; where action in [list|delete|purge]</font><font color="#336633">&#8220;</font><br /><span style="background-color: #000000"><font color="#3d3d3d">65 </font></span>&nbsp;&nbsp;&nbsp; <font color="#ffffb6">Kernel</font>.exit(<font color="#ff73fd">0</font>) <font color="#7c7c7c"># This is a nice way of ending a script</font><br /><span style="background-color: #000000"><font color="#3d3d3d">66 </font></span>&nbsp; <font color="#96cbfe">end</font><br /><span style="background-color: #000000"><font color="#3d3d3d">67 </font></span><font color="#96cbfe">end</font>&nbsp;<font color="#7c7c7c"># class Actions ends here..</font><br /><span style="background-color: #000000"><font color="#3d3d3d">68 </font></span><br /><span style="background-color: #000000"><font color="#3d3d3d">69 </font></span><font color="#7c7c7c">=begin</font><br /><span style="background-color: #000000"><font color="#3d3d3d">70 </font></span><font color="#7c7c7c">&nbsp; The rest of the script is not contained in a class. You may feel dirty</font><br /><span style="background-color: #000000"><font color="#3d3d3d">71 </font></span><font color="#7c7c7c">&nbsp; the first couple of times you do this, but it&#8217;s fine - I promise!</font><br /><span style="background-color: #000000"><font color="#3d3d3d">72 </font></span><font color="#7c7c7c">=end</font><br /><span style="background-color: #000000"><font color="#3d3d3d">73 </font></span><br /><span style="background-color: #000000"><font color="#3d3d3d">74 </font></span>mode = <font color="#c6c5fe">$*</font>.shift <font color="#7c7c7c"># get the first command line option passed to this script</font><br /><span style="background-color: #000000"><font color="#3d3d3d">75 </font></span><font color="#ffffb6">Actions</font>.exit <font color="#6699cc">unless</font> mode <font color="#7c7c7c"># call exit if no mode (if mode == nil)</font><br /><span style="background-color: #000000"><font color="#3d3d3d">76 </font></span><br /><span style="background-color: #000000"><font color="#3d3d3d">77 </font></span><font color="#7c7c7c">=begin</font><br /><span style="background-color: #000000"><font color="#3d3d3d">78 </font></span><font color="#7c7c7c">&nbsp; Load the .Net dll.</font><br /><span style="background-color: #000000"><font color="#3d3d3d">79 </font></span><font color="#7c7c7c">&nbsp; This is the only line of the script that will look strange to a normal </font><br /><span style="background-color: #000000"><font color="#3d3d3d">80 </font></span><font color="#7c7c7c">&nbsp; Ruby-developer that haven&#8217;t used IronRuby.</font><br /><span style="background-color: #000000"><font color="#3d3d3d">81 </font></span><font color="#7c7c7c">=end</font><br /><span style="background-color: #000000"><font color="#3d3d3d">82 </font></span>load_assembly <font color="#336633">&#8216;</font><font color="#a8ff60">System.Messaging</font><font color="#336633">&#8216;</font><br /><span style="background-color: #000000"><font color="#3d3d3d">83 </font></span><br /><span style="background-color: #000000"><font color="#3d3d3d">84 </font></span><font color="#7c7c7c">=begin</font><br /><span style="background-color: #000000"><font color="#3d3d3d">85 </font></span><font color="#7c7c7c">&nbsp; By including the System::Messaging namespace in this script, I&#8217;m able to</font><br /><span style="background-color: #000000"><font color="#3d3d3d">86 </font></span><font color="#7c7c7c">&nbsp; use the classes in the namespace directly. If I hadn&#8217;t done this I would</font><br /><span style="background-color: #000000"><font color="#3d3d3d">87 </font></span><font color="#7c7c7c">&nbsp; have to use System::Messaging::MessageQueue instead of just MessageQueue.</font><br /><span style="background-color: #000000"><font color="#3d3d3d">88 </font></span><br /><span style="background-color: #000000"><font color="#3d3d3d">89 </font></span><font color="#7c7c7c">&nbsp; Notice that when Ruby was parsing the Actions class, which use the</font><br /><span style="background-color: #000000"><font color="#3d3d3d">90 </font></span><font color="#7c7c7c">&nbsp; MessageQueue class, the System.Messaging.dll was not jet loaded, and the</font><br /><span style="background-color: #000000"><font color="#3d3d3d">91 </font></span><font color="#7c7c7c">&nbsp; namespace not yet included. That is fine however - when actual execution</font><br /><span style="background-color: #000000"><font color="#3d3d3d">92 </font></span><font color="#7c7c7c">&nbsp; enters the Actions class&#8217;s queue methods (when the methods are called), </font><br /><span style="background-color: #000000"><font color="#3d3d3d">93&nbsp;&nbsp; </font></span><font color="#7c7c7c">the namespace will be there. </font><br /><span style="background-color: #000000"><font color="#3d3d3d">94 </font></span><font color="#7c7c7c">=end</font><br /><span style="background-color: #000000"><font color="#3d3d3d">95 </font></span><font color="#96cbfe">include</font>&nbsp;<font color="#ffffb6">System</font>::<font color="#ffffb6">Messaging</font><br /><span style="background-color: #000000"><font color="#3d3d3d">96 </font></span><br /><span style="background-color: #000000"><font color="#3d3d3d">97 </font></span><font color="#7c7c7c">=begin</font><br /><span style="background-color: #000000"><font color="#3d3d3d">98 </font></span><font color="#7c7c7c">&nbsp; Getting queues. MessageQueue.get_private_queues_by_machine in ruby corresponds</font><br /><span style="background-color: #000000"><font color="#3d3d3d">99 </font></span><font color="#7c7c7c">&nbsp; to MessageQueue.GetPrivateQueuesByMachine in C#.</font><br /><span style="background-color: #000000"><font color="#3d3d3d">100 </font></span><font color="#7c7c7c">=end</font><br /><span style="background-color: #000000"><font color="#3d3d3d">101 </font></span>all_queues = <font color="#ffffb6">MessageQueue</font>.get_private_queues_by_machine(<font color="#336633">&#8216;</font><font color="#a8ff60">.</font><font color="#336633">&#8216;</font>) <font color="#7c7c7c"># &#8216;.&#8217; == local machine</font><br /><span style="background-color: #000000"><font color="#3d3d3d">102 </font></span><br /><span style="background-color: #000000"><font color="#3d3d3d">103 </font></span><font color="#7c7c7c"># Let user know if there are no queues to perform action on</font><br /><span style="background-color: #000000"><font color="#3d3d3d">104 </font></span>puts <font color="#336633">&#8220;</font><font color="#a8ff60">No queues available</font><font color="#336633">&#8220;</font>&nbsp;<font color="#6699cc">if</font> all_queues.length == <font color="#ff73fd">0</font><br /><span style="background-color: #000000"><font color="#3d3d3d">105 </font></span><br /><span style="background-color: #000000"><font color="#3d3d3d">106 </font></span><font color="#7c7c7c">=begin</font><br /><span style="background-color: #000000"><font color="#3d3d3d">107 </font></span><font color="#7c7c7c">&nbsp; The following line is very similar to C#&#8217;s List&lt;T&gt;.ForEach(Action&lt;T&gt; action).</font><br /><span style="background-color: #000000"><font color="#3d3d3d">108 </font></span><font color="#7c7c7c">&nbsp; For each queue I call the appropriate action. I do this by sending the </font><br /><span style="background-color: #000000"><font color="#3d3d3d">109 </font></span><font color="#7c7c7c">&nbsp; command line option (mode) as a message to the Actions class. The method</font><br /><span style="background-color: #000000"><font color="#3d3d3d">110 </font></span><font color="#7c7c7c">&nbsp; with the correct name will be called. The second argument will become the</font><br /><span style="background-color: #000000"><font color="#3d3d3d">111 </font></span><font color="#7c7c7c">&nbsp; argument to the actual method.</font><br /><span style="background-color: #000000"><font color="#3d3d3d">112 </font></span><font color="#7c7c7c">=end</font><br /><span style="background-color: #000000"><font color="#3d3d3d">113 </font></span>all_queues.each {|<font color="#c6c5fe">queue</font>| <font color="#ffffb6">Actions</font>.send(mode, queue) }<br /><span style="background-color: #000000"><font color="#3d3d3d">114 </font></span><br /><span style="background-color: #000000"><font color="#3d3d3d">115 </font></span>puts <font color="#336633">&#8216;</font><font color="#a8ff60">.</font><font color="#336633">&#8216;</font>&nbsp;<font color="#7c7c7c"># Just an end-of-program indicator</font><br /></font></div>
<p>For å for eksempel liste alle køene eksekverer man <tt>&#8220;ir all_queues.rb list&#8221;</tt> i kommandolinjen (all_queues.rb er navnet på skriptet og <em>ir</em> er IronRuby). Skriptet benyttes på egen rissiko, jeg tar ikke ansvar for tapte data eller andre problemer som måtte oppstå <img src='http://blog.kjempekjekt.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/kjempekjektcom?a=7HuiYntEOMc:wL1_fn-ZJB8:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/kjempekjektcom?i=7HuiYntEOMc:wL1_fn-ZJB8:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/kjempekjektcom?a=7HuiYntEOMc:wL1_fn-ZJB8:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/kjempekjektcom?d=yIl2AUoC8zA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/kjempekjektcom/~4/7HuiYntEOMc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRSS>http://blog.kjempekjekt.com/2010/03/07/slettetmme-msmq-ker-med-ironruby/feed/</wfw:commentRSS>
		<feedburner:origLink>http://blog.kjempekjekt.com/2010/03/07/slettetmme-msmq-ker-med-ironruby/</feedburner:origLink></item>
		<item>
		<title>Hvilket dynamiske programmeringspråk du skal lære deg</title>
		<link>http://feedproxy.google.com/~r/kjempekjektcom/~3/3h2xqUC35Xo/</link>
		<comments>http://blog.kjempekjekt.com/2010/03/05/hvilket-dynamiske-programmeringsprk-du-skal-lre-deg/#comments</comments>
		<pubDate>Thu, 04 Mar 2010 22:14:14 +0000</pubDate>
		<dc:creator>Torbjørn</dc:creator>
		
	<category>Polyglot</category>
		<guid isPermaLink="false">http://blog.kjempekjekt.com/2010/03/05/hvilket-dynamiske-programmeringsprk-du-skal-lre-deg/</guid>
		<description><![CDATA[Sett at jeg har overtalt deg til å lære dynamisk programmering, f.eks. da du leste artikkelen om at du MÅ beherkse et dynamisk språk. Spørsmålet du stiller deg da er: Hvilket språk skal jeg velge? Og jeg hjelper deg gjerne med det også.
Her finner du en oversikt over det som i dag er de mest [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Sett at jeg har overtalt deg til å lære dynamisk programmering, f.eks. da du leste artikkelen om at <a href="http://blog.kjempekjekt.com/2010/03/03/du-m-beherske-et-dynamisk-sprk/">du MÅ beherkse et dynamisk språk</a>. Spørsmålet du stiller deg da er: <em>Hvilket språk skal jeg velge?</em> Og jeg hjelper deg gjerne med det også.</strong></p>
<p>Her finner du en oversikt over det som i dag er de mest populære, dynamiske programmeringsspråkene, sammen med mine meninger om hvilke egenskaper de har, og hvorfor du eventuelt skal velge dem. De er sortert etter popularitet – de mest omtalte og brukte språkene er på toppen av listen. Ta gjerne en titt på blogposten om <a href="http://blog.kjempekjekt.com/2010/01/20/programmeringssprk-trender-2010/">trender innen programmeringsspråk i 2010</a> om du vil se nærmere på rangeringen.</p>
<h4>PHP</h4>
<p><img style="border-right-width: 0px; margin: 0px 0px 5px 15px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="php_logo" border="0" alt="php_logo" align="right" src="http://blog.kjempekjekt.com/wp-content/uploads/2010/03/php_logo.png" width="90" height="47"> PHP er for tiden på tredjeplass i TIOBE&#8217;s liste over populære programmeringsspråk. Men for guds skyld – ikke velg PHP til å lære deg dynamisk programmering! Det du gjør i PHP kan du få til i språk som Python og Ruby om du vil, men det fungerer ikke den andre veien. Har du behov for å utvikle i PHP så lærer du deg det i tillegg, men ikke som en erstatning for en orntlig språk. Det er med på denne listen for kompletthets skyld, og kun det. </p>
<p>Mulig jeg ikke vet hva jeg snakker om, men la oss uansett gå raskt gå videre…</p>
<h4>Python </h4>
<p><img style="border-right-width: 0px; margin: 0px 0px 5px 15px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="python_logo" border="0" alt="python_logo" align="right" src="http://blog.kjempekjekt.com/wp-content/uploads/2010/03/python_logo.png" width="200" height="60"> <strong><em>Python</em></strong> er et programmeringsspråk som så verdens lys sent på 80-tallet. Python-kode er svært konsis, legger vekt på lesbarhet, og har en syntaks som appellerer til mange utviklere. Det er et objektorientert språk, men støtter også det funksjonsbasert paradigmen. I motsetning til de fleste andre språk legger python betydning i innrykk – man bruker indentering for å angi blokker/programstruktur, og behøver derfor ikke avslutte klasser, metoder osv med &#8220;end&#8221; eller krøllparantes eller lignende.</p>
<p>Her er en <em>Hello World</em>-klasse i Python, og bruken av den for å skrive ut &#8220;Hello, T-Man&#8221;. Den kompakte stilen er herlig!</p>
<div style="background-color: #eeeeee; margin-bottom: 15px"><font face="monospace"><span style="background-color: #dddddd"><font color="#444444">&nbsp;&nbsp;&nbsp; 1 </font></span><font color="#111111"><b>class</b></font>&nbsp;<font color="#990000"><b>Greeter</b></font>:<br /><span style="background-color: #dddddd"><font color="#444444">&nbsp;&nbsp;&nbsp; 2 </font></span>&nbsp; <font color="#111111"><b>def</b></font>&nbsp;<font color="#990000"><b>hello</b></font>(self, name):<br /><span style="background-color: #dddddd"><font color="#444444">&nbsp;&nbsp;&nbsp; 3 </font></span>&nbsp;&nbsp;&nbsp; <font color="#111111"><b>print</b></font>&nbsp;<span style="background-color: #eeeeee"><font color="#000000">&#8216;</font></span><font color="#dd1144">Hello,</font><span style="background-color: #eeeeee"><font color="#000000">&#8216;</font></span>, name<br /><span style="background-color: #dddddd"><font color="#444444">&nbsp;&nbsp;&nbsp; 4 </font></span><br /><span style="background-color: #dddddd"><font color="#444444">&nbsp;&nbsp;&nbsp; 5 </font></span>g = Greeter()<br /><span style="background-color: #dddddd"><font color="#444444">&nbsp;&nbsp;&nbsp; 6 </font></span>g.hello(<span style="background-color: #eeeeee"><font color="#000000">&#8216;</font></span><font color="#dd1144">T-Man</font><span style="background-color: #eeeeee"><font color="#000000">&#8216;</font></span>)<br /></font></div>
<p>I tillegg til den vanlige implementasjonen i C, finnes Python også på .Net-plattformen i form av IronPython og på Java-plattformen i form av Jython. Om man behersker Python kan man dermed utnytte dynamisk programmering der også, noe som bør appelere til eksisterende .Net eller Java-utviklere.</p>
<p>Dessuten er Python det primære språket på <a href="http://code.google.com/intl/nb-NO/appengine/">Google App Engine</a>, så hvis du vil utnytte den plattformen kan det være et lurt valg (selv om App Engine nå også støtter Java-plattformen, inkludert alle språkene som kjører der). Python er mye brukt til webutvikling generelt, og det mest populære rammeverket for denslags ser ut til å være <a href="http://www.djangoproject.com/">django</a> – <em>The Web framework for perfectionists with deadlines</em>.</p>
<p>Vil du vite mer om Python tar du turen til <a href="http://www.python.org/">python.org</a>.</p>
<h4>Perl</h4>
<p><img style="border-right-width: 0px; margin: 0px 0px 5px 15px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="perl_logo" border="0" alt="perl_logo" align="right" src="http://blog.kjempekjekt.com/wp-content/uploads/2010/03/perl_logo.png" width="100" height="106">Da <strong><em>Perl</em></strong> dukket opp i 1987 var det som et skriptspråk for UNIX, og det er kjent for å ha en spesiell styrke når det kommer til prosessering av tekst. Språket har siden utviklet seg en god del, og har influert en rekke andre språk, som f.eks. Python og Ruby. Perl kalles <em>&#8220;the Swiss Army chainsaw of programming languages&#8221;</em>.</p>
<p>Jeg våger meg ikke på noe eksempel-kode, da jeg aldri har kodet en linje Perl i hele mitt liv. Min oppfatning er at Perl er litt utdatert, men om du har lyst til å ta en titt vil du finne det du trenger på <a href="http://www.perl.org/">perl.org</a>.</p>
<h4>JavaScript</h4>
<p>Vi har alle brukt det, om ikke mer så har de fleste av oss i alle fall klippet og limt snutter fra nettet. Men JavaScript er faktisk et spennende, dynamisk språk som brukes til mer enn bare klientside-funksjonalitet i websider. Det finnes en rekke avarter som f.eks. <a href="http://en.wikipedia.org/wiki/ActionScript">ActionScript</a> i Adobe Flash, <a href="http://en.wikipedia.org/wiki/JScript">JScript</a> på Microsoft-plattformen m.m. Man kan bruke JavaScript som skriptspråk i OpenOffice, og med verktøy som <a href="http://www.appcelerator.com/">Titanium fra appcelerator</a> kan man lage desktop og mobil-klienter vha HTML, CSS og JavaScript. Men først og fremst er det et språk for å lage dynamiske websider, og <em>det</em> har tatt av på nytt de siste årene nå som browserene begynner å bli bedre og mere kompatible med hverandre.</p>
<p>Det er derimot et litt rotete språk, og derfor ikke noe jeg ville ha valgt for å lære meg dynamisk programmering. Om du er av en annen mening bør du skaffe deg boken <em><a href="http://javascript.crockford.com/">JavaScript: The Good Parts</a></em> og lære det orntlig.</p>
<h4>Ruby</h4>
<p><img style="border-right-width: 0px; margin: 0px 0px 5px 15px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="ruby_logo" border="0" alt="ruby_logo" align="right" src="http://blog.kjempekjekt.com/wp-content/uploads/2010/03/ruby_logo.png" width="90" height="104"> <strong><em>Ruby</em></strong> er det språket som har arvet mest fra legendariske <a href="http://en.wikipedia.org/wiki/Smalltalk">Smalltalk</a>, og hevder å være det mest objektorienterte språket man har i dag. Det ble utviklet midt på 90-tallet av Yukihiro &#8220;Matz&#8221; Matsumoto, og er det programmeringsspråket jeg valgte for å lære meg dynamisk programmering. Matz ville lage et språk uten overraskelser, som skulle være en fornøyelse å bruke – fokuset er flyttet bort fra å programmere for <em>maskinen</em>, og mot å programmere for <em>mennesker</em>.</p>
<p><a href="http://rubyonrails.org/">Ruby on Rails</a>, et rammeverk for høy-effektiv webutvikling, er sansynligvis det som har gjort Ruby så populært som det er i dag, men det finnes et hav av andre verktøy og biblioteker også. Ruby-syntaksen egner seg dessuten godt til å lage domenespesifike språk som kan la seg forstå av mindre tekniske personer, og brukes derfor ofte til embedding.</p>
<p style="padding-left: 15px"><em>&#8220;Ruby on Rails is an open-source web framework that&#8217;s optimized for programmer happiness and sustainable productivity. It lets you write beautiful code by favoring convention over configuration.&#8221;</em></p>
<p>Du har sansynligvis allerede sett endel ruby-kode på denne bloggen, men her er et lite eksempel til. Her demonstreres bl.a. at man ikke behøver å deklarere instansvariabler (<em>@name</em>) – det er bare til å begynne å bruke dem, og anta at de er der når man trenger dem.</p>
<div style="background-color: #eeeeee; margin-bottom: 15px"><font face="monospace"><span style="background-color: #dddddd"><font color="#444444">&nbsp;&nbsp;&nbsp; 1 </font></span><font color="#222222"><b>class</b></font>&nbsp;<font color="#445588"><b>Greeter</b></font><br /><span style="background-color: #dddddd"><font color="#444444">&nbsp;&nbsp;&nbsp; 2 </font></span>&nbsp; <font color="#222222"><b>def</b></font>&nbsp;<font color="#990000"><b>initialize</b></font>(name)<br /><span style="background-color: #dddddd"><font color="#444444">&nbsp;&nbsp;&nbsp; 3 </font></span>&nbsp;&nbsp;&nbsp; <font color="#445588"><b>@name</b></font> = name.capitalize<br /><span style="background-color: #dddddd"><font color="#444444">&nbsp;&nbsp;&nbsp; 4 </font></span>&nbsp; <font color="#222222"><b>end</b></font>&nbsp;<br /><span style="background-color: #dddddd"><font color="#444444">&nbsp;&nbsp;&nbsp; 5 </font></span>&nbsp; <font color="#222222"><b>def</b></font>&nbsp;<font color="#990000"><b>salute</b></font><br /><span style="background-color: #dddddd"><font color="#444444">&nbsp;&nbsp;&nbsp; 6 </font></span>&nbsp;&nbsp;&nbsp; puts <font color="#dd1144">&#8220;</font><font color="#dd1144">Hello </font><font color="#dd1144">#{</font><font color="#445588"><b>@name</b></font><font color="#dd1144">}</font><font color="#dd1144">!</font><font color="#dd1144">&#8220;</font><br /><span style="background-color: #dddddd"><font color="#444444">&nbsp;&nbsp;&nbsp; 7 </font></span>&nbsp; <font color="#222222"><b>end</b></font><br /><span style="background-color: #dddddd"><font color="#444444">&nbsp;&nbsp;&nbsp; 8 </font></span><font color="#222222"><b>end</b></font><br /><span style="background-color: #dddddd"><font color="#444444">&nbsp;&nbsp;&nbsp; 9 </font></span>&nbsp;<br /><span style="background-color: #dddddd"><font color="#444444">&nbsp;&nbsp; 10 </font></span>g = <font color="#445588"><b>Greeter</b></font>.new(<font color="#dd1144">&#8220;</font><font color="#dd1144">world</font><font color="#dd1144">&#8220;</font>)<br /><span style="background-color: #dddddd"><font color="#444444">&nbsp;&nbsp; 11 </font></span>g.salute <font color="#555555"><b><i># Output &#8220;Hello World!&#8221;</i></b></font><br /></font></div>
<p>Som Python finnes også Ruby på både .NET-plattformen (i form av IronRuby) og på Java-runtimen (JRuby) i tillegg til den &#8220;vanlig&#8221; implementasjonen i C. </p>
<p>Er du interessert i Ruby kan du begynne på <a href="http://www.ruby-lang.org/">ruby-lang.org</a>.</p>
<h4>Objective-C</h4>
<p><strong><em>Objective-C</em></strong> er en slags blanding av C og Smalltalk, dvs. hardcore, low-level kombinert med elegant og dynamisk objektorientering. Språket har fått sin renessanse på grunn av at det er det primære programmeringsspråket for Apple&#8217;s Mac OS X og iPhone OS. Hvis <em>det</em> er din greie kan det sikkert være et spennende språk, selv om mange sier det er litt gammeldags og tungt å jobbe med. Selv synes jeg det ser litt gresk ut :-/</p>
<p>Jeg finner ikke noen kanonisk skilde til Objective-C, men <a href="http://developer.apple.com/Mac/library/documentation/Cocoa/Conceptual/ObjectiveC/Introduction/introObjectiveC.html">Mac OS X Reference Library har en brukbar introduksjon</a>.</p>
<h4>Lua</h4>
<p><img style="border-right-width: 0px; margin: 0px 0px 5px 15px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="lua_logo" border="0" alt="lua_logo" align="right" src="http://blog.kjempekjekt.com/wp-content/uploads/2010/03/lua_logo.png" width="90" height="88"> <strong><em>Lua</em></strong> er et lettvekts, prototype-basert språk som er designet for å være utvidbart. Som JavaScript er mye av inspirasjonen hentet fra Scheme – JavaScript og Lua har derfor mye til felles, selv om syntaksen er ganske anderledes. </p>
<p>Lua har blitt populært fordi det har blitt embeddet som skriptspråk i <em>World of Warcraft</em> og <a href="http://en.wikipedia.org/wiki/Category:Lua-scripted_video_games">mange andre spill</a>. Hvis du er en <em>gamer</em> kan dette selvsagt være inspirerende, men også om du ønsker å lage programvare som skal være utvidbar og derfor skal hoste sin egen skripting-motor. Lua har god performance, og lar seg bl.a. lett integrere med <a href="http://en.wikipedia.org/wiki/C%2B%2B">C++</a>.</p>
<p>Igjen har jeg ingen erfaring med dette programmeringsspråket, og skal ikke prøve meg på no eksempel. For mer info om Lua kan du gå til <a href="http://www.lua.org/">lua.org</a>.</p>
<h4>Groovy</h4>
<p><img style="border-right-width: 0px; margin: 0px 0px 5px 15px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="groovy_logo" border="0" alt="groovy_logo" align="right" src="http://blog.kjempekjekt.com/wp-content/uploads/2010/03/groovy_logo.png" width="120" height="63"><strong><em>Groovy</em></strong> er et objektorientert, dynamisk språk du finner på Java-plattformen. Version 1.0 ble lansert så sent som i 2007, og det har ikke fått så veldig stor markedsandel enda (plass #40 på TIOBE&#8217;s liste). Inspirasjonen er hentet fra Java, Python, Ruby og lignende språk. Blant annet er Java-kode ofte også gyldig groovy-kode (ifølge wikipedia), og man kan bruke alle eksisterende Java-biblioteker i Groovy.</p>
<p>Her er litt kode:</p>
<div style="background-color: #eeeeee; margin-bottom: 15px"><font face="monospace"><span style="background-color: #dddddd"><font color="#444444">&nbsp;&nbsp;&nbsp; 1 </font></span><font color="#445588"><b>class</b></font> Greeter {<br /><span style="background-color: #dddddd"><font color="#444444">&nbsp;&nbsp;&nbsp; 2 </font></span>&nbsp; <font color="#dd1144">def</font> name<br /><span style="background-color: #dddddd"><font color="#444444">&nbsp;&nbsp;&nbsp; 3 </font></span>&nbsp; Greet(who) {<br /><span style="background-color: #dddddd"><font color="#444444">&nbsp;&nbsp;&nbsp; 4 </font></span>&nbsp;&nbsp;&nbsp; name = who[<font color="#005599">0</font>].toUpperCase() + who[<font color="#005599">1.</font>.-<font color="#005599">1</font>]<br /><span style="background-color: #dddddd"><font color="#444444">&nbsp;&nbsp;&nbsp; 5 </font></span>&nbsp; }<br /><span style="background-color: #dddddd"><font color="#444444">&nbsp;&nbsp;&nbsp; 6 </font></span>&nbsp; <font color="#dd1144">def</font> salute() {<br /><span style="background-color: #dddddd"><font color="#444444">&nbsp;&nbsp;&nbsp; 7 </font></span>&nbsp;&nbsp;&nbsp; <font color="#990000"><b>println</b></font>&nbsp;<font color="#dd1144">&#8220;Hello $name!&#8221;</font><br /><span style="background-color: #dddddd"><font color="#444444">&nbsp;&nbsp;&nbsp; 8 </font></span>&nbsp; }<br /><span style="background-color: #dddddd"><font color="#444444">&nbsp;&nbsp;&nbsp; 9 </font></span>}<br /><span style="background-color: #dddddd"><font color="#444444">&nbsp;&nbsp; 10 </font></span><br /><span style="background-color: #dddddd"><font color="#444444">&nbsp;&nbsp; 11 </font></span>g = <font color="#222222"><b>new</b></font> Greeter(<font color="#dd1144">&#8216;world&#8217;</font>)<br /><span style="background-color: #dddddd"><font color="#444444">&nbsp;&nbsp; 12 </font></span>g.salute()&nbsp;&nbsp; <font color="#555555"><b><i>// Outout &#8220;Hello World!&#8221;</i></b></font><br /></font></div>
<p>Her demonstreres bl.a. Ruby/Python-style ranges (slutten av linje 4), dynamisk evaluering av streng mot variablenavn (såkalt interpolering - linje 7) og fullstendig fravær av type-deklarering. </p>
<p>Er du glad i Java-plattformen og vil lære dynamisk programmering kan du ta en titt på <a href="http://groovy.codehaus.org/">groovy.codehaus.org</a>.</p>
<p>Jeg håper og regner med du fant noe som appelerte her. Lykke til med valget!</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/kjempekjektcom?a=3h2xqUC35Xo:8EOfJgZIi4E:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/kjempekjektcom?i=3h2xqUC35Xo:8EOfJgZIi4E:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/kjempekjektcom?a=3h2xqUC35Xo:8EOfJgZIi4E:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/kjempekjektcom?d=yIl2AUoC8zA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/kjempekjektcom/~4/3h2xqUC35Xo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRSS>http://blog.kjempekjekt.com/2010/03/05/hvilket-dynamiske-programmeringsprk-du-skal-lre-deg/feed/</wfw:commentRSS>
		<feedburner:origLink>http://blog.kjempekjekt.com/2010/03/05/hvilket-dynamiske-programmeringsprk-du-skal-lre-deg/</feedburner:origLink></item>
		<item>
		<title>Du må beherske et dynamisk språk</title>
		<link>http://feedproxy.google.com/~r/kjempekjektcom/~3/ZXqpA2cgb88/</link>
		<comments>http://blog.kjempekjekt.com/2010/03/03/du-m-beherske-et-dynamisk-sprk/#comments</comments>
		<pubDate>Wed, 03 Mar 2010 05:10:17 +0000</pubDate>
		<dc:creator>Torbjørn</dc:creator>
		
	<category>.net ninja</category>
	<category>Polyglot</category>
		<guid isPermaLink="false">http://blog.kjempekjekt.com/2010/03/03/du-m-beherske-et-dynamisk-sprk/</guid>
		<description><![CDATA[Jeg vil si det så sterkt: Hvis du ikke behersker et dynamisk programmeringsspråk, slik at du er i stand til å designe fullverdige software-løsninger i det, da er du ikke en ferdig utdannet utvikler! [1]
Det har vært mye buzz rundt dynamiske språk de siste årene, og mange utviklere, spesielt i Agile-miljøer, migrerer over fra statiske [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Jeg vil si det så sterkt: Hvis du ikke behersker et dynamisk programmeringsspråk, slik at du er i stand til å designe fullverdige software-løsninger i det, da er du ikke en ferdig utdannet utvikler! [<a href="#footnote1">1</a>]</strong></p>
<p>Det har vært mye <em>buzz</em> rundt dynamiske språk de siste årene, og mange utviklere, spesielt i Agile-miljøer, migrerer over fra statiske språk til dynamiske. For å forstå hvorfor dette skjer er det viktig å vite hva vi mener med et dynamisk språk, og hvilke fordeler og ulemper det bringer med seg. Denne artikkelen er en god start for deg som ikke vet så alt for mye om temaet.</p>
<h4>Hva mener vi med Dynamic?</h4>
<p>Når vi sier at noe er <strong>STATIC</strong> mener vi at ting er definert og avgjørelser tas ved compile-time, mens <strong>DYNAMIC</strong> impliserer at det samme skjer i runtime. Det er derimot ingen språk som er fullstendig statiske, og heller ingen som er fullstendig dynamiske – de fleste språk befinner seg et sted mellom disse ytterpunktene.</p>
<p><img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="static_dynamic" border="0" alt="static_dynamic" src="http://blog.kjempekjekt.com/wp-content/uploads/2010/03/static_dynamic.png" width="434" height="128"> </p>
<p>Egenskaper som gjør et språk dynamisk er ting som <a href="http://c2.com/cgi/wiki?DynamicTyping">dynamisk typing</a>, <a href="http://en.wikipedia.org/wiki/Dynamic_dispatch">dynamisk dispatch</a>, <a href="http://en.wikipedia.org/wiki/Type_introspection">introspection</a>, dynamisk kompilering og <a href="http://en.wikipedia.org/wiki/Dynamic_loading">dynamisk loading</a>. I språk som er mer dynamiske kan man f.eks. gjøre ting som å endre hvordan typer ser ut – legge til metoder o.l. - mens programmet kjører.</p>
<p>De dynamiske spåkene begynte for alvor å vokse frem på 80-tallet – og språk som Larry Wall&#8217;s <a href="http://en.wikipedia.org/wiki/Perl">Perl</a> og Guido van Rossum&#8217;s <a href="http://en.wikipedia.org/wiki/Python_(programming_language)">Python</a> hadde stor betydning for internetts vekst på 90-tallet. De dynamske egenskapene hadde derimot en ulempe: <strong><em>Dårlig performance!</em></strong> Grunnen til at de dynamiske språkene har blitt mer populære de siste 10 årene er at vi nå har fått raskere og bedre maskinvare, som gjøre at vi i mange sammenhenger kan se bort fra at programmene kjører noe tregere relativt til kompilert, statisk kode.</p>
<h4>Mange språk utvikler seg i dynamisk retning</h4>
<p><img style="border-right-width: 0px; margin: 0px 0px 5px 15px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="dynamic-lang" border="0" alt="dynamic-lang" align="right" src="http://blog.kjempekjekt.com/wp-content/uploads/2010/03/dynamiclang.png" width="317" height="407">Programmeringsspråk utvikler seg hele tiden. De som ikke gjør det er i praksis døde. Og samtidig som dynamiske språk som Perl, Python og Ruby har blitt mer populære, har andre språk beveget seg i en mer dynamisk reting.</p>
<p>C# har for eksempel en rekke dynamiske egenskaper. Du lager dynamiske programmer om du bl.a. benytter deg av <em>reflection</em> (introspection). Det er bare det at reflection er mye enklere i språk som i utgangspunktet er designet for det. <em>Generics</em> er også en nokså dynamisk feature, som gir inntrykk av løsere typing i koden. Type inference – bruk av &#8220;var&#8221; – gir C# en dynamisk følelse. Og sist men ikke minst innfører man i .NET 4.0 <strong><em>Dynamic</em></strong>, en type hvor metodekall ikke evalueres før runtime (dynamic dispatch), slik at C# bedre kan kommunisere med mere dynamiske språk.</p>
<p>Ved å beherske et dynamisk språk vil man lære seg teknikker som gjør en til en bedre utvikler også når man jobber i mere statiske språk.</p>
<p><em>PS: Det dynamiske språktreet er ikke komplett, men viser de mest sentrale språkene, og hvordan de i hovedsak har påvirket hverandre.</em></p>
<h4>Fordeler ved dynamiske språk</h4>
<p>Jeg mener vi må innse at både statiske og dynamiske språk er viktige. Statiske språk gir en høy grad av kontroll – det er lettere å analysere koden og forutse hva som vil skje i runtime. Det er derimot vist gjentatte ganger at <strong>dynamiske språk gjør deg mere produktiv</strong>; man kan implementere mer funksjonalitet raskere, og med mindre kode.</p>
<p>Dynamiske språk er også mer fleksible, <em>smidige</em> om du vil, og egner seg til problemer hvor løsning i utgangspunktet er ukjent. Flere velger derfor å prototype i dynamiske språk, for så å implementere endelig løsning i et mere statisk språk om performance og sikkerhet er viktig.</p>
<p>En annen ting man oppdager når man går fra statisk til dynamisk programmering er at skillet mellom data og kode opphører – data og funksjonalitet smelter bedre sammen. Det er litt vanskelig å forklare dette uten et dypdykk, så jeg tror det må bli en fremtidig blogpost.</p>
<p>Et siste område hvor dynamiske språk egner seg spesielt godt er <strong><em>embedding</em></strong>. Sett at du skal utvikle et system hvor det meste skal være fast, og egner seg for et statisk språk. Men du ser at det kan bli behov for å kunne endre visse forretningsregler etter at systemet er tatt i bruk. Tradisjonelt vil man forsøke å forutse disse endringene, og lage et innfløkt konfigurasjonssystem for å dekke behovet. I stedet kan man utvikle selve systemet i C#, men kode forretningsreglene i et dynamisk språk. Den dynamiske koden vil evalueres når den behøves, og kan når som helst endres og utvides uten at man behøver å rekompilere og publisere en ny versjon.</p>
<p>I ytterste konsekvens kan man eksponere et API internt i applikasjonen som de dynamiske kodesnuttene kan få tilgang til – man har da laget et scriptbart system, og man kan lene seg tilbake og se på mens tredjepartsutviklere utvider funksjonaliteten i systemet ditt i retninger du selv ikke kunne ha forrutsett.</p>
<h4>Er dynamisk kode bedre enn statisk?</h4>
<p>Det kan hevdes at dynamiske språk oppfordrer deg som utvikler til å skrive bedre kode. Et sentralt poeng er at man ikke har en kompilator å støtte seg på, og viktigheten av enhetstester er derfor mye større. I &#8220;de dynamske miljøene&#8221; er man også mer opptatt av eleganse og enkel kode. Gjennom å praktisere dynamisk kode vil du øke forståelsen av hva kvalitet er for noe, og <em>det</em> vil forbedre din statiske kode også.
<p>Den andre siden av dette er at man ikke lenger har tilgang på mange av de verktøyene man har vendt seg til som f.eks. C#-utvikler: intellisense, god refakturerings-støtte, statisk analyse osv. Visual Studio, ReSharper o.l. gjør oss produktive, og det er en viss overgang å ikke ha disse lengre – man kan føle seg litt naken en stund.<br />
<h4>Videre lesing</h4>
<p>Til slutt har jeg funnet frem et par &#8220;research papers&#8221; for dem som er interessert i utviklingen av dynamiske språk.</p>
<p style="padding-left: 15px"><a href="http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.69.5966&amp;rep=rep1&amp;type=pdf"><strong>The End of the Cold War Between Programming Languages:</strong></a><br /><em>&#8220;Static typing is a powerful tool to help programmers express their assumptions about the problem they are trying to solve and allows them to write more concise and correct code. Dealing with uncertain assumptions, dynamism and (unexepected) change is becoming increasingly important in a loosely couple distributed world. Instead of hammering on the differences between dynamically and statically typed languages, <u>we should instead strive for a peaceful integration of static and dynamic aspect</u> in the same language. Static typing where possible, dynamic typing when needed!&#8221;</em>
</p>
<p style="padding-left: 15px"><strong><a href="http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.67.5268&amp;rep=rep1&amp;type=pdf">On the Revival of Dynamic Languages:</a></strong><br /><em>&#8220;The programming languages of today are stuck in a deep rut that has developed over the past 50 years. Although we are faced with new challenges posed by enormous advances in hardware and internet technology, we continue to struggle with old-fashioned languages based on rigid, static, closed-world file-based views of programming.&#8221;</em>
<p><em><strong>Fotnote:</strong></em><br /><a name="footnote1">[1]</a> Jeg hevder ikke at jeg vet når du kan kalle deg ferdig utdannet - bare at det å beherske et dynamisk språk må inngå i den definisjonen. Joe Armstrong, utvikleren av Erlang, sier f.eks. at det tar 30 år å lære å programmere (i boken <em>Coders at Work</em>).</p>
<p><em><strong>Referanse:</strong></em><br /><a href="http://www.infoq.com/presentations/randal-exploring-dynamism">Randal exploring dynamism (InfoQ)</a>
</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/kjempekjektcom?a=ZXqpA2cgb88:SKFCKdZrowU:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/kjempekjektcom?i=ZXqpA2cgb88:SKFCKdZrowU:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/kjempekjektcom?a=ZXqpA2cgb88:SKFCKdZrowU:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/kjempekjektcom?d=yIl2AUoC8zA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/kjempekjektcom/~4/ZXqpA2cgb88" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRSS>http://blog.kjempekjekt.com/2010/03/03/du-m-beherske-et-dynamisk-sprk/feed/</wfw:commentRSS>
		<feedburner:origLink>http://blog.kjempekjekt.com/2010/03/03/du-m-beherske-et-dynamisk-sprk/</feedburner:origLink></item>
		<item>
		<title>Jeg, Polyglot</title>
		<link>http://feedproxy.google.com/~r/kjempekjektcom/~3/5cOiHIlUfQI/</link>
		<comments>http://blog.kjempekjekt.com/2010/03/02/jeg-polyglot/#comments</comments>
		<pubDate>Tue, 02 Mar 2010 06:02:03 +0000</pubDate>
		<dc:creator>Torbjørn</dc:creator>
		
	<category>.net ninja</category>
	<category>Polyglot</category>
		<guid isPermaLink="false">http://blog.kjempekjekt.com/2010/03/02/jeg-polyglot/</guid>
		<description><![CDATA[ 
WikiPedia: Polyglot - someone who aptly and with a high level of fluency uses many languages.
Her skulle du nå ha lest en lengre artikkel om betydningen av å lære mange, ulike programmeringsspråk, men det viser seg at Live Writer hadde bestemt seg for å spise opp den teksten. Her er derfor selve essensen:
Da jeg [...]]]></description>
			<content:encoded><![CDATA[<p><em><strong><img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="rect2590" border="0" alt="rect2590" src="http://blog.kjempekjekt.com/wp-content/uploads/2010/03/rect2590.png" width="502" height="312"> </strong></em></p>
<p align="left"><em><strong>WikiPedia:</strong> Polyglot - someone who aptly and with a high level of fluency uses many languages.</em></p>
<p align="left">Her skulle du nå ha lest en lengre artikkel om betydningen av å lære mange, ulike programmeringsspråk, men det viser seg at Live Writer hadde bestemt seg for å spise opp den teksten. Her er derfor selve essensen:</p>
<p align="left">Da jeg for over et år siden begynte å for alvor ta tak i min egen utvikling, hadde jeg en lang liste med rammeverk, biblioteker og teknologier jeg ønsket å lære meg – som WCF, WPF, WF, NHibernate, CSLA.NET, nServiceBus m.m. Dette endret seg derimot raskt – min forståelse av hva som er viktig ble mere moden – og jeg begynte i stedet å fokusere på basis-ferdigheter som god <a href="http://blog.kjempekjekt.com/category/oo-designclean-code/">objektorientering</a> og <a href="http://blog.kjempekjekt.com/category/testing-tdd/">testdreven utvikling</a>. </p>
<p align="left">Jeg begynner nå å ane hva neste steg blir; jeg har nemlig blitt veldig opptatt av språk og programmeringsparadigmer. Jeg har begynt å forstå hvorfor erfarne utviklere hevder at man hele tiden må lære seg flere programmeringsspråk. Jeg har også begynt å se hvor mye det er å lære av historien vår. Dette markerer en endring i hva jeg er opptatt av, og jeg spår at det vil komme flere blogposter om språk-relaterte tema her fremover.</p>
<p align="left">Selv om jeg har vært borti mange språk og teknologier siden jeg kodet min første <em>if</em> i <a href="http://en.wikipedia.org/wiki/AMOS_(programming_language)">AMOS BASIC</a>, har mitt fokus de siste åtte årene utelukkende vært C# og .Net-plattformen. Det er for snevert for en profesjonell utvikler. Mens slagordet mitt i 2009 var &#8220;.Net Ninja&#8221; har jeg i år bestemt meg for å bli en <strong>polyglot</strong>, en som behersker en rekke, ulike språk. Jeg tror det vil gi meg en dypere kunnskap om programmering, og gi meg en allsidighet som vil gjøre meg bedre i praksis også.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/kjempekjektcom?a=5cOiHIlUfQI:7mbeOhMoEGs:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/kjempekjektcom?i=5cOiHIlUfQI:7mbeOhMoEGs:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/kjempekjektcom?a=5cOiHIlUfQI:7mbeOhMoEGs:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/kjempekjektcom?d=yIl2AUoC8zA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/kjempekjektcom/~4/5cOiHIlUfQI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRSS>http://blog.kjempekjekt.com/2010/03/02/jeg-polyglot/feed/</wfw:commentRSS>
		<feedburner:origLink>http://blog.kjempekjekt.com/2010/03/02/jeg-polyglot/</feedburner:origLink></item>
		<item>
		<title>.Net-nyheter fra Bergen</title>
		<link>http://feedproxy.google.com/~r/kjempekjektcom/~3/f9stM9ohUM0/</link>
		<comments>http://blog.kjempekjekt.com/2010/02/28/net-nyheter-fra-bergen/#comments</comments>
		<pubDate>Sun, 28 Feb 2010 21:19:33 +0000</pubDate>
		<dc:creator>Torbjørn</dc:creator>
		
	<category>NNUG / community</category>
		<guid isPermaLink="false">http://blog.kjempekjekt.com/2010/02/28/net-nyheter-fra-bergen/</guid>
		<description><![CDATA[Som vanlig skjer det mye i .Net-miljøet i Bergen. Her er noen høydepunkt akkurat nå..

Mark Nijhof, styremedlem i NNUG Bergen, annonserte på bloggen sin fredag at han slutter i Reaktor og starter sitt eget firma: Cre8tive Thought. Mark er kjent for å ha sterke meninger, og er opptatt av software craftsmanship-verdier. Han legger opp til [...]]]></description>
			<content:encoded><![CDATA[<p>Som vanlig skjer det mye i .Net-miljøet i Bergen. Her er noen høydepunkt akkurat nå..</p>
<p><img style="margin: 0px 15px 5px 0px" align="left" src="http://a3.twimg.com/profile_images/423279069/MarkNijhofGravatar_bigger.jpeg">
<p><strong>Mark Nijhof</strong>, styremedlem i NNUG Bergen, <a href="http://elegantcode.com/2010/02/26/initiate-and-embrace-change/">annonserte på bloggen sin fredag</a> at han slutter i Reaktor og starter sitt eget firma: <a href="http://www.cre8ivethought.com/">Cre8tive Thought</a>. Mark er kjent for å ha sterke meninger, og er opptatt av software craftsmanship-verdier. Han legger opp til å både ta utviklingsoppdrag (enten som utvikler eller teamleder) og coaching-oppdrag. Hvis du ønsker at teamet ditt skal bli litt mere smidig, så kan du f.eks. leie inn Mark til å hjelpe dere til å ta i bruk parprogrammering, få bedre utbytte av <a href="http://blog.kjempekjekt.com/category/testing-tdd/">testdreven utvikling</a>, eller ta en gjennomgang av arkitektur og design, og vurdere om koden er fleksibel nok i forhold til endringer.</p>
<p>Styrelederen i NNUG Bergen, <strong>Jon Arild Tørresdal</strong>, har også ting på gang. Han er nemlig med som foreleser på vårens <a href="http://www.microsoft.com/norge/msdn_technet_live/default.aspx">MSDN Live</a>, og vil informere folk i Stavanger, Bergen, Trondheim og Oslo om <a href="http://msdn.microsoft.com/en-us/security/aa570351.aspx">Windows Identity Foundation</a><em></em>. MSDN Live kommer til Bergen 23. april, og vil også omhandle Azure, SharePoint 2010, TFS og SIlverlight 4.</p>
<p>Skal du på <a href="http://qconlondon.com/">QCon London</a> – og det er bare en drøy uke igjen nå – så må du melde deg på <a href="https://secure.trifork.com/london-2010/freeevent/register.m?eventOID=2389">den sosiale kvelden NNUG Bergen har stelt i stand på torsdagen</a>. Vi inviterer alle som har lyst til å bli med på en uhøytidelig samling på en lokal pub, hvor du vil få anledning til å spandere øl og snakke med blant andre <em>Corey Haines, Udi Dahan, Dan North, Oren Eini (a.k.a. Ayende Rahien) og Jon Skeet</em>. Dette er en <strong>Unik Mulighet</strong> – for hvor ofte får du mulighet til å diskutere med en av verdens fremste .Net-arkitekter, mannen bak Behaviour-Driven Development, geniet bak RhinoMocks, og den mest kjente StackOverflow-brukeren på en og samme kveld? For ikke å snakke om den sympatiske Corey, som for tiden er selve personifiseringen av Software Craftsmanship.</p>
<p><img style="margin: 0px 15px 5px 0px" align="left" src="http://a3.twimg.com/profile_images/67188759/udi_dahan_headshot_bigger.png">
<p><strong>Udi Dahan</strong> kommer forresten til Bergen i april, og vil holde foredrag for NNUG&#8217;s medlemmer siste onsdagen i måneden (medlemskap er fortsatt uforpliktende og gratis). Deretter har vi overtalt ham til å holde et <a href="http://nnug.no/Avdelinger/Bergen/Moter/NNUG-Bergen---SOA-og-DDD-kurs-med-Udi-Dahan/">todagers kurs om SOA og DDD</a> – det er trolig fortsatt ledige plasser om du vil være med..</p>
<p>Det har forresten vært endel snakk om at selveste <a href="http://en.wikipedia.org/wiki/Kent_Beck"><strong>Kent Beck</strong></a> muligens kommer til Bergen i mars, også han for å besøke NNUG og kanskje holde et kurs. Og jeg har ikke hørt noe annet enn at dette fortsatt er planen. NNUG hadde et stjernespekket år i fjor, men 2010 ser sålangt ikke ut til å bli noe dårligere. Følg med på <a href="http://nnug.no/">nnug.no</a>.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/kjempekjektcom?a=f9stM9ohUM0:XiDFnnIEeNA:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/kjempekjektcom?i=f9stM9ohUM0:XiDFnnIEeNA:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/kjempekjektcom?a=f9stM9ohUM0:XiDFnnIEeNA:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/kjempekjektcom?d=yIl2AUoC8zA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/kjempekjektcom/~4/f9stM9ohUM0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRSS>http://blog.kjempekjekt.com/2010/02/28/net-nyheter-fra-bergen/feed/</wfw:commentRSS>
		<feedburner:origLink>http://blog.kjempekjekt.com/2010/02/28/net-nyheter-fra-bergen/</feedburner:origLink></item>
		<item>
		<title>En agurktest</title>
		<link>http://feedproxy.google.com/~r/kjempekjektcom/~3/CdB5qkA2fVY/</link>
		<comments>http://blog.kjempekjekt.com/2010/02/24/en-agurktest/#comments</comments>
		<pubDate>Wed, 24 Feb 2010 07:30:07 +0000</pubDate>
		<dc:creator>Torbjørn</dc:creator>
		
	<category>Ruby</category>
	<category>Testing / TDD</category>
		<guid isPermaLink="false">http://blog.kjempekjekt.com/2010/02/24/en-agurktest/</guid>
		<description><![CDATA[Om du ikke har levd under en stein det siste året så har sansynligvis hørt om Aslak Hellesøys Cucumber.
&#8220;Cucumber lets software development teams describe how software should behave in plain text. The text is written in a business-readable domain-specific language and serves as documentation, automated tests and development-aid - all rolled into one format.&#8220;
&#8220;Cucumber works [...]]]></description>
			<content:encoded><![CDATA[<p>Om du ikke har levd under en stein det siste året så har sansynligvis hørt om Aslak Hellesøys <strong><a href="http://cukes.info/">Cucumber</a>.</strong></p>
<p style="padding-left: 15px"><em>&#8220;Cucumber lets software development teams describe how software should behave in plain text. The text is written in a </em><a href="http://www.martinfowler.com/bliki/BusinessReadableDSL.html"><em>business-readable domain-specific language</em></a><em> and serves as documentation, automated tests and development-aid - all rolled into one format.<strong>&#8220;</strong></em></p>
<p style="padding-left: 15px"><em>&#8220;Cucumber works with Ruby, Java, .NET, Flex or web applications written in any language. It has been translated to over 30 spoken languages.<strong>&#8220;</strong></em></p>
<p>Men du har kanskje ikke testet det selv? Jeg tenkte derfor jeg kunne gjøre en rask demonstrasjon ved å skrive en akseptansetest for tjenesten jeg lagde i blogpostene om <a href="http://blog.kjempekjekt.com/2010/02/18/en-minimal-http-server-i-net/">en minimal http-server i .Net</a> / <a href="http://blog.kjempekjekt.com/2010/02/22/en-minimal-http-server-i-ruby/">Ruby</a>. Normalt vil man selvsagt beskrive featurene først, og så implementere dem og bruke cucumber til å bevise at de fungerer, men for enkelhets skyld tester jeg her altså min eksisterende tjeneste. Det spiller forøvrig ingen rolle om jeg tester .Net-varianten eller Ruby-varianten – jeg vil la akseptansetesten aksessere tjenesten direkte over http, og da er jo grensesnittet uansett det samme.</p>
<p>Det første jeg må gjøre er å beskrive tjenesten i form av en feature med tilhørende scenarier. Virker dette litt gresk anbefaler jeg at du leser deg litt opp på <a href="http://behaviour-driven.org/">Behaviour-Driven Development</a> (BDD).</p>
<div style="margin-bottom: 15px"><font face="monospace">File: features\add_service.feature:<br />
<div style="background-color: #000000; color: #f6f3e8"><span style="background-color: #000000"><font color="#3d3d3d">1 </font></span>Feature: Add-service<br /><span style="background-color: #000000"><font color="#3d3d3d">2 </font></span>  In order to save cycles on client CPUs<br /><span style="background-color: #000000"><font color="#3d3d3d">3 </font></span>  As an IT manager<br /><span style="background-color: #000000"><font color="#3d3d3d">4 </font></span>  I want a central server that can add numbers<br /><span style="background-color: #000000"><font color="#3d3d3d">5 </font></span><br /><span style="background-color: #000000"><font color="#3d3d3d">6 </font></span>  Scenario: Add a string of numbers<br /><span style="background-color: #000000"><font color="#3d3d3d">7 </font></span>    When I send 9,11,33,100 to the add service<br /><span style="background-color: #000000"><font color="#3d3d3d">8 </font></span>    Then the response should be &#8220;The answer is 153&#8243;<br /><span style="background-color: #000000"><font color="#3d3d3d">9 </font></span><br /><span style="background-color: #000000"><font color="#3d3d3d">10 </font></span>  Scenario: Add a single number<br /><span style="background-color: #000000"><font color="#3d3d3d">11 </font></span>    When I send 1 to the add service<br /><span style="background-color: #000000"><font color="#3d3d3d">12 </font></span>    Then the response should be &#8220;The answer is 1&#8243;</div>
<p></font></div>
<p>Feature-filen er input til cucumber, som vil analysere stegene i scenariene og forsøke å eksekvere dem. Men foreløpig skjønner cucumber lite, så vi må skrive litt kode for å definere stegene.</p>
<div style="margin-bottom: 15px"><font face="monospace">File: features\add_service_steps.rb:<br />
<div style="background-color: #000000; color: #f6f3e8"><span style="background-color: #000000"><font color="#3d3d3d">1 </font></span><font color="#96cbfe">require</font> <font color="#336633">&#8216;</font><font color="#a8ff60">open-uri</font><font color="#336633">&#8216;</font><br /><span style="background-color: #000000"><font color="#3d3d3d">2 </font></span><font color="#96cbfe">require</font> <font color="#336633">&#8216;</font><font color="#a8ff60">spec/expectations</font><font color="#336633">&#8216;</font><br /><span style="background-color: #000000"><font color="#3d3d3d">3 </font></span><br /><span style="background-color: #000000"><font color="#3d3d3d">4 </font></span><font color="#ffffb6">When</font> <font color="#ff8000">/</font><font color="#b18a3d">I send </font><font color="#e18964">(</font><font color="#e18964">.</font><font color="#e18964">*</font><font color="#e18964">)</font><font color="#b18a3d"> to the </font><font color="#e18964">(</font><font color="#e18964">.</font><font color="#e18964">*</font><font color="#e18964">)</font><font color="#b18a3d"> service</font><font color="#ff8000">/</font> <font color="#6699cc">do</font> |<font color="#c6c5fe">argument</font>, <font color="#c6c5fe">service</font>|<br /><span style="background-color: #000000"><font color="#3d3d3d">5 </font></span>  open(<font color="#336633">&#8220;</font><font color="#a8ff60"><a href="http://127.0.0.1:4567/">http://127.0.0.1:4567/</a></font><font color="#00a0a0">#{</font>service<font color="#00a0a0">}</font><font color="#a8ff60">?</font><font color="#00a0a0">#{</font>argument<font color="#00a0a0">}</font><font color="#336633">&#8220;</font>) <font color="#6699cc">do</font> |<font color="#c6c5fe">response</font>|<br /><span style="background-color: #000000"><font color="#3d3d3d">6 </font></span>    <font color="#c6c5fe">@data</font> = response.read<br /><span style="background-color: #000000"><font color="#3d3d3d">7 </font></span>  <font color="#6699cc">end</font><br /><span style="background-color: #000000"><font color="#3d3d3d">8 </font></span><font color="#6699cc">end</font><br /><span style="background-color: #000000"><font color="#3d3d3d">9 </font></span><br /><span style="background-color: #000000"><font color="#3d3d3d">10 </font></span><font color="#ffffb6">Then</font> <font color="#ff8000">/</font><font color="#b18a3d">the response should be &#8220;</font><font color="#e18964">(</font><font color="#e18964">[^</font><font color="#b18a3d">\&#8221;</font><font color="#e18964">]</font><font color="#e18964">*</font><font color="#e18964">)</font><font color="#b18a3d">&#8220;</font><font color="#ff8000">/</font> <font color="#6699cc">do</font> |<font color="#c6c5fe">expected</font>|<br /><span style="background-color: #000000"><font color="#3d3d3d">11 </font></span>  <font color="#c6c5fe">@data</font>.should == expected<br /><span style="background-color: #000000"><font color="#3d3d3d">12 </font></span><font color="#6699cc">end</font></div>
<p></font></div>
<p>Sånn, det er alt som trengs. Jeg lager et <em>&#8220;When I send X to the Y service&#8221;</em>-steg som gjør en forespørsel til tjenesten min og sender de definerte argumentene. Cucumber tar seg av å bytte ut X og Y med argumentene og navnet på tjenesten. <em>&#8220;Then the response should be Z&#8221;</em>-steget gjør en assert mot det forventede svaret som er beskrevet i scenariene. </p>
<p>Legg merke til at det er to forskjellige DSL&#8217;er (domenespesifike språk) i bruk her – en ekstern DSL for å definere features, og en intern Ruby-DSL (intern som i &#8220;er gyldig ruby-kode) for å definere stegene.</p>
<p>Når jeg kjører cucumber nå får jeg følgende output:</p>
<div style="margin-bottom: 15px"><font face="monospace">C:\Users\tormar\ruby_projects\httpListener>cucumber<br />
<div style="background-color: #000000; padding-left: 5px; color: #f6f3e8">Feature: Add-service<br />        In order to save cycles on client CPUs<br />        As an IT manager<br />        I want a central server that can add numbers</p>
<p>  Scenario: Add a string of numbers<br />    <font color="green">When I send</font> <font color="#a8ff60">9,11,33,100</font> <font color="green">to the</font> <font color="#a8ff60">add</font> <font color="green">service</font><br />    <font color="green">Then the response should be &#8220;</font><font color="#a8ff60">The answer is 153</font><font color="green">&#8220;</font></p>
<p>  Scenario: Add a single number<br />    <font color="green">When I send</font> <font color="#a8ff60">1</font> <font color="green">to the</font> <font color="#a8ff60">add</font> <font color="green">service</font><br />    <font color="green">Then the response should be &#8220;</font><font color="#a8ff60">The answer is 1</font><font color="green">&#8220;</font></p>
<p>2 scenarios (<font color="green">2 passed</font>)<br />4 steps (<font color="green">4 passed</font>)<br />0m0.122s</div>
<p></font></div>
<p>Alle scenariene for Add-servicen passerte (hvis ikke hadde det dukket opp endel rødt i output). Kult?</p>
<p>Hvis du er alergisk mot Ruby så finnes det også et prosjekt som heter <a href="http://www.specflow.org/">SpecFlow</a> som er en port av cucumber til .Net. Men det er absolutt å anbefale å benytte the real thing, gjerne med IronRuby på .Net-plattformen.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/kjempekjektcom?a=CdB5qkA2fVY:luZNi8wSIQQ:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/kjempekjektcom?i=CdB5qkA2fVY:luZNi8wSIQQ:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/kjempekjektcom?a=CdB5qkA2fVY:luZNi8wSIQQ:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/kjempekjektcom?d=yIl2AUoC8zA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/kjempekjektcom/~4/CdB5qkA2fVY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRSS>http://blog.kjempekjekt.com/2010/02/24/en-agurktest/feed/</wfw:commentRSS>
		<feedburner:origLink>http://blog.kjempekjekt.com/2010/02/24/en-agurktest/</feedburner:origLink></item>
		<item>
		<title>En minimal http-server i Ruby</title>
		<link>http://feedproxy.google.com/~r/kjempekjektcom/~3/0claTQdCO7o/</link>
		<comments>http://blog.kjempekjekt.com/2010/02/22/en-minimal-http-server-i-ruby/#comments</comments>
		<pubDate>Mon, 22 Feb 2010 07:46:04 +0000</pubDate>
		<dc:creator>Torbjørn</dc:creator>
		
	<category>Ruby</category>
	<category>Webutvikling</category>
		<guid isPermaLink="false">http://blog.kjempekjekt.com/2010/02/22/en-minimal-http-server-i-ruby/</guid>
		<description><![CDATA[I denne oppfølgingsposten til En minimal http-server i .Net viser jeg hvordan jeg raskt kan sette opp en tilsvarende løsning i Ruby. Jeg skal altså implementere en tjeneste som lytter på http, og som responderer på ulike argumenter. Løsningen skal være enkel å utvide med flere &#8220;respondere&#8221; – det skal ikke være nødvendig å editere [...]]]></description>
			<content:encoded><![CDATA[<p>I denne oppfølgingsposten til <em><a href="http://blog.kjempekjekt.com/2010/02/18/en-minimal-http-server-i-net/">En minimal http-server i .Net</a></em> viser jeg hvordan jeg raskt kan sette opp en tilsvarende løsning i Ruby. Jeg skal altså implementere en tjeneste som lytter på http, og som responderer på ulike argumenter. Løsningen skal være enkel å utvide med flere &#8220;respondere&#8221; – det skal ikke være nødvendig å editere eksisterende kode for å håndtere nye typer forespørsler (se forrige post om du vil vite mer om oppgaven).</p>
<p>Ruby shipper med mange, nyttige moduler - blant annet en søt, liten tjeneste som heter <strong><em><a href="http://en.wikipedia.org/wiki/WEBrick" target="_blank">WEBrick</a></em></strong>, som kan brukes ganske likt som .Net&#8217;s HttpListener egentlig. I følgende program setter jeg opp en server til å lytte på port 8081:</p>
<div style="padding-bottom: 4px; font-family: monospace; margin-bottom: 12px; background: #003d59; color: #e2e2e2; font-size: 9pt; padding-top: 4px">
<p style="line-height: 11pt; margin: 0px"><span style="color: #2b91af">   1</span> <span style="color: #a0dafc">require</span> &#8216;webrick&#8217;</p>
<p style="line-height: 11pt; margin: 0px"><span style="color: #2b91af">   2</span> <span style="color: #a0dafc">include</span> WEBrick</p>
<p style="line-height: 11pt; margin: 0px"><span style="color: #2b91af">   3</span> </p>
<p style="line-height: 11pt; margin: 0px"><span style="color: #2b91af">   4</span> <span style="color: #136bfd">#DSL method for defining responders</span></p>
<p style="line-height: 11pt; margin: 0px"><span style="color: #2b91af">   5</span> <span style="color: #70aeed">def</span> <span style="color: #a0dafc">respond_to</span> config</p>
<p style="line-height: 11pt; margin: 0px"><span style="color: #2b91af">   6</span>     key <span style="color: #e2e2e2">=</span> config[:key]</p>
<p style="line-height: 11pt; margin: 0px"><span style="color: #2b91af">   7</span>     $server.mount_proc(key) <span style="color: #70aeed">do</span> |request, response|</p>
<p style="line-height: 11pt; margin: 0px"><span style="color: #2b91af">   8</span>         response.body <span style="color: #e2e2e2">=</span> yield request.query.to_s</p>
<p style="line-height: 11pt; margin: 0px"><span style="color: #2b91af">   9</span>     <span style="color: #70aeed">end</span></p>
<p style="line-height: 11pt; margin: 0px"><span style="color: #2b91af">   10</span> <span style="color: #70aeed">end</span></p>
<p style="line-height: 11pt; margin: 0px"><span style="color: #2b91af">   11</span> </p>
<p style="line-height: 11pt; margin: 0px"><span style="color: #2b91af">   12</span> <span style="color: #70aeed">def</span> <span style="color: #a0dafc">load_responders</span></p>
<p style="line-height: 11pt; margin: 0px"><span style="color: #2b91af">   13</span>     responder_definitions <span style="color: #e2e2e2">=</span> Dir.glob(&#8221;*.responder&#8221;)</p>
<p style="line-height: 11pt; margin: 0px"><span style="color: #2b91af">   14</span>     responder_definitions.each { |d| load d }</p>
<p style="line-height: 11pt; margin: 0px"><span style="color: #2b91af">   15</span> <span style="color: #70aeed">end</span></p>
<p style="line-height: 11pt; margin: 0px"><span style="color: #2b91af">   16</span> </p>
<p style="line-height: 11pt; margin: 0px"><span style="color: #2b91af">   17</span> $server <span style="color: #e2e2e2">=</span> HTTPServer.new( &#58;Port => 8081 )</p>
<p style="line-height: 11pt; margin: 0px"><span style="color: #2b91af">   18</span> load_responders</p>
<p style="line-height: 11pt; margin: 0px"><span style="color: #2b91af">   19</span> trap(&#8221;INT&#8221;) { $server.shutdown }</p>
<p style="line-height: 11pt; margin: 0px"><span style="color: #2b91af">   20</span> $server.start</p>
</div>
<p>Servicen opprettes i linje 17, og i neste linje kaller jeg en metode jeg har kalt load_responders. Den henter alle filer med <em>.responder</em> extension, og kjører innholdet. Responder-filene i sin tur benytter respond_to metoden definert fra linje 5 til å konfigurere WEBrick.</p>
<div style="border-bottom: black 1px solid; border-left: black 1px solid; padding-bottom: 10px; background-color: lightblue; margin: 10px 10px 25px; padding-left: 10px; padding-right: 10px; border-top: black 1px solid; border-right: black 1px solid; padding-top: 10px"><em><b>Sidenote:</b> Jeg implementerte først en løsning med en SimpleHttpServer-klasse og en klasse for å representere respondere. Etter å ha tenkt meg litt om så jeg derimot at det bare ble en masse stafasje, og at koden ikke kommuniserte så veldig godt hva den gjorde. Enkelhet er et av de viktigste budene for smidige utviklere, og Ruby lar meg skrelle bort ganske mye. Så etter å ha slettet 30 linjer kode følte jeg meg mer komfortabel. Om du vil se en mere objektorientert løsning kan du ta en titt på <a href="http://jroller.com/rolsen/entry/building_a_dsl_in_ruby1" target="_blank">Building a DSL in Ruby, part II</a> fra bloggen Technology as if People Mattered, som var en viktig inspirasjonskilde til </em>denne<em> bloggposten.</em></div>
<p>Nedefor er responder-filen for add-tjenesten. Se forrige post for å se hvordan denne responderen ser ut i .net. Som du kanskje ser er dette rett og slett et kall til respond_to. Som argument til metoden sendes nøkkelen &#8220;/add&#8221;, som er det responderen skal håndtere (ref bruk av attributtet <em>RespondTo</em> i .Net-løsningen). Resten er en kodeblokk som tar som input argumentene fra requesten, og returnerer et svar. Denne kodeblokken brukes til å håndtere forespørselen (magien ligger i <em>&#8220;yield&#8221;</em> i linje 8 i programmet over).</p>
<div style="padding-bottom: 4px; font-family: monospace; margin-bottom: 12px; background: #003d59; color: #e2e2e2; font-size: 9pt; padding-top: 4px">
<p style="line-height: 11pt; margin: 0px"><span style="color: #2b91af">   1</span> respond_to :key => &#8220;/add&#8221; <span style="color: #70aeed">do</span> |arguments|</p>
<p style="line-height: 11pt; margin: 0px"><span style="color: #2b91af">   2</span>     sum <span style="color: #e2e2e2">=</span> 0</p>
<p style="line-height: 11pt; margin: 0px"><span style="color: #2b91af">   3</span>     numbers <span style="color: #e2e2e2">=</span> arguments.split(&#8217;,')</p>
<p style="line-height: 11pt; margin: 0px"><span style="color: #2b91af">   4</span>     numbers.each { |n| sum += n.to_i }</p>
<p style="line-height: 11pt; margin: 0px"><span style="color: #2b91af">   5</span>     &#8220;The answer is #{sum}&#8221;</p>
<p style="line-height: 11pt; margin: 0px"><span style="color: #2b91af">   6</span> <span style="color: #70aeed">end</span></p>
</div>
<p>Koden i denne responderen er litt C#-ish, jeg har gjort nøyaktig det samme som jeg gjorde i C#-varianten, bare oversatt det til Ruby. For å gjøre den mere <em>rubyesque</em> benytte vi et par array-metoder som Ruby har arvet fra SmallTalk: <em>map</em> (som egentlig er en alias fro <em>collect</em>, men jeg liker <em>map</em> bedre) tar et array, kjører en gitt transformasjon på hvert element (i dette tilfellet eksplisit konvertering til integer), og returnerer et nytt array med resultatet. Dette føles nok ikke så  fremmed for .Net-utviklere lengre, nå som vi har vendt oss til Linq, som tilbyr samme funksjonalitet via <em>Select</em>-metoden.</p>
<p>Det andre trikset er metoden <em>inject.</em> Den kan brukes til å &#8220;samle informasjon&#8221; fra et array, i dette tilfellet summen av alle argumentene. Dermed kan spesifikasjonen av add-responderen modifiseres til å se slik ut:</p>
<div style="padding-bottom: 4px; font-family: monospace; margin-bottom: 12px; background: #003d59; color: #e2e2e2; font-size: 9pt; padding-top: 4px">
<p style="line-height: 11pt; margin: 0px"><span style="color: #2b91af">   1</span> respond_to :key => &#8220;/add&#8221; <span style="color: #70aeed">do</span> |arguments|</p>
<p style="line-height: 11pt; margin: 0px"><span style="color: #2b91af">   2</span>     numbers <span style="color: #e2e2e2">=</span> arguments.split(&#8217;,').map {|arg| arg.to_i}</p>
<p style="line-height: 11pt; margin: 0px"><span style="color: #2b91af">   3</span>     &#8220;The answer is #{numbers.inject {|x,n| x+n }}&#8221;</p>
<p style="line-height: 11pt; margin: 0px"><span style="color: #2b91af">   4</span> <span style="color: #70aeed">end</span></p>
</div>
<p>Resultatet er altså at jeg på 20 linjer har satt opp en dynamisk webserver som jeg kan utvide ved å legge til flere <em>.responder</em>-filer. Definisjonen av hver responder er veldig konsis og grei, og står på ingen måte tilbake for .Net-løsningen. I Ruby har jeg ikke behøvd å definere interface for respondere, og lastingen av dem – som er basert på fil-extension i stedet for refleksion og attributter – er mye enklere. Når du tar med i betraktning at jeg ikke engang behøver å kompilere Ruby-løsningen, så er det ikke vanskelig for meg å foretrekke denne når jeg får behov for å raskt sette opp web-tjenester av ulik art f.eks. for å simulere tjenester jeg skal integrere mot.</p>
<h4>Sinatra entrer scenen</h4>
<p><img style="border-right-width: 0px; margin: 0px 0px 10px 15px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="frank_sinatra" border="0" alt="frank_sinatra" align="right" src="http://blog.kjempekjekt.com/wp-content/uploads/2010/02/frank_sinatra.jpg" width="138" height="148"> Å bruke WEBrick til dette her er ganske &#8220;<em>low level&#8221;</em> (på samme måte som HttpListener var det). I .NET-verden har vi rammeverk for webutvikling på et høyere nivå som blant andre WebForms, <a href="http://www.asp.net/mvc/" target="_blank">ASP.NET MVC</a>, <a href="http://code.google.com/p/fubumvc/" target="_blank">FubuMVC</a> og <a href="http://www.castleproject.org/monorail/index.html" target="_blank">MonoRail</a> (det er egentlig alle jeg vet om). <a href="http://www.ruby-lang.org/en/" target="_blank">Ruby</a> har også dette; det desidert mest kjente er <a href="http://rubyonrails.org/" target="_blank">Ruby on Rails</a>, som gjør deg ekstremt produktiv så sant du er villig til å følge Rails konvensjoner og måter å gjøre ting på. <a href="http://ramaze.net/" target="_blank">Ramaze</a> er et rammeverk med mye større frihet, hvor man kan velge mellom et hav av moduler og måter å gjøre ting på. Begge disse baserer seg i hovedsak på <em>Model-View-Controller</em> paradigmet.</p>
<p><a href="http://www.sinatrarb.com/" target="_blank"><strong>Sinatra</strong></a> er et tredje ruby-biblotek som er ganske nyttig til å utvikle mindre websider og tjenester. Det minner mye om det jeg har gjort i denne artikkelen, og ved å bruke Sinatra kan jeg forenkle tjenesten min ganske mye (som om den ikke var enkel nok allerede).</p>
<p>Sinatra-versjonen av selve tjenesten min ser slik ut:</p>
<div style="padding-bottom: 4px; font-family: monospace; margin-bottom: 12px; background: #003d59; color: #e2e2e2; font-size: 9pt; padding-top: 4px">
<p style="line-height: 11pt; margin: 0px"><span style="color: #2b91af">   1</span> <span style="color: #a0dafc">require</span> &#8217;sinatra&#8217;</p>
<p style="line-height: 11pt; margin: 0px"><span style="color: #2b91af">   2</span> Dir.glob(&#8221;*.responder&#8221;).each { |d| load d }</p>
</div>
<p>Ved å inkludere sinatra-bibloteket startes automatisk en webserver. Det eneste jeg da trenger er å dynamisk laste alle responder-filene. Jeg har slått sammen linje 13 og 14 fra det orginale skriptet, og står dermed igjen med én require og én kodelinje. </p>
<p>Responder-filen ser nesten ut som tidligere, men kallet til <em>respond_to</em>, som jeg selv definerte, har vi nå et kall til sinatras <em>get</em>-metode (&#8217;get&#8217; som i REST-metoden get):</p>
<div style="padding-bottom: 4px; font-family: monospace; margin-bottom: 12px; background: #003d59; color: #e2e2e2; font-size: 9pt; padding-top: 4px">
<p style="line-height: 11pt; margin: 0px"><span style="color: #2b91af">   1</span> get &#8220;/add&#8221; <span style="color: #70aeed">do</span></p>
<p style="line-height: 11pt; margin: 0px"><span style="color: #2b91af">   2</span>     numbers <span style="color: #e2e2e2">=</span> params.to_s.split(&#8217;,').map {|arg| arg.to_i}</p>
<p style="line-height: 11pt; margin: 0px"><span style="color: #2b91af">   3</span>     &#8220;The answer is #{numbers.inject {|x,n| x+n }}&#8221;</p>
<p style="line-height: 11pt; margin: 0px"><span style="color: #2b91af">   4</span> <span style="color: #70aeed">end</span></p>
</div>
<p>Dermed har jeg gått fra 24 til 6 linjer. Det er latterlig lite!</p>
<p>Og den tilsvarende C#-løsningen fra <a href="http://blog.kjempekjekt.com/2010/02/18/en-minimal-http-server-i-net/">forrige post</a> var på over 170 linjer. Det finnes selvfølgelig mere optimale løsninger, men jeg har vært en C#-utvikler i åtte år, og 170 liner ++ var det jeg havnet på. Jeg har vært Ruby-utvikler på hobbybasis i et par måneder, og landet på 6 linjer. Det MÅ jo si noe om Ruby og dynamisk programmering! </p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/kjempekjektcom?a=0claTQdCO7o:ElgJq_UMDUo:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/kjempekjektcom?i=0claTQdCO7o:ElgJq_UMDUo:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/kjempekjektcom?a=0claTQdCO7o:ElgJq_UMDUo:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/kjempekjektcom?d=yIl2AUoC8zA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/kjempekjektcom/~4/0claTQdCO7o" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRSS>http://blog.kjempekjekt.com/2010/02/22/en-minimal-http-server-i-ruby/feed/</wfw:commentRSS>
		<feedburner:origLink>http://blog.kjempekjekt.com/2010/02/22/en-minimal-http-server-i-ruby/</feedburner:origLink></item>
		<item>
		<title>En minimal http-server i .Net</title>
		<link>http://feedproxy.google.com/~r/kjempekjektcom/~3/EdLLGobpIaY/</link>
		<comments>http://blog.kjempekjekt.com/2010/02/18/en-minimal-http-server-i-net/#comments</comments>
		<pubDate>Thu, 18 Feb 2010 09:32:54 +0000</pubDate>
		<dc:creator>Torbjørn</dc:creator>
		
	<category>Webutvikling</category>
	<category>OO-design/clean code</category>
		<guid isPermaLink="false">http://blog.kjempekjekt.com/2010/02/18/en-minimal-http-server-i-net/</guid>
		<description><![CDATA[.Net-rammeverket er fullt av moduler for å lage webtjenester; du kan bruke WebForms eller ASP.NET MVC, SOAP web services eller WCF, RIA services eller Astoria data services, alt etter dagsform og hvilket behov du har. Noen ganger kan det derimot være greit å vite hvordan man på aller enklest måte kan lage en http-basert server. [...]]]></description>
			<content:encoded><![CDATA[<p>.Net-rammeverket er fullt av moduler for å lage webtjenester; du kan bruke <strong>WebForms</strong> eller <strong>ASP.NET MVC</strong>, <strong>SOAP web services</strong> eller <strong>WCF</strong>, <strong>RIA services</strong> eller <strong>Astoria data services</strong>, alt etter dagsform og hvilket behov du har. Noen ganger kan det derimot være greit å vite hvordan man på aller enklest måte kan lage en http-basert server. I Chrome-vinduet under ser du hvordan jeg aksesserer en <em>&#8220;no-fuss&#8221;</em> service som kan fortelle meg hva klokka er…</p>
<p><img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="CropperCapture[48]" border="0" alt="CropperCapture[48]" src="http://blog.kjempekjekt.com/wp-content/uploads/2010/02/CropperCapture48.png" width="498" height="169"> </p>
<p>I denne artikkelen presenterer jeg den ikke så veldig godt kjente klassen <strong><em>HttpListener</em></strong> (i System.Net namespacet), og viser hvordan man enkelt kan bruke den til å lage en slags webserver. Denne teknikken kan være aktuell om man f.eks. skulle trenge å raskt <em>mocke opp</em> noen webservicer som ikke følger de vanlige standardene, eller om man skal lage moduler som kommuniserer over http med en proprietær protokoll.</p>
<p>Men jeg har mer på lur: Http-serveren jeg presenterer her er designet for å være utvidbar, og bruker derfor STRATEGY PATTERN i håndteringen av forespørslene. Du vil også få se hvordan jeg kombinerer <em><strong>attributter</strong></em> og <strong><em>reflection</em></strong> for å kunne dynamisk legge til ny adferd uten å måtte editere eksisterende kode. </p>
<p>Her følger selve server-klassen: SimpleHttpServer. Det sentrale skjer i linje 30 til 33, hvor jeg oppretter en HttpListener, registrerer adresse og port for lytting, og starter å lytte. Dette tilsvarer mer eller mindre hvordan Internet Information Server (IIS) selv registrerer seg for lytting mot operativsystemet.</p>
<div style="padding-left: 5px; font-family: monospace; margin-bottom: 12px; background: #202020; color: #e0e0e0; font-size: 9pt">
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">    9</span> <span style="color: #00bfff">public</span> <span style="color: #00bfff">class</span> <span style="color: #00d2d2">SimpleHttpServer</span></p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   10</span> {</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   11</span>     <span style="color: #00bfff">private</span> <span style="color: #00bfff">string</span> <span style="color: #c4c4c4">_address</span>;</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   12</span>     <span style="color: #00bfff">private</span> <span style="color: #00bfff">int</span> <span style="color: #c4c4c4">_port</span>;</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   13</span>     <span style="color: #00bfff">private</span> <span style="color: #7ee0ce">ResponderFactory</span> <span style="color: #c4c4c4">_dispatcher</span>;</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   14</span>     <span style="color: #00bfff">public</span> <span style="color: #c4c4c4">SimpleHttpServer</span>(<span style="color: #00bfff">string</span> <span style="color: #c4c4c4">address</span>, <span style="color: #00bfff">int</span> <span style="color: #c4c4c4">port</span>, <span style="color: #7ee0ce">ResponderFactory</span> <span style="color: #c4c4c4">dispatcher</span>)</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   15</span>     {</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   16</span>         <span style="color: #c4c4c4">_port</span> <span style="color: silver">=</span> <span style="color: #c4c4c4">port</span>;</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   17</span>         <span style="color: #c4c4c4">_address</span> <span style="color: silver">=</span> <span style="color: #c4c4c4">address</span>;</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   18</span>         <span style="color: #c4c4c4">_dispatcher</span> <span style="color: silver">=</span> <span style="color: #c4c4c4">dispatcher</span>;</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   19</span>     }</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   20</span> </p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   21</span>     <span style="color: #00bfff">private</span> <span style="color: #00d2d2">HttpListener</span> <span style="color: #c4c4c4">_httpListener</span>;</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   22</span>     <span style="color: #00bfff">public</span> <span style="color: #00bfff">void</span> <span style="color: #c4c4c4">Start</span>()</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   23</span>     {</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   24</span>         <span style="color: #c4c4c4">StartHttpListener</span>();</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   25</span>         <span style="color: #00bfff">while</span> (<span style="color: #00bfff">true</span>)</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   26</span>             <span style="color: #c4c4c4">WaitForRequestThenHandle</span>();</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   27</span>     }</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   28</span>     <span style="color: #00bfff">private</span> <span style="color: #00bfff">void</span> <span style="color: #c4c4c4">StartHttpListener</span>()</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   29</span>     {</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   30</span>         <span style="color: #c4c4c4">_httpListener</span> <span style="color: silver">=</span> <span style="color: #00bfff">new</span> <span style="color: #00d2d2">HttpListener</span>();</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   31</span>         <span style="color: #c4c4c4">_httpListener</span><span style="color: silver">.</span><span style="color: #c4c4c4">Prefixes</span><span style="color: silver">.</span><span style="color: #c4c4c4">Add</span>(</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   32</span>             <span style="color: #00d2d2">String</span><span style="color: silver">.</span><span style="color: #c4c4c4">Format</span>(<span style="color: #fa8072">&#8220;http://{0}:{1}/&#8221;</span>, <span style="color: #c4c4c4">_address</span>, <span style="color: #c4c4c4">_port</span>));</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   33</span>         <span style="color: #c4c4c4">_httpListener</span><span style="color: silver">.</span><span style="color: #c4c4c4">Start</span>();</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   34</span>     }</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   35</span>     <span style="color: #00bfff">private</span> <span style="color: #00bfff">void</span> <span style="color: #c4c4c4">WaitForRequestThenHandle</span>()</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   36</span>     {</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   37</span>         <span style="color: #00bfff">var</span> <span style="color: #c4c4c4">incomingRequestContext</span> <span style="color: silver">=</span> <span style="color: #c4c4c4">_httpListener</span><span style="color: silver">.</span><span style="color: #c4c4c4">GetContext</span>();</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   38</span> </p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   39</span>         <span style="color: #00d2d2">ThreadPool</span><span style="color: silver">.</span><span style="color: #c4c4c4">QueueUserWorkItem</span>((<span style="color: #c4c4c4">state</span>) <span style="color: silver">=></span></p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   40</span>         {</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   41</span>             <span style="color: #00bfff">try</span></p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   42</span>             {</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   43</span>                 <span style="color: #00bfff">var</span> <span style="color: #c4c4c4">context</span> <span style="color: silver">=</span> <span style="color: #c4c4c4">state</span> <span style="color: #00bfff">as</span> <span style="color: #00d2d2">HttpListenerContext</span>;</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   44</span>                 <span style="color: #00bfff">var</span> <span style="color: #c4c4c4">url</span> <span style="color: silver">=</span> <span style="color: #c4c4c4">context</span><span style="color: silver">.</span><span style="color: #c4c4c4">Request</span><span style="color: silver">.</span><span style="color: #c4c4c4">Url</span>;</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   45</span>                 <span style="color: #00bfff">var</span> <span style="color: #c4c4c4">encoding</span> <span style="color: silver">=</span> <span style="color: #c4c4c4">context</span><span style="color: silver">.</span><span style="color: #c4c4c4">Request</span><span style="color: silver">.</span><span style="color: #c4c4c4">ContentEncoding</span>;</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   46</span> </p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   47</span>                 <span style="color: #00bfff">var</span> <span style="color: #c4c4c4">result</span> <span style="color: silver">=</span> <span style="color: #c4c4c4">_dispatcher</span></p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   48</span>                     <span style="color: silver">.</span><span style="color: #c4c4c4">GetResponder</span>(<span style="color: #c4c4c4">GetCommandKey</span>(<span style="color: #c4c4c4">url</span>, <span style="color: #c4c4c4">encoding</span>))</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   49</span>                     <span style="color: silver">.</span><span style="color: #c4c4c4">RespondTo</span>(<span style="color: #c4c4c4">GetCommandArguments</span>(<span style="color: #c4c4c4">url</span>, <span style="color: #c4c4c4">encoding</span>));</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   50</span> </p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   51</span>                 <span style="color: #c4c4c4">Respond</span>(<span style="color: #c4c4c4">context</span>, <span style="color: #c4c4c4">encoding</span>, <span style="color: #c4c4c4">result</span>);</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   52</span>             }</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   53</span>             <span style="color: #00bfff">catch</span> (<span style="color: #00d2d2">Exception</span> <span style="color: #c4c4c4">ex</span>)</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   54</span>             {</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   55</span>                 <span style="color: #bdb76b">// Don&#8217;t want the service to die, just log it..</span></p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   56</span>                 <span style="color: #00d2d2">Console</span><span style="color: silver">.</span><span style="color: #c4c4c4">WriteLine</span>(<span style="color: #c4c4c4">ex</span><span style="color: silver">.</span><span style="color: #c4c4c4">ToString</span>());</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   57</span>                 <span style="color: #bdb76b">// Could then responde with some error code&#8230;</span></p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   58</span>             }</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   59</span>         },</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   60</span>         <span style="color: #c4c4c4">incomingRequestContext</span>);</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   61</span>     }</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   62</span> </p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   63</span>     <span style="color: #00bfff">private</span> <span style="color: #00bfff">static</span> <span style="color: #00bfff">string</span> <span style="color: #c4c4c4">GetCommandKey</span>(<span style="color: #00d2d2">Uri</span> <span style="color: #c4c4c4">url</span>, <span style="color: #00d2d2">Encoding</span> <span style="color: #c4c4c4">encoding</span>)</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   64</span>     {</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   65</span>         <span style="color: #bdb76b">// AbsolutePath always starts with a &#8216;/&#8217;</span></p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   66</span>         <span style="color: #00bfff">return</span> <span style="color: #00d2d2">HttpUtility</span><span style="color: silver">.</span><span style="color: #c4c4c4">UrlDecode</span>(<span style="color: #c4c4c4">url</span><span style="color: silver">.</span><span style="color: #c4c4c4">AbsolutePath</span><span style="color: silver">.</span><span style="color: #c4c4c4">Substring</span>(<span style="color: #80ff00">1</span>), <span style="color: #c4c4c4">encoding</span>);</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   67</span>     }</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   68</span>     <span style="color: #00bfff">private</span> <span style="color: #00bfff">static</span> <span style="color: #00bfff">string</span> <span style="color: #c4c4c4">GetCommandArguments</span>(<span style="color: #00d2d2">Uri</span> <span style="color: #c4c4c4">url</span>, <span style="color: #00d2d2">Encoding</span> <span style="color: #c4c4c4">encoding</span>)</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   69</span>     {</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   70</span>         <span style="color: #bdb76b">// Query always starts with a &#8216;?&#8217;, but may be null</span></p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   71</span>         <span style="color: #00bfff">return</span> <span style="color: #c4c4c4">url</span><span style="color: silver">.</span><span style="color: #c4c4c4">Query</span> <span style="color: silver">!=</span> <span style="color: #00bfff">null</span> <span style="color: silver">&#038;&#038;</span> <span style="color: #c4c4c4">url</span><span style="color: silver">.</span><span style="color: #c4c4c4">Query</span><span style="color: silver">.</span><span style="color: #c4c4c4">Length</span> <span style="color: silver">></span> <span style="color: #80ff00">1</span></p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   72</span>                         <span style="color: silver">?</span> <span style="color: #00d2d2">HttpUtility</span><span style="color: silver">.</span><span style="color: #c4c4c4">UrlDecode</span>(<span style="color: #c4c4c4">url</span><span style="color: silver">.</span><span style="color: #c4c4c4">Query</span><span style="color: silver">.</span><span style="color: #c4c4c4">Substring</span>(<span style="color: #80ff00">1</span>), <span style="color: #c4c4c4">encoding</span>)</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   73</span>                         : <span style="color: #00bfff">string</span><span style="color: silver">.</span><span style="color: #c4c4c4">Empty</span>;</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   74</span>     }</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   75</span>     <span style="color: #00bfff">private</span> <span style="color: #00bfff">static</span> <span style="color: #00bfff">void</span> <span style="color: #c4c4c4">Respond</span>(<span style="color: #00d2d2">HttpListenerContext</span> <span style="color: #c4c4c4">context</span>, <span style="color: #00d2d2">Encoding</span> <span style="color: #c4c4c4">encoding</span>, <span style="color: #00bfff">string</span> <span style="color: #c4c4c4">result</span>)</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   76</span>     {</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   77</span>         <span style="color: #00bfff">var</span> <span style="color: #c4c4c4">bytes</span> <span style="color: silver">=</span> <span style="color: #c4c4c4">encoding</span><span style="color: silver">.</span><span style="color: #c4c4c4">GetBytes</span>(<span style="color: #c4c4c4">result</span>);</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   78</span>         <span style="color: #c4c4c4">context</span><span style="color: silver">.</span><span style="color: #c4c4c4">Response</span><span style="color: silver">.</span><span style="color: #c4c4c4">ContentLength64</span> <span style="color: silver">=</span> <span style="color: #c4c4c4">bytes</span><span style="color: silver">.</span><span style="color: #c4c4c4">Length</span>;</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   79</span>         <span style="color: #c4c4c4">context</span><span style="color: silver">.</span><span style="color: #c4c4c4">Response</span><span style="color: silver">.</span><span style="color: #c4c4c4">OutputStream</span><span style="color: silver">.</span><span style="color: #c4c4c4">Write</span>(<span style="color: #c4c4c4">bytes</span>, <span style="color: #80ff00">0</span>, <span style="color: #c4c4c4">bytes</span><span style="color: silver">.</span><span style="color: #c4c4c4">Length</span>);</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   80</span>         <span style="color: #c4c4c4">context</span><span style="color: silver">.</span><span style="color: #c4c4c4">Response</span><span style="color: silver">.</span><span style="color: #c4c4c4">StatusCode</span> <span style="color: silver">=</span> <span style="color: #80ff00">200</span>; <span style="color: #bdb76b">// everything is ok <img src='http://blog.kjempekjekt.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </span></p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   81</span>         <span style="color: #c4c4c4">context</span><span style="color: silver">.</span><span style="color: #c4c4c4">Response</span><span style="color: silver">.</span><span style="color: #c4c4c4">Close</span>();</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   82</span>     }</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   83</span> }</p>
</div>
<p>Etter å ha opprettet HttpListener kjører jeg en uendelig løkke som mottar innkommende forespørsler og håndterer dem (en robust implementasjon ville også hatt en Stop-metode som terminerte løkken). Kallet til GetContext() i linje 37 returnerer når en request mottas, og så bruker jeg ThreadPool til å <em>spawn&#8217;e</em> en ny tråd som håndterer den og svarer tilbake.</p>
<p>Denne serveren bruker selve URL&#8217;en til å avgjøre hva den skal gjøre. I eksempelet i starten av artikkelen var requesten <u>http://127.0.0.1:8081/time?</u>. Alt etter domenet og porten men før spørsmålstegnet bruker jeg til å avgjøre hvilken <strong><em>Responder</em></strong> som skal brukes. Det er her STARTEGY pattern kommer inn i bildet – en responder er en klasse som implementerer interfacet <em>Responder</em>…</p>
<div style="padding-left: 5px; font-family: monospace; margin-bottom: 12px; background: #202020; color: #e0e0e0; font-size: 9pt">
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">    5</span> <span style="color: #00bfff">public</span> <span style="color: #00bfff">interface</span> <span style="color: #7ee0ce">Responder</span></p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">    6</span> {</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">    7</span>     <span style="color: #00bfff">string</span> <span style="color: #c4c4c4">RespondTo</span>(<span style="color: #00bfff">string</span> <span style="color: #c4c4c4">arguments</span>);</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">    8</span> }</p>
</div>
<div style="padding-left: 5px; font-family: monospace; margin-bottom: 12px; background: #202020; color: #e0e0e0; font-size: 9pt">
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">    5</span> <span style="color: #00bfff">public</span> <span style="color: #00bfff">interface</span> <span style="color: #7ee0ce">ResponderFactory</span></p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">    6</span> {</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">    7</span>     <span style="color: #7ee0ce">Responder</span> <span style="color: #c4c4c4">GetResponder</span>(<span style="color: #00bfff">string</span> <span style="color: #c4c4c4">responderKey</span>);</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">    8</span> }</p>
</div>
<p>Argumentene som sendes til responderen er alt som kommer etter spørsmålstegnet i requesten. HttpListener støtter mye mer enn dette, men alt jeg er interessert i denne gangen er selve URL&#8217;en.</p>
<p>SimpleHttpServer ble initialisert med en ResponderFactory. Denne vil - gitt en nøkkel - returnere riktig responder. Ta en titt til på serveren om du ikke fikk det helt med deg første gangen, spesielt linje 47 til 49.</p>
<p>En første versjon av ResponderFactory (den faktiske implementasjonen kommer lengre nede) kunne vært en klasse som uansett nøkkel returnerte en UnknownCommandResponder:</p>
<div style="padding-left: 5px; font-family: monospace; margin-bottom: 12px; background: #202020; color: #e0e0e0; font-size: 9pt">
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">    5</span> <span style="color: #00bfff">public</span> <span style="color: #00bfff">class</span> <span style="color: #00d2d2">UnknownCommandResponder</span> : <span style="color: #7ee0ce">Responder</span></p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">    6</span> {</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">    7</span>     <span style="color: #00bfff">private</span> <span style="color: #00bfff">string</span> <span style="color: #c4c4c4">_request</span>;</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">    8</span>     <span style="color: #00bfff">public</span> <span style="color: #c4c4c4">UnknownCommandResponder</span>(<span style="color: #00bfff">string</span> <span style="color: #c4c4c4">request</span>)</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">    9</span>     {</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   10</span>         <span style="color: #c4c4c4">_request</span> <span style="color: silver">=</span> <span style="color: #c4c4c4">request</span>;</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   11</span>     }</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   12</span>     <span style="color: #00bfff">public</span> <span style="color: #00bfff">string</span> <span style="color: #c4c4c4">RespondTo</span>(<span style="color: #00bfff">string</span> <span style="color: #c4c4c4">arguments</span>)</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   13</span>     {</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   14</span>         <span style="color: #00bfff">return</span> <span style="color: #00d2d2">String</span><span style="color: silver">.</span><span style="color: #c4c4c4">Format</span>(<span style="color: #fa8072">&#8220;Unknown command: &#8216;{0}&#8217; with arguments &#8216;{1}&#8217;&#8221;</span>, </p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   15</span>             <span style="color: #c4c4c4">_request</span>, </p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   16</span>             <span style="color: #c4c4c4">arguments</span>);</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   17</span>     }</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   18</span> }</p>
</div>
<p>Det kan være greit å ha en slik default strategi/responder til å svare på alle mulige ting man måtte finne på å etterspørre. Her ser du den i aksjon:</p>
<p><img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="CropperCapture[46]" border="0" alt="CropperCapture[46]" src="http://blog.kjempekjekt.com/wp-content/uploads/2010/02/CropperCapture46.png" width="498" height="169"> </p>
<h4>Opprette flere tjenester: Attributter og reflection</h4>
<p>Før jeg legger til den første &#8220;fornuftige&#8221; responderen oppretter jeg et .net-attributt. Det trenger ikke være noe mer avansert enn å lage en klassen som arver fra Attribute.</p>
<div style="padding-left: 5px; font-family: monospace; margin-bottom: 12px; background: #202020; color: #e0e0e0; font-size: 9pt">
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">    6</span> <span style="color: #00bfff">public</span> <span style="color: #00bfff">class</span> <span style="color: #00d2d2">RespondToAttribute</span> : <span style="color: #00d2d2">Attribute</span></p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">    7</span> {</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">    8</span>     <span style="color: #00bfff">public</span> <span style="color: #00bfff">string</span> <span style="color: #c4c4c4">Key</span> { <span style="color: #00bfff">get</span>; <span style="color: #00bfff">set</span>; }</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">    9</span>     <span style="color: #00bfff">public</span> <span style="color: #c4c4c4">RespondToAttribute</span>(<span style="color: #00bfff">string</span> <span style="color: #c4c4c4">key</span>) { </p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   10</span>         <span style="color: #c4c4c4">Key</span> <span style="color: silver">=</span> <span style="color: #c4c4c4">key</span>; </p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   11</span>     }</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   12</span> }</p>
</div>
<p>Jeg har laget svært få attributter i min karriære, men det er en teknikk som kan gi veldig elegante løsninger om det brukes riktig. Måten jeg bruker det på her er ganske vanlig. Og enkel! Den vil rett og slett la meg legge til nye respondere uten at jeg behøver å endre noen eksisterende kode. </p>
<p>Men first thing first: Når jeg implementerer mine respondere vil RespondToAttribute la meg spesifisere hvilken nøkkel hver responder gjelder for. Her er f.eks. en enkel responder som legger sammen en rekke med tall separert med komma:</p>
<div style="padding-left: 5px; font-family: monospace; margin-bottom: 12px; background: #202020; color: #e0e0e0; font-size: 9pt">
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">    6</span> [<span style="color: #00d2d2">RespondTo</span>(<span style="color: #fa8072">&#8220;add&#8221;</span>)]</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">    7</span> <span style="color: #00bfff">public</span> <span style="color: #00bfff">class</span> <span style="color: #00d2d2">Add</span> : <span style="color: #7ee0ce">Responder</span></p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">    8</span> {</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">    9</span>     <span style="color: #00bfff">public</span> <span style="color: #00bfff">string</span> <span style="color: #c4c4c4">RespondTo</span>(<span style="color: #00bfff">string</span> <span style="color: #c4c4c4">arguments</span>)</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   10</span>     {</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   11</span>         <span style="color: #00bfff">int</span> <span style="color: #c4c4c4">result</span> <span style="color: silver">=</span> <span style="color: #80ff00">0</span>;</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   12</span>         <span style="color: #00d2d2">Array</span><span style="color: silver">.</span><span style="color: #c4c4c4">ForEach</span>(<span style="color: #c4c4c4">arguments</span><span style="color: silver">.</span><span style="color: #c4c4c4">Split</span>(<span style="color: #fa8072">&#8216;,&#8217;</span>),</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   13</span>             (<span style="color: #c4c4c4">arg</span>) <span style="color: silver">=></span> <span style="color: #c4c4c4">result</span> <span style="color: silver">+=</span> <span style="color: #00d2d2">Int32</span><span style="color: silver">.</span><span style="color: #c4c4c4">Parse</span>(<span style="color: #c4c4c4">arg</span>));            </p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   14</span>         <span style="color: #00bfff">return</span> <span style="color: #00bfff">string</span><span style="color: silver">.</span><span style="color: #c4c4c4">Format</span>(<span style="color: #fa8072">&#8220;The answer is {0}&#8221;</span>, <span style="color: #c4c4c4">result</span>);</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   15</span>     }</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   16</span> }</p>
</div>
<p>(Det er en konvensjon i .Net at man slipper å skrive &#8220;Attribute&#8221;-delen av attributt-navnet. Dermed blir linje 6 så fin.., denne klassen <em>&#8220;responderer på add&#8221;</em>.)</p>
<p>Når jeg gjør ting som dette er det typisk endel implisitte regler jeg må følge. I dette tilfelle vil det for eksempel ikke gi mening om mer enn én klasse responderer på &#8220;add&#8221;. Nøkkelen må med andre ord være unik. For å håndheve slike regler oppretter jeg som regel validerende enhetstester. Følgende test bruker reflection til å hente ut alle typer i prosjektet, samle opp alle RespondToAttributes fra typene, og sjekke at de er unike..</p>
<div style="padding-left: 5px; font-family: monospace; margin-bottom: 12px; background: #202020; color: #e0e0e0; font-size: 9pt">
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   12</span> [<span style="color: #00d2d2">Test</span>]</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   13</span> <span style="color: #00bfff">public</span> <span style="color: #00bfff">void</span> <span style="color: #c4c4c4">Should_all_be_unique</span>()</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   14</span> {</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   15</span>     <span style="color: #00bfff">var</span> <span style="color: #c4c4c4">keys</span> <span style="color: silver">=</span> <span style="color: #00bfff">new</span> <span style="color: #00d2d2">List</span><span style="color: silver"><</span><span style="color: #00bfff">string</span><span style="color: silver">></span>();</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   16</span>     <span style="color: #00bfff">var</span> <span style="color: #c4c4c4">allTypes</span> <span style="color: silver">=</span> <span style="color: #00d2d2">Assembly</span><span style="color: silver">.</span><span style="color: #c4c4c4">GetExecutingAssembly</span>()<span style="color: silver">.</span><span style="color: #c4c4c4">GetTypes</span>();</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   17</span>     <span style="color: #00bfff">foreach</span> (<span style="color: #00bfff">var</span> <span style="color: #c4c4c4">t</span> <span style="color: #00bfff">in</span> <span style="color: #c4c4c4">allTypes</span>)</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   18</span>     {</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   19</span>         <span style="color: #00bfff">var</span> <span style="color: #c4c4c4">attribute</span> <span style="color: silver">=</span> <span style="color: #00d2d2">Attribute</span></p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   20</span>             <span style="color: silver">.</span><span style="color: #c4c4c4">GetCustomAttribute</span>(<span style="color: #c4c4c4">t</span>, <span style="color: #00bfff">typeof</span>(<span style="color: #00d2d2">RespondToAttribute</span>))</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   21</span>             <span style="color: #00bfff">as</span> <span style="color: #00d2d2">RespondToAttribute</span>;</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   22</span> </p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   23</span>         <span style="color: #00bfff">if</span> (<span style="color: #c4c4c4">attribute</span> <span style="color: silver">==</span> <span style="color: #00bfff">null</span>)</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   24</span>             <span style="color: #00bfff">continue</span>;</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   25</span> </p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   26</span>         <span style="color: #00bfff">if</span> (<span style="color: #c4c4c4">keys</span><span style="color: silver">.</span><span style="color: #c4c4c4">Contains</span>(<span style="color: #c4c4c4">attribute</span><span style="color: silver">.</span><span style="color: #c4c4c4">Key</span>))</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   27</span>             <span style="color: #00d2d2">Assert</span><span style="color: silver">.</span><span style="color: #c4c4c4">Fail</span>(<span style="color: #c4c4c4">attribute</span><span style="color: silver">.</span><span style="color: #c4c4c4">Key</span> <span style="color: silver">+</span> <span style="color: #fa8072">&#8221; appear more than once!&#8221;</span>);</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   28</span> </p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   29</span>         <span style="color: #c4c4c4">keys</span><span style="color: silver">.</span><span style="color: #c4c4c4">Add</span>(<span style="color: #c4c4c4">attribute</span><span style="color: silver">.</span><span style="color: #c4c4c4">Key</span>);</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   30</span>     }</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   31</span> }</p>
</div>
<p>Og denne samme teknikken vil jeg bruke når jeg implementerer den endelige ResponderFactory-klassen. Den oppretter en dictionary med nøkler mappet til respondere (eller mer nøyaktig mappet til funksjoner som oppretter respondere).</p>
<div style="padding-left: 5px; font-family: monospace; margin-bottom: 12px; background: #202020; color: #e0e0e0; font-size: 9pt">
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">    7</span> <span style="color: #00bfff">public</span> <span style="color: #00bfff">class</span> <span style="color: #00d2d2">ReflectiveResponderFactory</span> : <span style="color: #7ee0ce">ResponderFactory</span></p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">    8</span> {</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">    9</span>     <span style="color: #00bfff">private</span> <span style="color: #00d2d2">Dictionary</span><span style="color: silver"><</span><span style="color: #00bfff">string</span>, <span style="color: yellow">Func</span><span style="color: silver"><</span><span style="color: #7ee0ce">Responder</span><span style="color: silver">>></span> <span style="color: #c4c4c4">_dispatchTable</span>;</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   10</span> </p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   11</span>     <span style="color: #00bfff">public</span> <span style="color: #c4c4c4">ReflectiveResponderFactory</span>()</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   12</span>     {</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   13</span>         <span style="color: #c4c4c4">_dispatchTable</span> <span style="color: silver">=</span> <span style="color: #00bfff">new</span> <span style="color: #00d2d2">Dictionary</span><span style="color: silver"><</span><span style="color: #00bfff">string</span>, <span style="color: yellow">Func</span><span style="color: silver"><</span><span style="color: #7ee0ce">Responder</span><span style="color: silver">>></span>();</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   14</span>         <span style="color: #00d2d2">Array</span><span style="color: silver">.</span><span style="color: #c4c4c4">ForEach</span>(<span style="color: #00d2d2">Assembly</span><span style="color: silver">.</span><span style="color: #c4c4c4">GetExecutingAssembly</span>()<span style="color: silver">.</span><span style="color: #c4c4c4">GetTypes</span>(),</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   15</span>             (<span style="color: #c4c4c4">type</span>) <span style="color: silver">=></span> <span style="color: #c4c4c4">AddDispatchIfResponder</span>(<span style="color: #c4c4c4">type</span>, <span style="color: #c4c4c4">GetResponderInfo</span>(<span style="color: #c4c4c4">type</span>)));</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   16</span>     }</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   17</span>     <span style="color: #00bfff">private</span> <span style="color: #00bfff">static</span> <span style="color: #00d2d2">RespondToAttribute</span> <span style="color: #c4c4c4">GetResponderInfo</span>(<span style="color: #00d2d2">Type</span> <span style="color: #c4c4c4">maybeResponderType</span>)</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   18</span>     {</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   19</span>         <span style="color: #00bfff">return</span> <span style="color: #00d2d2">Attribute</span><span style="color: silver">.</span><span style="color: #c4c4c4">GetCustomAttribute</span>(<span style="color: #c4c4c4">maybeResponderType</span>,</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   20</span>             <span style="color: #00bfff">typeof</span>(<span style="color: #00d2d2">RespondToAttribute</span>)) <span style="color: #00bfff">as</span> <span style="color: #00d2d2">RespondToAttribute</span>;</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   21</span>     }</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   22</span>     <span style="color: #00bfff">private</span> <span style="color: #00bfff">void</span> <span style="color: #c4c4c4">AddDispatchIfResponder</span>(<span style="color: #00d2d2">Type</span> <span style="color: #c4c4c4">type</span>, <span style="color: #00d2d2">RespondToAttribute</span> <span style="color: #c4c4c4">responderInfo</span>)</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   23</span>     {</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   24</span>         <span style="color: #00bfff">if</span> (<span style="color: #c4c4c4">responderInfo</span> <span style="color: silver">!=</span> <span style="color: #00bfff">null</span>)</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   25</span>             <span style="color: #c4c4c4">_dispatchTable</span><span style="color: silver">.</span><span style="color: #c4c4c4">Add</span>(</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   26</span>                 <span style="color: #c4c4c4">responderInfo</span><span style="color: silver">.</span><span style="color: #c4c4c4">Key</span>,</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   27</span>                 () <span style="color: silver">=></span> <span style="color: #00d2d2">Activator</span><span style="color: silver">.</span><span style="color: #c4c4c4">CreateInstance</span>(<span style="color: #c4c4c4">type</span>) <span style="color: #00bfff">as</span> <span style="color: #7ee0ce">Responder</span>);</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   28</span>     }</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   29</span> </p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   30</span>     <span style="color: #00bfff">public</span> <span style="color: #7ee0ce">Responder</span> <span style="color: #c4c4c4">GetResponder</span>(<span style="color: #00bfff">string</span> <span style="color: #c4c4c4">responderKey</span>)</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   31</span>     {</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   32</span>         <span style="color: #00bfff">if</span> (<span style="color: silver">!</span><span style="color: #c4c4c4">_dispatchTable</span><span style="color: silver">.</span><span style="color: #c4c4c4">ContainsKey</span>(<span style="color: #c4c4c4">responderKey</span>))</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   33</span>             <span style="color: #00bfff">return</span> <span style="color: #00bfff">new</span> <span style="color: #00d2d2">UnknownCommandResponder</span>(<span style="color: #c4c4c4">responderKey</span>);</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   34</span>         <span style="color: #00bfff">return</span> <span style="color: #c4c4c4">_dispatchTable</span>[<span style="color: #c4c4c4">responderKey</span>]<span style="color: silver">.</span><span style="color: #c4c4c4">Invoke</span>();</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   35</span>     }</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   36</span> }</p>
</div>
<p>Her forutsettes det at alle respondere (med RespondTo-attributt) har en default, parameter-løs konstruktør, slik at den kan opprettes i lambda-uttrykket i linje 27. Du bør opprette en enhetstest for å validere dette også, slik at ingen lager en responder med konstruktør-parametre i fremtiden og dermed introduserer en bug (ikke at de ikke ville ha oppdaget det, men rask tilbakemelding er alltid kjekt).</p>
<p>Om du nå har skjønt hvordan disse klassene henger sammen gjenstår det bare å opprette og starte en SimpleHttpServer for at dette skal fungere. Her kjører jeg serveren i et konsollprogram, men i et mer realistisk senario vil du typisk kjøre den i en enkel Windows service.</p>
<div style="padding-left: 5px; font-family: monospace; margin-bottom: 12px; background: #202020; color: #e0e0e0; font-size: 9pt">
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">    7</span> <span style="color: #00bfff">static</span> <span style="color: #00bfff">void</span> <span style="color: #c4c4c4">Main</span>(<span style="color: #00bfff">string</span>[] <span style="color: #c4c4c4">args</span>)</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">    8</span> {</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">    9</span>     <span style="color: #00bfff">new</span> <span style="color: #00d2d2">SimpleHttpServer</span></p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   10</span>         (<span style="color: #fa8072">&#8220;*&#8221;</span>, <span style="color: #80ff00">8081</span>, <span style="color: #00bfff">new</span> <span style="color: #00d2d2">ReflectiveResponderFactory</span>())</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   11</span>         <span style="color: silver">.</span><span style="color: #c4c4c4">Start</span>();</p>
<p style="line-height: 11pt; margin: 0px"><span style="background: #282828; color: gray">   12</span> }</p>
</div>
<p>Og nå kan vi endelig få vite hvor mye 10 + 20 + 30 er…</p>
<p><img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="CropperCapture[47]" border="0" alt="CropperCapture[47]" src="http://blog.kjempekjekt.com/wp-content/uploads/2010/02/CropperCapture47.png" width="498" height="169"></p>
<p>For å utvide serveren med mer funksjonalitet er det nå bare til å opprette flere klasser som arver fra Responder-interfacet, og legge til et RespondToAttribute. ReflectiveResponderFactory vil finne og registrere den nye klassen under oppstart, og delegere til en ny instans av responderen om nøkkelen kommer i en forespørsel.</p>
<p>Jeg håper noen klarte å henge med óg få noe fornuftig ut av dette. Mer info om <a href="http://msdn.microsoft.com/en-us/library/system.net.httplistener.aspx" target="_blank">HttpListener finner du her</a>, og <a href="http://www.google.no/search?q=.net+attributes" target="_blank">info om .net attributes finner du via google</a>. I <a href="http://blog.kjempekjekt.com/2010/02/22/en-minimal-http-server-i-ruby/">neste blogpost</a> vil du få se hvordan jeg implementerer nøyaktig samme funksjonalitet ved hjelp av Ruby.</p>
<p><strong>Knagger:</strong> <a href="http://blog.kjempekjekt.com/index.php?s=SOAP" rel="tag">SOAP</a>, <a href="http://blog.kjempekjekt.com/index.php?s=Strategy" rel="tag">Strategy</a>, <a href="http://blog.kjempekjekt.com/index.php?s=WCF" rel="tag">WCF</a></p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/kjempekjektcom?a=EdLLGobpIaY:w3OCfn510c4:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/kjempekjektcom?i=EdLLGobpIaY:w3OCfn510c4:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/kjempekjektcom?a=EdLLGobpIaY:w3OCfn510c4:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/kjempekjektcom?d=yIl2AUoC8zA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/kjempekjektcom/~4/EdLLGobpIaY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRSS>http://blog.kjempekjekt.com/2010/02/18/en-minimal-http-server-i-net/feed/</wfw:commentRSS>
		<feedburner:origLink>http://blog.kjempekjekt.com/2010/02/18/en-minimal-http-server-i-net/</feedburner:origLink></item>
		<item>
		<title>PSWinCom drar til Qcon London 2010</title>
		<link>http://feedproxy.google.com/~r/kjempekjektcom/~3/rbPjOgTGTs8/</link>
		<comments>http://blog.kjempekjekt.com/2010/02/05/pswincom-drar-til-qcon-london-2010/#comments</comments>
		<pubDate>Fri, 05 Feb 2010 12:47:16 +0000</pubDate>
		<dc:creator>Torbjørn</dc:creator>
		
	<category>Jobb</category>
	<category>NNUG / community</category>
		<guid isPermaLink="false">http://blog.kjempekjekt.com/2010/02/05/pswincom-drar-til-qcon-london-2010/</guid>
		<description><![CDATA[I mars pakker fire utviklere fra PSWinCom kofferten og drar på utviklerkonferanse: QCon London 2010. QCon er en årlig konferanse som sier de retter seg mot arkitekter, teamledere og prosjektledere, men alle som brenner for systemutvikling vil garantert finne mye av interesse.
Konferansen har ikke noe leverandør-fokus, og dekker arkitektur og design i en nøytral kontekst. [...]]]></description>
			<content:encoded><![CDATA[<p><img style="border-right-width: 0px; margin: 0px 15px 5px 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="qcon-logo" border="0" alt="qcon-logo" align="left" src="http://blog.kjempekjekt.com/wp-content/uploads/2010/02/qconlogo.gif" width="172" height="121">I mars pakker fire utviklere fra <a href="http://pswin.com">PSWinCom</a> kofferten og drar på utviklerkonferanse: <a href="http://qconlondon.com/"><strong>QCon London 2010</strong></a>. QCon er en årlig konferanse som sier de retter seg mot arkitekter, teamledere og prosjektledere, men alle som brenner for systemutvikling vil garantert finne mye av interesse.</p>
<p>Konferansen har <em>ikke</em> noe leverandør-fokus, og dekker arkitektur og design i en nøytral kontekst. QCon 2010 har hele 15 spor, og strekker seg over tre dager. Sentrale tema er ting som utvikling innen programmeringsspråk, craftsmanship, smidige metoder og test-dreven utvikling, nettskyen, browseren som plattform, og SOA. Java og .NET, som de to viktigste utviklingsmiljøene for enterprise, har også hvert sitt spor.</p>
<p>QCon er en konferanse som trekker <em>the best of the best</em> i bransjen. Denne gangen har arrangørene samlet 100 forelesere(!!!), og keynotes holdes av <strong>Dan Ingalls</strong> (Smalltalk-gud) og <strong>Uncle Bob <em>&#8220;I want to code till I die&#8221;</em> Martin</strong>. Her er 15 glimrende grunner til at vi drar i år:</p>
<p><img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="qcon" border="0" alt="qcon" src="http://blog.kjempekjekt.com/wp-content/uploads/2010/02/qcon.jpg" width="481" height="311"></p>
<p>Jeg er spesielt interessert i foredragene som fokuserer på concurrency og skalering, og tror vi kan plukke opp mye bra her som kan gjøre PSWinCom&#8217;s produkter og leveranse enda bedre. Allerede nå har jeg bestemt meg for å følge sporene <a href="http://qconlondon.com/london-2010/tracks/show_track.jsp?trackOID=327">Software Craftsmanship</a> og <a href="http://qconlondon.com/london-2010/tracks/show_track.jsp?trackOID=333">The Concurrency Challange</a> nøye - sistnevnte med sterkt fokus på funksjonsbaserte språk som Erlang og Haskell. Bortsett fra dette blir det som vanlig en ganske stor utfordring å besteme seg for hvilke av de parallelle sesjonene man skal gå på – f.eks. høres både <a href="http://qconlondon.com/london-2010/tracks/show_track.jsp?trackOID=334">Pragmatic Cloud Computing</a> og <a href="http://qconlondon.com/london-2010/tracks/show_track.jsp?trackOID=329">Irresposible Architectures and Unusual Architects</a> ut som veldig spennende spor, og kolliderer ganske kraftig. </p>
<p><a href="http://nnug.no/">NNUG</a> har forresten fått til en deal med QCon, hvor alle medlemmer får £297 av på fullpris om de registrerer seg før 22. februar (med koden &#8220;NNUG&#8221;). Vi er en liten gjeng fra Bergen som drar over sjøen, og forhåpentligvis kommer det noen fra andre steder av landet også. NNUG kommer til å arrangere en sosial samling i løpet av konferansen på et egnet sted (hørte jeg pub? Selvsagt hørte jeg pub!). <span style="color: goldenrod"><strong>Hvis du som leser dette også skal på QCon så hadde det vært hyggelig om du la igjen en kommentar så vi vet om deg!</strong></span></p>
<p>Hva med <a href="http://www.ndc2010.no/">NDC 2010</a> da? I fjor var jeg veldig gira på å dra på NDC, og det ble en flott konferanse med mange, spennende sesjoner. Det ser ut til å bli minst like bra i år, og det vil nok føles litt rart når norges utvikler-community samles i Oslo uten oss i sommer - men for vår del hadde vi lyst til å gjøre noe nytt, så da ble det QCon denne gangen.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/kjempekjektcom?a=rbPjOgTGTs8:JtafJrlJ1Xc:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/kjempekjektcom?i=rbPjOgTGTs8:JtafJrlJ1Xc:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/kjempekjektcom?a=rbPjOgTGTs8:JtafJrlJ1Xc:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/kjempekjektcom?d=yIl2AUoC8zA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/kjempekjektcom/~4/rbPjOgTGTs8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRSS>http://blog.kjempekjekt.com/2010/02/05/pswincom-drar-til-qcon-london-2010/feed/</wfw:commentRSS>
		<feedburner:origLink>http://blog.kjempekjekt.com/2010/02/05/pswincom-drar-til-qcon-london-2010/</feedburner:origLink></item>
	</channel>
</rss>
