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

<channel>
	<title>MoMolog &#187; Ruby</title>
	<atom:link href="http://momolog.info/category/ruby/feed/" rel="self" type="application/rss+xml" />
	<link>http://momolog.info</link>
	<description>MoMolog aus Berlin stellt sich vor. Projekte, Ideen, Referenzen.</description>
	<lastBuildDate>Sat, 07 Apr 2012 23:23:44 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.2</generator>
		<item>
		<title>Using throw and catch to tidy up our code</title>
		<link>http://momolog.info/2012/03/29/using-throw-and-catch-in-controllers/</link>
		<comments>http://momolog.info/2012/03/29/using-throw-and-catch-in-controllers/#comments</comments>
		<pubDate>Thu, 29 Mar 2012 10:17:25 +0000</pubDate>
		<dc:creator>aljoscha</dc:creator>
				<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://momolog.info/?p=316</guid>
		<description><![CDATA[Let&#8217;s say we want a simple controller action that checks, if a given code is valid. It should return true and false and, if the code is invalid, give the reason (whether that is because it is unknown or because it has been used already). The action could look like this: Now this deep nesting [...]]]></description>
			<content:encoded><![CDATA[<p>Let&#8217;s say we want a simple controller action that checks, if a given code is valid.<br />
It should return true and false and, if the code is invalid, give the reason (whether that is because it is unknown or because it has been used already). The action could look like this:</p>
<p><div id="gist-2235608" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="k">def</span> <span class="nf">valid</span></div><div class='line' id='LC2'>&nbsp;&nbsp;<span class="k">if</span> <span class="n">code</span> <span class="o">=</span> <span class="no">Code</span><span class="o">.</span><span class="n">find_by_value</span><span class="p">(</span><span class="n">params</span><span class="o">[</span><span class="ss">:id</span><span class="o">]</span><span class="p">)</span></div><div class='line' id='LC3'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">unless</span> <span class="n">code</span><span class="o">.</span><span class="n">used?</span></div><div class='line' id='LC4'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">respond_with</span> <span class="ss">:valid</span> <span class="o">=&gt;</span> <span class="kp">true</span></div><div class='line' id='LC5'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">else</span></div><div class='line' id='LC6'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">respond_with</span> <span class="ss">:valid</span> <span class="o">=&gt;</span> <span class="kp">false</span><span class="p">,</span> <span class="ss">:reason</span> <span class="o">=&gt;</span> <span class="s1">&#39;used&#39;</span></div><div class='line' id='LC7'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">end</span> </div><div class='line' id='LC8'>&nbsp;&nbsp;<span class="k">else</span></div><div class='line' id='LC9'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">respond_with</span> <span class="ss">:valid</span> <span class="o">=&gt;</span> <span class="kp">false</span><span class="p">,</span> <span class="ss">:reason</span> <span class="o">=&gt;</span> <span class="s1">&#39;unknown&#39;</span></div><div class='line' id='LC10'>&nbsp;&nbsp;<span class="k">end</span> </div><div class='line' id='LC11'><span class="k">end</span> </div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/2235608/3eb1d48a47361bb1b7d1bd60716e0124f44bd284/nested.rb" style="float:right;">view raw</a>
            <a href="https://gist.github.com/2235608#file_nested.rb" style="float:right;margin-right:10px;color:#666">nested.rb</a>
            <a href="https://gist.github.com/2235608">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</p>
<p>Now this deep nesting effectively hides the underlying algorithm, a simple one in this case.<br />
Expressing this using <code>throw</code> and <code>catch</code> straightens the code a bit:</p>
<p><div id="gist-2235614" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="k">def</span> <span class="nf">valid</span></div><div class='line' id='LC2'>&nbsp;&nbsp;<span class="n">failure</span> <span class="o">=</span> <span class="kp">catch</span> <span class="ss">:fail</span> <span class="k">do</span></div><div class='line' id='LC3'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">code</span> <span class="o">=</span> <span class="no">Code</span><span class="o">.</span><span class="n">find_by_value</span><span class="p">(</span><span class="n">params</span><span class="o">[</span><span class="ss">:id</span><span class="o">]</span><span class="p">)</span> <span class="ow">or</span> <span class="kp">throw</span><span class="p">(</span><span class="ss">:fail</span><span class="p">,</span> <span class="s1">&#39;unknown&#39;</span><span class="p">)</span></div><div class='line' id='LC4'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">code</span><span class="o">.</span><span class="n">unused?</span>                           <span class="ow">or</span> <span class="kp">throw</span><span class="p">(</span><span class="ss">:fail</span><span class="p">,</span> <span class="s1">&#39;used&#39;</span><span class="p">)</span></div><div class='line' id='LC5'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="kp">nil</span></div><div class='line' id='LC6'>&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC7'>&nbsp;&nbsp;<span class="n">respond_with</span><span class="p">({</span><span class="ss">:valid</span> <span class="o">=&gt;</span> <span class="o">!</span><span class="n">failure</span><span class="p">}</span><span class="o">.</span><span class="n">merge</span><span class="p">(</span><span class="n">failure</span> <span class="p">?</span> <span class="p">{</span><span class="ss">:reason</span> <span class="o">=&gt;</span> <span class="n">failure</span><span class="p">}:</span> <span class="p">{}))</span></div><div class='line' id='LC8'><span class="k">end</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/2235614/a118ac15ff04ad1f189a73b1ff790f1c17e042b3/throw-catch.rb" style="float:right;">view raw</a>
            <a href="https://gist.github.com/2235614#file_throw_catch.rb" style="float:right;margin-right:10px;color:#666">throw-catch.rb</a>
            <a href="https://gist.github.com/2235614">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</p>
<p>We are down to one <code>respond_with</code> line but the has merging and the throws at the beginning of the line are not particularly pretty.</p>
<p>Let&#8217;s introduce a little Ruby mixin for the <code>Hash</code> class that provides it with a <code>compact</code> method that its friend <code>Array</code> has had all along:</p>
<p><div id="gist-2235631" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="k">module</span> <span class="nn">HashExtensions</span></div><div class='line' id='LC2'>&nbsp;&nbsp;<span class="k">def</span> <span class="nf">compact</span></div><div class='line' id='LC3'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="nb">self</span><span class="o">.</span><span class="n">reject</span><span class="p">{</span><span class="o">|</span><span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="o">|</span> <span class="n">value</span><span class="o">.</span><span class="n">nil?</span> <span class="p">}</span></div><div class='line' id='LC4'>&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC5'><span class="k">end</span></div><div class='line' id='LC6'><br/></div><div class='line' id='LC7'><span class="k">class</span> <span class="nc">Hash</span></div><div class='line' id='LC8'>&nbsp;&nbsp;<span class="kp">include</span> <span class="no">HashExtensions</span></div><div class='line' id='LC9'><span class="k">end</span></div><div class='line' id='LC10'><br/></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/2235631/b319e64306d93d94bcb809954b344f59442c3ea2/hash-compact.rb" style="float:right;">view raw</a>
            <a href="https://gist.github.com/2235631#file_hash_compact.rb" style="float:right;margin-right:10px;color:#666">hash-compact.rb</a>
            <a href="https://gist.github.com/2235631">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</p>
<p>Now using this to clean up the response hash and moving the throw statements to the end so the steps of the algorithm are visible we have our final version of the action:</p>
<p><div id="gist-2235618" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="k">def</span> <span class="nf">valid</span></div><div class='line' id='LC2'>&nbsp;&nbsp;<span class="n">failure</span> <span class="o">=</span> <span class="kp">catch</span> <span class="ss">:fail</span> <span class="k">do</span></div><div class='line' id='LC3'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">code</span> <span class="o">=</span> <span class="no">Code</span><span class="o">.</span><span class="n">find_by_value</span><span class="p">(</span><span class="n">params</span><span class="o">[</span><span class="ss">:id</span><span class="o">]</span><span class="p">)</span> <span class="ow">or</span> <span class="kp">throw</span> <span class="ss">:fail</span><span class="p">,</span> <span class="s1">&#39;unknown&#39;</span></div><div class='line' id='LC4'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">code</span><span class="o">.</span><span class="n">unused?</span>                           <span class="ow">or</span> <span class="kp">throw</span> <span class="ss">:fail</span><span class="p">,</span> <span class="s1">&#39;used&#39;</span></div><div class='line' id='LC5'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="kp">nil</span> </div><div class='line' id='LC6'>&nbsp;&nbsp;<span class="k">end</span> </div><div class='line' id='LC7'>&nbsp;&nbsp;<span class="n">respond_with</span><span class="p">({</span><span class="ss">:valid</span> <span class="o">=&gt;</span> <span class="o">!</span><span class="n">failure</span><span class="p">,</span> <span class="ss">:reason</span> <span class="o">=&gt;</span> <span class="n">failure</span><span class="p">}</span><span class="o">.</span><span class="n">compact</span><span class="p">)</span></div><div class='line' id='LC8'><span class="k">end</span> </div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/2235618/23a91505eeedb8d84d0cbeda32daab673be27754/throw-catch-final.rb" style="float:right;">view raw</a>
            <a href="https://gist.github.com/2235618#file_throw_catch_final.rb" style="float:right;margin-right:10px;color:#666">throw-catch-final.rb</a>
            <a href="https://gist.github.com/2235618">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</p>
]]></content:encoded>
			<wfw:commentRss>http://momolog.info/2012/03/29/using-throw-and-catch-in-controllers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Saving local text files to S3 using paperclip</title>
		<link>http://momolog.info/2011/12/02/saving-local-text-files-to-s3-using-paperclip/</link>
		<comments>http://momolog.info/2011/12/02/saving-local-text-files-to-s3-using-paperclip/#comments</comments>
		<pubDate>Fri, 02 Dec 2011 10:49:36 +0000</pubDate>
		<dc:creator>aljoscha</dc:creator>
				<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://momolog.info/?p=290</guid>
		<description><![CDATA[Sometimes you need to save a locally created file to S3 instead of an uploaded file, as is the standard. Here is how: has_attached_file :tagged_text_file, STORAGE_OPTIONS.merge({ :processors => [] }) def save_tagged_text_file file = File.open("#{RAILS_ROOT}/tmp/tagged_text_#{id}.txt", 'w+') file]]></description>
			<content:encoded><![CDATA[<p>Sometimes you need to save a locally created file to S3 instead of an uploaded file, as is the standard. Here is how:</p>
<pre>
  has_attached_file :tagged_text_file,  STORAGE_OPTIONS.merge({
    :processors   => []
  })
</pre>
<pre>
  def save_tagged_text_file
    file = File.open("#{RAILS_ROOT}/tmp/tagged_text_#{id}.txt", 'w+')
    file << tagged_text
    self.tagged_text_file = file
    save!
    file.close
  end
</pre>
]]></content:encoded>
			<wfw:commentRss>http://momolog.info/2011/12/02/saving-local-text-files-to-s3-using-paperclip/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Push local branch to specific heroku app</title>
		<link>http://momolog.info/2011/11/28/push-local-branch-to-specific-heroku-app/</link>
		<comments>http://momolog.info/2011/11/28/push-local-branch-to-specific-heroku-app/#comments</comments>
		<pubDate>Mon, 28 Nov 2011 17:33:24 +0000</pubDate>
		<dc:creator>aljoscha</dc:creator>
				<category><![CDATA[Note to self]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://momolog.info/?p=295</guid>
		<description><![CDATA[You use two heroku apps as staging and production for your project. You added both as git remotes, e.g. &#8220;production&#8221; and &#8220;staging&#8221;. Now you want to push your local branch &#8220;poster&#8221; to remote &#8220;staging&#8221;, use git push staging poster:master Note, that you can only push to &#8220;master&#8221; on herokus side. This is just git syntax, [...]]]></description>
			<content:encoded><![CDATA[<p>You use two heroku apps as staging and production for your project. You added both as git remotes, e.g. &#8220;production&#8221; and &#8220;staging&#8221;.</p>
<p>Now you want to push your local branch &#8220;poster&#8221; to remote &#8220;staging&#8221;, use<br />
<code>git push staging poster:master<br />
</code></p>
<p>Note, that you can only push to &#8220;master&#8221; on herokus side. This is just git syntax, but I keep forgetting it, so here it is for future reference.</p>
]]></content:encoded>
			<wfw:commentRss>http://momolog.info/2011/11/28/push-local-branch-to-specific-heroku-app/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ruby: map Array to Hash</title>
		<link>http://momolog.info/2010/10/07/ruby-map-array-to-hash/</link>
		<comments>http://momolog.info/2010/10/07/ruby-map-array-to-hash/#comments</comments>
		<pubDate>Thu, 07 Oct 2010 06:49:50 +0000</pubDate>
		<dc:creator>aljoscha</dc:creator>
				<category><![CDATA[Note to self]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://momolog.info/?p=277</guid>
		<description><![CDATA[Sometimes you may wish to map an Array to a Hash in Ruby, like say, you got the output of I18n.available_locales locales = [:en, :de, :fr] and want to transform that into a Hash to fill a select element, like so: [:en => 'EN', :de => 'DE', :fr => 'FR'] How do you do that [...]]]></description>
			<content:encoded><![CDATA[<p>Sometimes you may wish to map an Array to a Hash in Ruby, like say, you got the output of I18n.available_locales</p>
<p><code>locales = [:en, :de, :fr]</code></p>
<p>and want to transform that into a Hash to fill a select element, like so:</p>
<p><code>[:en => 'EN', :de => 'DE', :fr => 'FR']</code></p>
<p>How do you do that in the most concise way?<br />
First, there is always <code>inject</code>:</p>
<p><code>locales.inject({}) {|hsh, sym| hsh[sym] = sym.to_s.upcase; hsh}</code></p>
<p>But I like the following approach way better, mainly because it emphasizes my intention more clearly (and, btw. is faster too):</p>
<p><code>Hash[locales.map{|sym| [sym, sym.to_s.upcase]}]</code></p>
<p><em>Remember</em>: <code>Hash[:a,:b,:c,:d]</code> produces <code>{:a => :b, :c => :d}</code>.</p>
]]></content:encoded>
			<wfw:commentRss>http://momolog.info/2010/10/07/ruby-map-array-to-hash/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Copying Files between S3 buckets</title>
		<link>http://momolog.info/2010/07/08/copying-files-between-s3-buckets/</link>
		<comments>http://momolog.info/2010/07/08/copying-files-between-s3-buckets/#comments</comments>
		<pubDate>Thu, 08 Jul 2010 10:27:26 +0000</pubDate>
		<dc:creator>aljoscha</dc:creator>
				<category><![CDATA[AWS]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://momolog.info/?p=268</guid>
		<description><![CDATA[Building on this article here is a simple ruby script, that copies files between two buckets of the same S3 account, omitting files already present (by name). This variant adds a list of path prefixes, so you can selectively copy only certain directories of your buckets. Furthermore it copies the original buckets ACLs for each [...]]]></description>
			<content:encoded><![CDATA[<p>Building on <a href="http://www.lakedenman.com/2009/10/27/copying-files-between-s3-buckets.html">this article</a> here is a simple ruby script, that copies files between two buckets of the same S3 account, omitting files already present (by name).<br />
This variant adds a list of path prefixes, so you can selectively copy only certain directories of your buckets.<br />
Furthermore it copies the original buckets ACLs for each key.</p>
<pre>
require 'rubygems'
require 'right_aws'

aws_access_key_id     = 'YOUR AMAZON ACCESS KEY'
aws_secret_access_key = 'YOUR AMAZON SECRET ACCESS KEY'
source_bucket         = 'SOURCE BUCKET NAME'
target_bucket         = 'TARGET BUCKET NAME'
prefixes              = [PATH_PREFIX1, PATH_PREFIX2, ...]

s3 = RightAws::S3Interface.new(aws_access_key_id, aws_secret_access_key)

copied_keys = Array.new
(prefixes || ['']).each do |prefix|
  s3.incrementally_list_bucket(target_bucket, {:prefix => prefix}) do |key_set|
    copied_keys << key_set[:contents].map{|k| k[:key]}.flatten
  end
end
copied_keys.flatten!

(prefixes || ['']).each do |prefix|
  s3.incrementally_list_bucket(source_bucket, {:prefix => prefix}) do |key_set|
    key_set[:contents].each do |key|
      key = key[:key]
      if copied_keys.include?(key)
        puts "#{target_bucket} #{key} already exists. Skipping..."
      else

        puts "Copying #{source_bucket} #{key}, setting acl"

        retries=0
        begin
          s3.copy(source_bucket, key, target_bucket)
          acl = s3.get_acl(source_bucket, key)
          s3.put_acl(target_bucket, key, acl[:object])
        rescue Exception => e
          puts "cannot copy key, #{e.inspect}\nretrying #{retries} out of 10 times..."
          retries += 1
          retry if retries <= 10
        end
      end
    end
  end
end
</pre>
]]></content:encoded>
			<wfw:commentRss>http://momolog.info/2010/07/08/copying-files-between-s3-buckets/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Vor kurzem dazugelernt:</title>
		<link>http://momolog.info/2009/10/18/vor-kurzem-dazugelernt/</link>
		<comments>http://momolog.info/2009/10/18/vor-kurzem-dazugelernt/#comments</comments>
		<pubDate>Sun, 18 Oct 2009 15:46:19 +0000</pubDate>
		<dc:creator>aljoscha</dc:creator>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[MacOSX]]></category>
		<category><![CDATA[Note to self]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://momolog.info/?p=204</guid>
		<description><![CDATA[Suche nach Wort unter dem Cursor in vim: #. jssh ist eine JavaScript Shell, die den Firefox per Port 9997 fernsteuerbar macht. Download z.B. hier. y erzeugt einen YAML dump auf der Rails console, mehr dazu hier. =3D ist ein escaptes &#8220;=&#8221; in quoted_printable. sudo /usr/libexec/locate.updatedb aktualisiert unter MacOSX sofort die locate Datenbank. rake db:migrate:redo [...]]]></description>
			<content:encoded><![CDATA[<p>Suche nach Wort unter dem Cursor in vim: <code>#</code>.</p>
<p><code>jssh</code> ist eine JavaScript Shell, die den Firefox per Port 9997 fernsteuerbar macht.<br />
Download z.B. <a href="http://wiki.openqa.org/display/WTR/FireWatir+Installation">hier</a>.</p>
<p><code>y</code> erzeugt einen YAML dump auf der Rails console, mehr dazu <a href="http://blog.floehopper.org/articles/2006/12/22/rails-console-shortcuts">hier</a>.</p>
<p><code>=3D</code> ist ein escaptes &#8220;=&#8221; in <a href="http://de.wikipedia.org/wiki/Quoted-printable">quoted_printable</a>.</p>
<p><code>sudo /usr/libexec/locate.updatedb</code> aktualisiert unter MacOSX sofort die <code>locate</code> Datenbank.</p>
<p><code>rake db:migrate:redo</code> führt unter rails die letzte Migration rückwärts und sofort wieder vorwärts aus, so dass sich die Vorwärts-Action korrigieren läßt </p>
<p><code>ack -Q</code> bringt <a href="http://betterthangrep.com/">ack</a> dazu, <em>literal</em>, also ohne RegExp zu suchen.</p>
]]></content:encoded>
			<wfw:commentRss>http://momolog.info/2009/10/18/vor-kurzem-dazugelernt/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>What ist this?</title>
		<link>http://momolog.info/2009/05/15/what-ist-this/</link>
		<comments>http://momolog.info/2009/05/15/what-ist-this/#comments</comments>
		<pubDate>Fri, 15 May 2009 17:25:24 +0000</pubDate>
		<dc:creator>aljoscha</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://momolog.info/?p=37</guid>
		<description><![CDATA[Laut PHP-Doku ist das Verhalten der Pseudo-Variablen $this wie folgt: $this is a reference to the calling object (usually the object to which the method belongs, but can be another object, if the method is called statically from the context of a secondary object). Schauen wir uns folgendes Beispiel an: class A{ function __construct(){ $this->name [...]]]></description>
			<content:encoded><![CDATA[<p>Laut <a href="http://www.php.net/manual/en/language.oop5.basic.php">PHP-Doku</a> ist das Verhalten der Pseudo-Variablen <code>$this</code> wie folgt:</p>
<blockquote><p>$this is a reference to the calling object (usually the object to which the method belongs, but can be another object, if the method is called statically from the context of a secondary object).
</p></blockquote>
<p>Schauen wir uns folgendes Beispiel an:</p>
<pre>
class A{
  function __construct(){
    $this->name = 'A';
  }

  function echoThisName(){
    echo "My Name is {$this->name}.\n";
  }
}
</pre>
<p>Jetzt rufen wir die Methode mal als Instanzmethode und mal statisch auf:</p>
<pre>
$a = new A();
$a->echoThisName();
A::echoThisName();

My Name is A.
PHP Fatal error:  Using $this when not in object context in
/Users/aljoscha/test.php on line 9
Fatal error: Using $this when not in object context in
/Users/aljoscha/test.php on line 9
</pre>
<p>Das ist vernünftig. (ausser: Warum muss sich PHP eigentlich immer wiederholen? Ist eine Fehlermeldung zu subtil?)<br />
Jetzt rufen wird diese Methoden aus einer anderen Klasse <code>B</code> heraus auf:</p>
<pre>
class B{
  function __construct(){
    $this->name = 'B';
  }

  function echoAsName(){
    $a = new A();
    $a->echoThisName();
    A::echoThisName();
  }
}

$b = new B();
$b->echoAsName();
</pre>
<p>Und das gibt:</p>
<pre>
My Name is A.
My Name is B.
</pre>
<p>Wir haben die Methode <code>echoThisName</code> der Klasse <code>A</code> <em>statisch</em> aufgerufen, aber <code>$this</code> ist darin trotzdem gesetzt, und zwar als wären wir in der Instanz <code>$b</code> der Klasse <code>B</code>.<br />
<code>$b</code> hat sich die statische Methode gekapert. </p>
<p>Was sagt Ruby dazu?</p>
<pre>

class A
  def initialize
    @name = 'A';
  end

  def echoThisName
    puts "My Name is #{@name}.\n";
  end
end

$a = A.new;
$a.echoThisName;
A::echoThisName;
</pre>
<p>ergibt:</p>
<pre>

My Name is A.
test.rb:13: undefined method `echoThisName' for A:Class (NoMethodError)
</pre>
<p>Rufen wir <code>A::echoThisName</code> aus einer Instanz von <code>B</code> auf:</p>
<pre>

class B
  def initialize
    @name = 'B';
  end

  def echoAsName
    $a = A.new;
    $a.echoThisName;
    A::echoThisName;
  end
end

$b = B.new;
$b.echoAsName;
</pre>
<p>Ist das Ergebnis entsprechend:</p>
<pre>
My Name is A.
test.rb:23:in `echoAsName': undefined method `echoThisName'
for A:Class (NoMethodError) from test.rb:28
</pre>
<p>Besser.<br />
<i>Dank an Stephan für den Hinweis auf die Dokumentation des Verhaltens in PHP.</i></p>
]]></content:encoded>
			<wfw:commentRss>http://momolog.info/2009/05/15/what-ist-this/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Fixing the Prototype Enumeration Mixin</title>
		<link>http://momolog.info/2006/10/14/prototype-enumeration/</link>
		<comments>http://momolog.info/2006/10/14/prototype-enumeration/#comments</comments>
		<pubDate>Sat, 14 Oct 2006 11:42:56 +0000</pubDate>
		<dc:creator>aljoscha</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Prototype]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[The following article describes ticket #3592 in the RoR Trac and explains a proposed solution. Prototypes Enumerable mixin class does not properly respect the mixees internal format. For example the reject and findAll methods, operating on Hashes, return Arrays instead of Hashes. var a = $H({a:1, b:2, c:1, d:3}); document.writeln(a.inspect().escapeHTML()); =># var b = a.reject(function(val){ [...]]]></description>
			<content:encoded><![CDATA[<p>The following article describes <a href="http://dev.rubyonrails.org/ticket/3592">ticket #3592</a> in the RoR Trac and explains a proposed solution.</p>
<p>Prototypes Enumerable mixin class does not properly respect the mixees internal format. For example the <code>reject</code> and <code>findAll</code> methods, operating on Hashes, return Arrays instead of Hashes.</p>
<pre>
var a = $H({a:1, b:2, c:1, d:3});
document.writeln(a.inspect().escapeHTML());

=>#<Hash:{'a': 1, 'b': 2, 'c': 1, 'd': 3}>

var b = a.reject(function(val){ return (val[1]==1) });
document.writeln(b.inspect().escapeHTML());

=> [['b', 2], ['d', 3]]   // !!! should be hash

var c = b.findAll(function(val){ return (val[0]=='d') });
document.writeln(c.inspect().escapeHTML());

=> [['b', 2], ['d', 3]]   // !!! should be hash
</pre>
<p>In Ruby (from which the inspiration for the Enumerable Mixin stems), the reject method does return a hash, not an array, when operating on an hash:  </p>
<pre>
irb(main):001:0> a={:a => 1, :b => 2, :c => 1, :d => 3}  

=> {:b=>2, :c=>1, :a=>1, :d=>3}  

irb(main):002:0> b=a.reject{|k,v| v==1}

=> {:b=>2, :d=>3}
</pre>
<p>The patch requires all classes that want to mixin Enumerable to define two more methods similar to <code>_each</code>:<br />
<code>_new</code>, which returns an empty object of that class and<br />
<code>_add</code>, that adds an element. Enumerable mixin thus needs to make no more assumptions about the internal structure of its mixee class.</p>
<p>After the fix the methods return correctly:</p>
<pre>
=> #<Hash:{'b': 2, 'd': 3}>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://momolog.info/2006/10/14/prototype-enumeration/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

