<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-7665701969641921005</id><updated>2011-12-28T10:25:54.769-08:00</updated><title type='text'>Mumuki(2)</title><subtitle type='html'>The programming blog of James Whiteman</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://mumuki2.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7665701969641921005/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://mumuki2.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>J. Whiteman</name><uri>http://www.blogger.com/profile/05163279495847602913</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>15</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7665701969641921005.post-370092021587486879</id><published>2009-01-01T11:52:00.000-08:00</published><updated>2009-02-20T07:52:23.052-08:00</updated><title type='text'>Home Made Continuations with Ruby</title><content type='html'>More functional experiments from yours truly. Upon review, I've realized that this code is quite tricky.&lt;br /&gt;&lt;br /&gt;Here's the rub: Basically, evens_only_star_cc is a function that processes a gnarly data structure of nested lists (I designate these types of functions with 'star') using a collector (aka a continuation -- hence the cc in the function name). It could just as easily have been called evens_only.&lt;br /&gt;&lt;br /&gt;A continuation in this context means that instead of using the call stack the normal way, I'm opting to just nest lambdas. That means that the function needs to be called with a lambda as one of the arguments. You can think of this lambda as the innermost doll in those nifty russian matryoshka doll sets. Each time the function recurs, it wraps the previous doll (lambda) in a new one. When the function reaches its termination point, we can either hand back our 'nested doll lambda call stack' thing as is, or we can apply it to its arguments and undwind it. I'm doing the latter here.&lt;br /&gt;&lt;br /&gt;What we're doing is recurring through a crazy ass data structure of integers and collecting only the evens, while at the same time finding the sum of the odd numbers and the product of the even numbers. For sure, there are easier ways to do the same thing, but it's nice to put Ruby to the test every now and again. It's a great language.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;The Code&lt;/strong&gt;&lt;br /&gt;&lt;pre class="textmate-source"&gt;&lt;pre class="sunburst"&gt;&lt;span class="meta meta_function meta_function_method meta_function_method_with-arguments meta_function_method_with-arguments_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_def keyword_control_def_ruby"&gt;def&lt;/span&gt; &lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;evens_only_star_cc&lt;/span&gt;(&lt;span class="variable variable_parameter variable_parameter_function variable_parameter_function_ruby"&gt;l, col&lt;/span&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword keyword_control keyword_control_ruby"&gt;if&lt;/span&gt; l&lt;span class="meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby"&gt;.&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;empty?&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;  col&lt;span class="meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby"&gt;.&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;call&lt;/span&gt;&lt;/span&gt; [], &lt;span class="constant constant_numeric constant_numeric_ruby"&gt;1&lt;/span&gt;, &lt;span class="constant constant_numeric constant_numeric_ruby"&gt;0&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword keyword_control keyword_control_ruby"&gt;elsif&lt;/span&gt; l&lt;span class="meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby"&gt;.&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;car&lt;/span&gt;&lt;/span&gt;&lt;span class="meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby"&gt;.&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;is_a?&lt;/span&gt;&lt;/span&gt; &lt;span class="variable variable_other variable_other_constant variable_other_constant_ruby"&gt;Fixnum&lt;/span&gt;&lt;br /&gt;  &lt;span class="keyword keyword_control keyword_control_ruby"&gt;if&lt;/span&gt; l&lt;span class="meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby"&gt;.&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;car&lt;/span&gt;&lt;/span&gt;&lt;span class="meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby"&gt;.&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;even?&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;    evens_only_star_cc l&lt;span class="meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby"&gt;.&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;cdr&lt;/span&gt;&lt;/span&gt;, &lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby"&gt;-&lt;/span&gt;&lt;span class="keyword keyword_operator keyword_operator_comparison keyword_operator_comparison_ruby"&gt;&amp;gt;&lt;/span&gt;(op, ep, os) {&lt;span class="meta meta_syntax meta_syntax_ruby meta_syntax_ruby_start-block"&gt;&lt;/span&gt;&lt;br /&gt;      col&lt;span class="meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby"&gt;.&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;call&lt;/span&gt;&lt;/span&gt; op&lt;span class="meta meta_function-call meta_function-call_method meta_function-call_method_with-arguments meta_function-call_method_with-arguments_ruby"&gt;.&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;cons&lt;/span&gt;&lt;/span&gt;(l&lt;span class="meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby"&gt;.&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;car&lt;/span&gt;&lt;/span&gt;),&lt;br /&gt;               (ep &lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby"&gt;*&lt;/span&gt; l&lt;span class="meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby"&gt;.&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;car&lt;/span&gt;&lt;/span&gt;),&lt;br /&gt;               os&lt;br /&gt;    }&lt;br /&gt;  &lt;span class="keyword keyword_control keyword_control_ruby"&gt;else&lt;/span&gt;&lt;br /&gt;    evens_only_star_cc l&lt;span class="meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby"&gt;.&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;cdr&lt;/span&gt;&lt;/span&gt;, &lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby"&gt;-&lt;/span&gt;&lt;span class="keyword keyword_operator keyword_operator_comparison keyword_operator_comparison_ruby"&gt;&amp;gt;&lt;/span&gt;(op, ep, os) {&lt;span class="meta meta_syntax meta_syntax_ruby meta_syntax_ruby_start-block"&gt;&lt;/span&gt;&lt;br /&gt;      col&lt;span class="meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby"&gt;.&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;call&lt;/span&gt;&lt;/span&gt; op,&lt;br /&gt;               ep,&lt;br /&gt;               (os &lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby"&gt;+&lt;/span&gt; l&lt;span class="meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby"&gt;.&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;car&lt;/span&gt;&lt;/span&gt;)&lt;br /&gt;    }&lt;br /&gt;  &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword keyword_control keyword_control_ruby"&gt;else&lt;/span&gt;&lt;br /&gt;  evens_only_star_cc l&lt;span class="meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby"&gt;.&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;car&lt;/span&gt;&lt;/span&gt;, &lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby"&gt;-&lt;/span&gt;&lt;span class="keyword keyword_operator keyword_operator_comparison keyword_operator_comparison_ruby"&gt;&amp;gt;&lt;/span&gt;(nop, nep, nos) {&lt;span class="meta meta_syntax meta_syntax_ruby meta_syntax_ruby_start-block"&gt;&lt;/span&gt;&lt;br /&gt;    evens_only_star_cc l&lt;span class="meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby"&gt;.&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;cdr&lt;/span&gt;&lt;/span&gt;, &lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby"&gt;-&lt;/span&gt;&lt;span class="keyword keyword_operator keyword_operator_comparison keyword_operator_comparison_ruby"&gt;&amp;gt;&lt;/span&gt;(op, ep, os) {&lt;span class="meta meta_syntax meta_syntax_ruby meta_syntax_ruby_start-block"&gt;&lt;/span&gt;&lt;br /&gt;      col&lt;span class="meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby"&gt;.&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;call&lt;/span&gt;&lt;/span&gt; op&lt;span class="meta meta_function-call meta_function-call_method meta_function-call_method_with-arguments meta_function-call_method_with-arguments_ruby"&gt;.&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;cons&lt;/span&gt;&lt;/span&gt;(nop),&lt;br /&gt;               (ep &lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby"&gt;*&lt;/span&gt; nep),&lt;br /&gt;               (os &lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby"&gt;+&lt;/span&gt; nos)&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;strong&gt;Usage&lt;/strong&gt;&lt;br /&gt;&lt;pre class="textmate-source"&gt;&lt;pre class="sunburst"&gt;&lt;span class="meta meta_function-call meta_function-call_ruby"&gt;&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;evens_only_star_cc&lt;/span&gt;&lt;/span&gt;([&lt;span class="constant constant_numeric constant_numeric_ruby"&gt;1&lt;/span&gt;, [&lt;span class="constant constant_numeric constant_numeric_ruby"&gt;2&lt;/span&gt;, [&lt;span class="constant constant_numeric constant_numeric_ruby"&gt;3&lt;/span&gt;]], &lt;span class="constant constant_numeric constant_numeric_ruby"&gt;4&lt;/span&gt;, [[[&lt;span class="constant constant_numeric constant_numeric_ruby"&gt;5&lt;/span&gt;]]], &lt;span class="constant constant_numeric constant_numeric_ruby"&gt;6&lt;/span&gt;, [&lt;span class="constant constant_numeric constant_numeric_ruby"&gt;7&lt;/span&gt;, [&lt;span class="constant constant_numeric constant_numeric_ruby"&gt;8&lt;/span&gt;]], &lt;span class="constant constant_numeric constant_numeric_ruby"&gt;9&lt;/span&gt;, &lt;span class="constant constant_numeric constant_numeric_ruby"&gt;10&lt;/span&gt;],  &lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby"&gt;-&lt;/span&gt;&lt;span class="keyword keyword_operator keyword_operator_comparison keyword_operator_comparison_ruby"&gt;&amp;gt;&lt;/span&gt;(output, poe, soo) {&lt;span class="meta meta_syntax meta_syntax_ruby meta_syntax_ruby_start-block"&gt; &lt;/span&gt;&lt;br /&gt;{&lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;:output&lt;/span&gt; =&amp;gt; output, &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;:product_of_evens&lt;/span&gt; =&amp;gt; poe, &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;:sum_of_odds&lt;/span&gt; =&amp;gt; soo}&lt;br /&gt;})&lt;br /&gt;&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;strong&gt;Preliminaries&lt;/strong&gt;&lt;br /&gt;&lt;pre class="textmate-source"&gt;&lt;pre class="sunburst"&gt;&lt;span class="meta meta_class meta_class_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_class keyword_control_class_ruby"&gt;class&lt;/span&gt; &lt;span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby"&gt;Array&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="meta meta_function meta_function_method meta_function_method_without-arguments meta_function_method_without-arguments_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_def keyword_control_def_ruby"&gt;def&lt;/span&gt; &lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;car&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;  first&lt;br /&gt;&lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="meta meta_function meta_function_method meta_function_method_without-arguments meta_function_method_without-arguments_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_def keyword_control_def_ruby"&gt;def&lt;/span&gt; &lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;cdr&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class="variable variable_language variable_language_ruby"&gt;self&lt;/span&gt;[&lt;span class="constant constant_numeric constant_numeric_ruby"&gt;1&lt;/span&gt;..&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby"&gt;-&lt;/span&gt;&lt;span class="constant constant_numeric constant_numeric_ruby"&gt;1&lt;/span&gt;]&lt;br /&gt;&lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="meta meta_function meta_function_method meta_function_method_with-arguments meta_function_method_with-arguments_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_def keyword_control_def_ruby"&gt;def&lt;/span&gt; &lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;cons&lt;/span&gt;(&lt;span class="variable variable_parameter variable_parameter_function variable_parameter_function_ruby"&gt;s&lt;/span&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;span class="variable variable_language variable_language_ruby"&gt;self&lt;/span&gt;&lt;span class="meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby"&gt;.&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;unshift&lt;/span&gt;&lt;/span&gt; s&lt;br /&gt;&lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="meta meta_class meta_class_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_class keyword_control_class_ruby"&gt;class&lt;/span&gt; &lt;span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby"&gt;Fixnum&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="meta meta_function meta_function_method meta_function_method_without-arguments meta_function_method_without-arguments_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_def keyword_control_def_ruby"&gt;def&lt;/span&gt; &lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;even?&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;  (&lt;span class="variable variable_language variable_language_ruby"&gt;self&lt;/span&gt; &lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby"&gt;%&lt;/span&gt; &lt;span class="constant constant_numeric constant_numeric_ruby"&gt;2&lt;/span&gt;) &lt;span class="keyword keyword_operator keyword_operator_comparison keyword_operator_comparison_ruby"&gt;==&lt;/span&gt; &lt;span class="constant constant_numeric constant_numeric_ruby"&gt;0&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7665701969641921005-370092021587486879?l=mumuki2.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7665701969641921005/posts/default/370092021587486879'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7665701969641921005/posts/default/370092021587486879'/><link rel='alternate' type='text/html' href='http://mumuki2.blogspot.com/2008/08/home-made-continuations-with-ruby.html' title='Home Made Continuations with Ruby'/><author><name>J. Whiteman</name><uri>http://www.blogger.com/profile/05163279495847602913</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-7665701969641921005.post-4822691075447342628</id><published>2008-12-15T12:06:00.000-08:00</published><updated>2009-02-27T09:05:30.132-08:00</updated><title type='text'>Ruby: throw/catch vs callcc</title><content type='html'>More diversions. I earlier stated that this code should be readily understood by intermediate Rubyists. That is false, actually. The code is difficult. Not because it's using advanced Ruby, but because it's using Ruby in a very non standard way. rember_upto_last stands for "remove member upto last". 'a' stands for any atom (perhaps an integer or a symbol or a char). 'lat' stands for list-of-atoms (a simple array of atoms).&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;rember_upto_last&lt;/strong&gt;&lt;br /&gt;&lt;pre class="textmate-source"&gt;&lt;pre class="sunburst"&gt;&lt;span class="comment comment_line comment_line_number-sign comment_line_number-sign_ruby"&gt;# if the atom is not in the list we simply return the list.&lt;/span&gt;&lt;br /&gt;rember_upto_last &lt;span class="string string_quoted string_quoted_single string_quoted_single_ruby"&gt;'a'&lt;/span&gt;, &lt;span class="string string_quoted string_quoted_other string_quoted_other_literal string_quoted_other_literal_lower string_quoted_other_literal_lower_ruby"&gt;%w(x y z)&lt;/span&gt;&lt;br /&gt;=&amp;gt; &lt;span class="string string_quoted string_quoted_other string_quoted_other_literal string_quoted_other_literal_lower string_quoted_other_literal_lower_ruby"&gt;%w(x y z)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="comment comment_line comment_line_number-sign comment_line_number-sign_ruby"&gt;# if the atom is in the list, we only return everything &lt;/span&gt;&lt;br /&gt;&lt;span class="comment comment_line comment_line_number-sign comment_line_number-sign_ruby"&gt;# after the atom.&lt;/span&gt;&lt;br /&gt;rember_upto_last &lt;span class="string string_quoted string_quoted_single string_quoted_single_ruby"&gt;'a'&lt;/span&gt;, &lt;span class="string string_quoted string_quoted_other string_quoted_other_literal string_quoted_other_literal_lower string_quoted_other_literal_lower_ruby"&gt;%w(x y z a b c)&lt;/span&gt;&lt;br /&gt;=&amp;gt; &lt;span class="string string_quoted string_quoted_other string_quoted_other_literal string_quoted_other_literal_lower string_quoted_other_literal_lower_ruby"&gt;%w(b c)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="comment comment_line comment_line_number-sign comment_line_number-sign_ruby"&gt;# if the atom exists in multiple places, then we only &lt;/span&gt;&lt;br /&gt;&lt;span class="comment comment_line comment_line_number-sign comment_line_number-sign_ruby"&gt;# return everything after the last instance of the atom.&lt;/span&gt;&lt;br /&gt;rember_upto_last &lt;span class="string string_quoted string_quoted_single string_quoted_single_ruby"&gt;'a'&lt;/span&gt;, &lt;span class="string string_quoted string_quoted_other string_quoted_other_literal string_quoted_other_literal_lower string_quoted_other_literal_lower_ruby"&gt;%w(x y z a b c a p q)&lt;/span&gt;&lt;br /&gt;=&amp;gt; &lt;span class="string string_quoted string_quoted_other string_quoted_other_literal string_quoted_other_literal_lower string_quoted_other_literal_lower_ruby"&gt;%w(p q)&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;strong&gt;version using throw/catch&lt;/strong&gt;&lt;br /&gt;&lt;pre class="textmate-source"&gt;&lt;pre class="sunburst"&gt;&lt;span class="comment comment_line comment_line_number-sign comment_line_number-sign_ruby"&gt;# with try/catch&lt;/span&gt;&lt;br /&gt;&lt;span class="meta meta_function meta_function_method meta_function_method_with-arguments meta_function_method_with-arguments_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_def keyword_control_def_ruby"&gt;def&lt;/span&gt; &lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;rember_upto_last&lt;/span&gt;(&lt;span class="variable variable_parameter variable_parameter_function variable_parameter_function_ruby"&gt;a, lat&lt;/span&gt;)&lt;/span&gt;&lt;br /&gt;result &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby"&gt;=&lt;/span&gt; &lt;span class="keyword keyword_other keyword_other_special-method keyword_other_special-method_ruby"&gt;catch&lt;/span&gt;(&lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;:jump!&lt;/span&gt;) &lt;span class="keyword keyword_control keyword_control_ruby keyword_control_ruby_start-block"&gt;do&lt;/span&gt;&lt;br /&gt;  r &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby"&gt;=&lt;/span&gt; lambda &lt;span class="keyword keyword_control keyword_control_ruby keyword_control_ruby_start-block"&gt;do &lt;/span&gt;|&lt;span class="variable variable_other variable_other_block variable_other_block_ruby"&gt;l&lt;/span&gt;|&lt;br /&gt;    &lt;span class="keyword keyword_control keyword_control_ruby"&gt;if&lt;/span&gt; l&lt;span class="meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby"&gt;.&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;empty?&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;      []&lt;br /&gt;    &lt;span class="keyword keyword_control keyword_control_ruby"&gt;elsif&lt;/span&gt; l&lt;span class="meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby"&gt;.&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;first&lt;/span&gt;&lt;/span&gt; &lt;span class="keyword keyword_operator keyword_operator_comparison keyword_operator_comparison_ruby"&gt;==&lt;/span&gt; a&lt;br /&gt;      &lt;span class="keyword keyword_other keyword_other_special-method keyword_other_special-method_ruby"&gt;throw&lt;/span&gt; &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;:jump!&lt;/span&gt;, r&lt;span class="meta meta_function-call meta_function-call_method meta_function-call_method_with-arguments meta_function-call_method_with-arguments_ruby"&gt;.&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;call&lt;/span&gt;&lt;/span&gt;(l[&lt;span class="constant constant_numeric constant_numeric_ruby"&gt;1&lt;/span&gt;..&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby"&gt;-&lt;/span&gt;&lt;span class="constant constant_numeric constant_numeric_ruby"&gt;1&lt;/span&gt;])&lt;br /&gt;    &lt;span class="keyword keyword_control keyword_control_ruby"&gt;else&lt;/span&gt;&lt;br /&gt;      cons l&lt;span class="meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby"&gt;.&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;first&lt;/span&gt;&lt;/span&gt;, r&lt;span class="meta meta_function-call meta_function-call_method meta_function-call_method_with-arguments meta_function-call_method_with-arguments_ruby"&gt;.&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;call&lt;/span&gt;&lt;/span&gt;(l[&lt;span class="constant constant_numeric constant_numeric_ruby"&gt;1&lt;/span&gt;..&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby"&gt;-&lt;/span&gt;&lt;span class="constant constant_numeric constant_numeric_ruby"&gt;1&lt;/span&gt;])&lt;br /&gt;    &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;br /&gt;  &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  r&lt;span class="meta meta_function-call meta_function-call_method meta_function-call_method_with-arguments meta_function-call_method_with-arguments_ruby"&gt;.&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;call&lt;/span&gt;&lt;/span&gt;(lat)&lt;br /&gt;&lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;strong&gt;version using callcc&lt;/strong&gt;&lt;br /&gt;&lt;pre class="textmate-source"&gt;&lt;pre class="sunburst"&gt;&lt;span class="comment comment_line comment_line_number-sign comment_line_number-sign_ruby"&gt;# with callcc&lt;/span&gt;&lt;br /&gt;&lt;span class="meta meta_function meta_function_method meta_function_method_with-arguments meta_function_method_with-arguments_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_def keyword_control_def_ruby"&gt;def&lt;/span&gt; &lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;rember_upto_last&lt;/span&gt;(&lt;span class="variable variable_parameter variable_parameter_function variable_parameter_function_ruby"&gt;a, lat&lt;/span&gt;)&lt;/span&gt;&lt;br /&gt;result &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby"&gt;=&lt;/span&gt; callcc &lt;span class="keyword keyword_control keyword_control_ruby keyword_control_ruby_start-block"&gt;do &lt;/span&gt;|&lt;span class="variable variable_other variable_other_block variable_other_block_ruby"&gt;c&lt;/span&gt;|&lt;br /&gt;  yComb &lt;span class="keyword keyword_control keyword_control_ruby keyword_control_ruby_start-block"&gt;do &lt;/span&gt;|&lt;span class="variable variable_other variable_other_block variable_other_block_ruby"&gt;f&lt;/span&gt;|&lt;br /&gt;    lambda &lt;span class="keyword keyword_control keyword_control_ruby keyword_control_ruby_start-block"&gt;do &lt;/span&gt;|&lt;span class="variable variable_other variable_other_block variable_other_block_ruby"&gt;l&lt;/span&gt;|&lt;br /&gt;      &lt;span class="keyword keyword_control keyword_control_ruby"&gt;if&lt;/span&gt; l&lt;span class="meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby"&gt;.&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;empty?&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;        []&lt;br /&gt;      &lt;span class="keyword keyword_control keyword_control_ruby"&gt;elsif&lt;/span&gt; l&lt;span class="meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby"&gt;.&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;first&lt;/span&gt;&lt;/span&gt; &lt;span class="keyword keyword_operator keyword_operator_comparison keyword_operator_comparison_ruby"&gt;==&lt;/span&gt; a&lt;br /&gt;        c&lt;span class="meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby"&gt;.&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;call&lt;/span&gt;&lt;/span&gt; f&lt;span class="meta meta_function-call meta_function-call_method meta_function-call_method_with-arguments meta_function-call_method_with-arguments_ruby"&gt;.&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;call&lt;/span&gt;&lt;/span&gt;(l[&lt;span class="constant constant_numeric constant_numeric_ruby"&gt;1&lt;/span&gt;..&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby"&gt;-&lt;/span&gt;&lt;span class="constant constant_numeric constant_numeric_ruby"&gt;1&lt;/span&gt;])&lt;br /&gt;      &lt;span class="keyword keyword_control keyword_control_ruby"&gt;else&lt;/span&gt;&lt;br /&gt;        cons l&lt;span class="meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby"&gt;.&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;first&lt;/span&gt;&lt;/span&gt;, f&lt;span class="meta meta_function-call meta_function-call_method meta_function-call_method_with-arguments meta_function-call_method_with-arguments_ruby"&gt;.&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;call&lt;/span&gt;&lt;/span&gt;(l[&lt;span class="constant constant_numeric constant_numeric_ruby"&gt;1&lt;/span&gt;..&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby"&gt;-&lt;/span&gt;&lt;span class="constant constant_numeric constant_numeric_ruby"&gt;1&lt;/span&gt;])&lt;br /&gt;      &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;br /&gt;    &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;br /&gt;  &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;span class="meta meta_function-call meta_function-call_method meta_function-call_method_with-arguments meta_function-call_method_with-arguments_ruby"&gt;.&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;call&lt;/span&gt;&lt;/span&gt;(lat)&lt;br /&gt;&lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;strong&gt;helpers&lt;/strong&gt;&lt;br /&gt;&lt;pre class="textmate-source"&gt;&lt;pre class="sunburst"&gt;&lt;span class="meta meta_function meta_function_method meta_function_method_with-arguments meta_function_method_with-arguments_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_def keyword_control_def_ruby"&gt;def&lt;/span&gt; &lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;cons&lt;/span&gt;(&lt;span class="variable variable_parameter variable_parameter_function variable_parameter_function_ruby"&gt;a, b&lt;/span&gt;)&lt;/span&gt;&lt;br /&gt;b&lt;span class="meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby"&gt;.&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;unshift&lt;/span&gt;&lt;/span&gt; a&lt;br /&gt;&lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="meta meta_function meta_function_method meta_function_method_without-arguments meta_function_method_without-arguments_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_def keyword_control_def_ruby"&gt;def&lt;/span&gt; &lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;yComb&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;lambda {&lt;span class="meta meta_syntax meta_syntax_ruby meta_syntax_ruby_start-block"&gt; &lt;/span&gt;|&lt;span class="variable variable_other variable_other_block variable_other_block_ruby"&gt;f&lt;/span&gt;|&lt;br /&gt;  f[f]&lt;br /&gt;}&lt;span class="meta meta_function-call meta_function-call_method meta_function-call_method_with-arguments meta_function-call_method_with-arguments_ruby"&gt;.&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;call&lt;/span&gt;&lt;/span&gt;(&lt;br /&gt;  lambda {&lt;span class="meta meta_syntax meta_syntax_ruby meta_syntax_ruby_start-block"&gt; &lt;/span&gt;|&lt;span class="variable variable_other variable_other_block variable_other_block_ruby"&gt;f&lt;/span&gt;| &lt;span class="keyword keyword_control keyword_control_pseudo-method keyword_control_pseudo-method_ruby"&gt;yield&lt;/span&gt; lambda {&lt;span class="meta meta_syntax meta_syntax_ruby meta_syntax_ruby_start-block"&gt; &lt;/span&gt;|&lt;span class="variable variable_other variable_other_block variable_other_block_ruby"&gt;x&lt;/span&gt;| f[f][x] } }&lt;br /&gt;)&lt;br /&gt;&lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7665701969641921005-4822691075447342628?l=mumuki2.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7665701969641921005/posts/default/4822691075447342628'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7665701969641921005/posts/default/4822691075447342628'/><link rel='alternate' type='text/html' href='http://mumuki2.blogspot.com/2008/08/ruby-trycatch-vs-callcc.html' title='Ruby: throw/catch vs callcc'/><author><name>J. Whiteman</name><uri>http://www.blogger.com/profile/05163279495847602913</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-7665701969641921005.post-6727074246146459722</id><published>2008-09-26T18:29:00.000-07:00</published><updated>2008-11-14T08:47:06.496-08:00</updated><title type='text'>Beware Herd Thinking in Design Patterns</title><content type='html'>I was reading &lt;a href="http://tinyurl.com/yo9mwr"&gt;Object Design&lt;/a&gt; a few months back and came upon an example illustrating &lt;a href="http://en.wikipedia.org/wiki/Double_dispatch"&gt;Double Dispatch&lt;/a&gt;. The example was showing a simple way to model &lt;a href="http://en.wikipedia.org/wiki/Rock-paper-scissors"&gt;Rock, Paper, Scissors&lt;/a&gt;. Here is the code translated to Ruby from Java:&lt;br /&gt;&lt;br /&gt;&lt;pre class="textmate-source"&gt;&lt;pre class="sunburst"&gt;&lt;span class="meta meta_class meta_class_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_class keyword_control_class_ruby"&gt;class&lt;/span&gt; &lt;span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby"&gt;Rock&lt;/span&gt;&lt;/span&gt;&lt;br /&gt; &lt;span class="meta meta_function meta_function_method meta_function_method_with-arguments meta_function_method_with-arguments_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_def keyword_control_def_ruby"&gt;def&lt;/span&gt; &lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;beats?&lt;/span&gt;(&lt;span class="variable variable_parameter variable_parameter_function variable_parameter_function_ruby"&gt;obj&lt;/span&gt;)&lt;/span&gt;&lt;br /&gt;   obj&lt;span class="meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby"&gt;.&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;loses_to_rock?&lt;/span&gt;&lt;/span&gt;&lt;br /&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; &lt;span class="meta meta_function meta_function_method meta_function_method_without-arguments meta_function_method_without-arguments_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_def keyword_control_def_ruby"&gt;def&lt;/span&gt; &lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;loses_to_rock?&lt;/span&gt;&lt;/span&gt;; &lt;span class="constant constant_language constant_language_ruby"&gt;false&lt;/span&gt;; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;br /&gt; &lt;span class="meta meta_function meta_function_method meta_function_method_without-arguments meta_function_method_without-arguments_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_def keyword_control_def_ruby"&gt;def&lt;/span&gt; &lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;loses_to_paper?&lt;/span&gt;&lt;/span&gt;; &lt;span class="constant constant_language constant_language_ruby"&gt;true&lt;/span&gt;; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;br /&gt; &lt;span class="meta meta_function meta_function_method meta_function_method_without-arguments meta_function_method_without-arguments_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_def keyword_control_def_ruby"&gt;def&lt;/span&gt; &lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;loses_to_scissors?&lt;/span&gt;&lt;/span&gt;; &lt;span class="constant constant_language constant_language_ruby"&gt;false&lt;/span&gt;; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="meta meta_class meta_class_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_class keyword_control_class_ruby"&gt;class&lt;/span&gt; &lt;span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby"&gt;Paper&lt;/span&gt;&lt;/span&gt;&lt;br /&gt; &lt;span class="meta meta_function meta_function_method meta_function_method_with-arguments meta_function_method_with-arguments_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_def keyword_control_def_ruby"&gt;def&lt;/span&gt; &lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;beats?&lt;/span&gt;(&lt;span class="variable variable_parameter variable_parameter_function variable_parameter_function_ruby"&gt;obj&lt;/span&gt;)&lt;/span&gt;&lt;br /&gt;   obj&lt;span class="meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby"&gt;.&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;loses_to_paper?&lt;/span&gt;&lt;/span&gt;&lt;br /&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; &lt;span class="meta meta_function meta_function_method meta_function_method_without-arguments meta_function_method_without-arguments_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_def keyword_control_def_ruby"&gt;def&lt;/span&gt; &lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;loses_to_rock?&lt;/span&gt;&lt;/span&gt;; &lt;span class="constant constant_language constant_language_ruby"&gt;false&lt;/span&gt;; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;br /&gt; &lt;span class="meta meta_function meta_function_method meta_function_method_without-arguments meta_function_method_without-arguments_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_def keyword_control_def_ruby"&gt;def&lt;/span&gt; &lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;loses_to_paper?&lt;/span&gt;&lt;/span&gt;; &lt;span class="constant constant_language constant_language_ruby"&gt;false&lt;/span&gt;; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;br /&gt; &lt;span class="meta meta_function meta_function_method meta_function_method_without-arguments meta_function_method_without-arguments_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_def keyword_control_def_ruby"&gt;def&lt;/span&gt; &lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;loses_to_scissors?&lt;/span&gt;&lt;/span&gt;; &lt;span class="constant constant_language constant_language_ruby"&gt;true&lt;/span&gt;; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="meta meta_class meta_class_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_class keyword_control_class_ruby"&gt;class&lt;/span&gt; &lt;span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby"&gt;Scissors&lt;/span&gt;&lt;/span&gt;&lt;br /&gt; &lt;span class="meta meta_function meta_function_method meta_function_method_with-arguments meta_function_method_with-arguments_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_def keyword_control_def_ruby"&gt;def&lt;/span&gt; &lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;beats?&lt;/span&gt;(&lt;span class="variable variable_parameter variable_parameter_function variable_parameter_function_ruby"&gt;obj&lt;/span&gt;)&lt;/span&gt;&lt;br /&gt;   obj&lt;span class="meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby"&gt;.&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;loses_to_scissors?&lt;/span&gt;&lt;/span&gt;&lt;br /&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; &lt;span class="meta meta_function meta_function_method meta_function_method_without-arguments meta_function_method_without-arguments_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_def keyword_control_def_ruby"&gt;def&lt;/span&gt; &lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;loses_to_rock?&lt;/span&gt;&lt;/span&gt;; &lt;span class="constant constant_language constant_language_ruby"&gt;true&lt;/span&gt;; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;br /&gt; &lt;span class="meta meta_function meta_function_method meta_function_method_without-arguments meta_function_method_without-arguments_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_def keyword_control_def_ruby"&gt;def&lt;/span&gt; &lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;loses_to_paper?&lt;/span&gt;&lt;/span&gt;; &lt;span class="constant constant_language constant_language_ruby"&gt;false&lt;/span&gt;; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;br /&gt; &lt;span class="meta meta_function meta_function_method meta_function_method_without-arguments meta_function_method_without-arguments_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_def keyword_control_def_ruby"&gt;def&lt;/span&gt; &lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;loses_to_scissors?&lt;/span&gt;&lt;/span&gt;; &lt;span class="constant constant_language constant_language_ruby"&gt;false&lt;/span&gt;; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/pre&gt;Programmers with some experience with metaprogramming may instinctively feel uneasy with this code. I mean, it &lt;em&gt;looks&lt;/em&gt; like a pattern. And we know that if we wished to extend the game, then we're obligated to add another boxy class with all of those silly `loses_to...` methods.&lt;br /&gt;&lt;br /&gt;Here's a &lt;strong&gt;much&lt;/strong&gt; better way:&lt;br /&gt;&lt;br /&gt;&lt;pre class="textmate-source"&gt;&lt;pre class="sunburst"&gt;&lt;span class="comment comment_line comment_line_number-sign comment_line_number-sign_ruby"&gt;# this makes me happy :)&lt;/span&gt;&lt;br /&gt;&lt;span class="meta meta_class meta_class_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_class keyword_control_class_ruby"&gt;class&lt;/span&gt; &lt;span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby"&gt;Piece&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="meta meta_class meta_class_ruby"&gt;  &lt;span class="keyword keyword_control keyword_control_class keyword_control_class_ruby"&gt;class&lt;/span&gt; &lt;span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby"&gt;&lt;span class="variable variable_other variable_other_object variable_other_object_ruby"&gt;&amp;lt;&amp;lt; self&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;   &lt;span class="meta meta_function meta_function_method meta_function_method_with-arguments meta_function_method_with-arguments_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_def keyword_control_def_ruby"&gt;def&lt;/span&gt; &lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;beats&lt;/span&gt;(&lt;span class="variable variable_parameter variable_parameter_function variable_parameter_function_ruby"&gt;&lt;span class="keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby"&gt;*&lt;/span&gt;args&lt;/span&gt;)&lt;/span&gt;&lt;br /&gt;     class_eval &lt;span class="keyword keyword_control keyword_control_ruby keyword_control_ruby_start-block"&gt;do&lt;/span&gt;&lt;br /&gt;       &lt;span class="meta meta_function-call meta_function-call_ruby"&gt;&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;define_method&lt;/span&gt;&lt;/span&gt;(&lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;:beats&lt;/span&gt;) &lt;span class="keyword keyword_control keyword_control_ruby keyword_control_ruby_start-block"&gt;do&lt;/span&gt;&lt;br /&gt;         args&lt;span class="meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby"&gt;.&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;map&lt;/span&gt;&lt;/span&gt; {&lt;span class="meta meta_syntax meta_syntax_ruby meta_syntax_ruby_start-block"&gt; &lt;/span&gt;|&lt;span class="variable variable_other variable_other_block variable_other_block_ruby"&gt;s&lt;/span&gt;| &lt;span class="support support_class support_class_ruby"&gt;Object&lt;/span&gt;&lt;span class="meta meta_function-call meta_function-call_method meta_function-call_method_with-arguments meta_function-call_method_with-arguments_ruby"&gt;.&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;const_get&lt;/span&gt;&lt;/span&gt;(s&lt;span class="meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby"&gt;.&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;to_s&lt;/span&gt;&lt;/span&gt;&lt;span class="meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby"&gt;.&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;capitalize&lt;/span&gt;&lt;/span&gt;) }&lt;br /&gt;       &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;br /&gt;     &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;br /&gt;   &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;br /&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; &lt;span class="meta meta_function meta_function_method meta_function_method_with-arguments meta_function_method_with-arguments_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_def keyword_control_def_ruby"&gt;def&lt;/span&gt; &lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;beats?&lt;/span&gt;(&lt;span class="variable variable_parameter variable_parameter_function variable_parameter_function_ruby"&gt;opp&lt;/span&gt;)&lt;/span&gt;&lt;br /&gt;   beats&lt;span class="meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby"&gt;.&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;include?&lt;/span&gt;&lt;/span&gt; opp&lt;span class="meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby"&gt;.&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;class&lt;/span&gt;&lt;/span&gt;&lt;br /&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="meta meta_class meta_class_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_class keyword_control_class_ruby"&gt;class&lt;/span&gt; &lt;span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby"&gt;Rock&lt;span class="entity entity_other entity_other_inherited-class entity_other_inherited-class_ruby"&gt; &amp;lt; Piece&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt; beats &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;:scissors&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="meta meta_class meta_class_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_class keyword_control_class_ruby"&gt;class&lt;/span&gt; &lt;span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby"&gt;Scissors&lt;span class="entity entity_other entity_other_inherited-class entity_other_inherited-class_ruby"&gt; &amp;lt; Piece&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt; beats &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;:paper&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="meta meta_class meta_class_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_class keyword_control_class_ruby"&gt;class&lt;/span&gt; &lt;span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby"&gt;Paper&lt;span class="entity entity_other entity_other_inherited-class entity_other_inherited-class_ruby"&gt; &amp;lt; Piece&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt; beats &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;:rock&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;In this way, it is trivial to extend the game:&lt;br /&gt;&lt;br /&gt;&lt;pre class="textmate-source"&gt;&lt;pre class="sunburst"&gt;&lt;span class="meta meta_class meta_class_ruby"&gt;&lt;span class="keyword keyword_control keyword_control_class keyword_control_class_ruby"&gt;class&lt;/span&gt; &lt;span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby"&gt;JamesWhiteman&lt;span class="entity entity_other entity_other_inherited-class entity_other_inherited-class_ruby"&gt; &amp;lt; Piece&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt; beats &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;:paper&lt;/span&gt;, &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;:scissors&lt;/span&gt;, &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;:rock&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="comment comment_line comment_line_number-sign comment_line_number-sign_ruby"&gt;# ok, let me instantiate myself...&lt;/span&gt;&lt;br /&gt;james_whiteman &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby"&gt;=&lt;/span&gt; &lt;span class="support support_class support_class_ruby"&gt;JamesWhiteman&lt;/span&gt;&lt;span class="meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby"&gt;.&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;new&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="comment comment_line comment_line_number-sign comment_line_number-sign_ruby"&gt;# and time to start kicking some ass :)&lt;/span&gt;&lt;br /&gt;james_whiteman&lt;span class="meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby"&gt;.&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;beats?&lt;/span&gt;&lt;/span&gt; &lt;span class="support support_class support_class_ruby"&gt;Rock&lt;/span&gt;&lt;span class="meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby"&gt;.&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;new&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;=&amp;gt; &lt;span class="variable variable_other variable_other_constant variable_other_constant_ruby"&gt;TRUE&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;james_whiteman&lt;span class="meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby"&gt;.&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;beats?&lt;/span&gt;&lt;/span&gt; &lt;span class="support support_class support_class_ruby"&gt;Paper&lt;/span&gt;&lt;span class="meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby"&gt;.&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;new&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;=&amp;gt; &lt;span class="variable variable_other variable_other_constant variable_other_constant_ruby"&gt;TRUE&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;james_whiteman&lt;span class="meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby"&gt;.&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;beats?&lt;/span&gt;&lt;/span&gt; &lt;span class="support support_class support_class_ruby"&gt;Scissors&lt;/span&gt;&lt;span class="meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby"&gt;.&lt;span class="entity entity_name entity_name_function entity_name_function_ruby"&gt;new&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;=&amp;gt; &lt;span class="variable variable_other variable_other_constant variable_other_constant_ruby"&gt;TRUE&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7665701969641921005-6727074246146459722?l=mumuki2.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7665701969641921005/posts/default/6727074246146459722'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7665701969641921005/posts/default/6727074246146459722'/><link rel='alternate' type='text/html' href='http://mumuki2.blogspot.com/2008/09/beware-herd-thinking-in-design-patterns.html' title='Beware Herd Thinking in Design Patterns'/><author><name>J. Whiteman</name><uri>http://www.blogger.com/profile/05163279495847602913</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-7665701969641921005.post-8874763037165167815</id><published>2008-09-26T18:11:00.000-07:00</published><updated>2008-09-26T18:18:58.620-07:00</updated><title type='text'>Meta Programming 101: A Compression Macro</title><content type='html'>Here is another small (and hopefully instructive)  example I came up with to help you grok meta programming. Any subclass of Bar will have a `compress` class method (aka ruby-style macro).&lt;br /&gt;&lt;br /&gt;&lt;pre class="textmate-source"&gt;&lt;pre class="sunburst"&gt;&lt;span class='meta meta_require meta_require_ruby'&gt;&lt;span class='keyword keyword_other keyword_other_special-method keyword_other_special-method_ruby'&gt;require&lt;/span&gt; &lt;span class='string string_quoted string_quoted_single string_quoted_single_ruby'&gt;'zlib'&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class='meta meta_class meta_class_ruby'&gt;&lt;span class='keyword keyword_control keyword_control_class keyword_control_class_ruby'&gt;class&lt;/span&gt; &lt;span class='entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby'&gt;Bar&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class='meta meta_class meta_class_ruby'&gt;  &lt;span class='keyword keyword_control keyword_control_class keyword_control_class_ruby'&gt;class&lt;/span&gt; &lt;span class='entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby'&gt;&lt;span class='variable variable_other variable_other_object variable_other_object_ruby'&gt;&amp;lt;&amp;lt; self&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class='meta meta_function meta_function_method meta_function_method_with-arguments meta_function_method_with-arguments_ruby'&gt;&lt;span class='keyword keyword_control keyword_control_def keyword_control_def_ruby'&gt;def&lt;/span&gt; &lt;span class='entity entity_name entity_name_function entity_name_function_ruby'&gt;compress&lt;/span&gt;(&lt;span class='variable variable_parameter variable_parameter_function variable_parameter_function_ruby'&gt;&lt;span class='keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby'&gt;*&lt;/span&gt;args&lt;/span&gt;)&lt;/span&gt;&lt;br /&gt;      args&lt;span class='meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby'&gt;.&lt;span class='entity entity_name entity_name_function entity_name_function_ruby'&gt;each&lt;/span&gt;&lt;/span&gt; &lt;span class='keyword keyword_control keyword_control_ruby keyword_control_ruby_start-block'&gt;do &lt;/span&gt;|&lt;span class='variable variable_other variable_other_block variable_other_block_ruby'&gt;id&lt;/span&gt;|&lt;br /&gt;        module_eval &lt;span class='keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_augmented keyword_operator_assignment_augmented_ruby'&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class='keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby'&gt;-&lt;/span&gt;&lt;span class='string string_quoted string_quoted_double string_quoted_double_ruby'&gt;&amp;quot;end;&amp;quot;&lt;/span&gt;&lt;br /&gt;          &lt;span class='keyword keyword_control keyword_control_pseudo-method keyword_control_pseudo-method_ruby'&gt;alias_method&lt;/span&gt; &lt;span class='constant constant_other constant_other_symbol constant_other_symbol_ruby'&gt;:__&lt;/span&gt;&lt;span class='comment comment_line comment_line_number-sign comment_line_number-sign_ruby'&gt;#{id.to_i}__, :#{id.to_s}&lt;/span&gt;&lt;br /&gt;          &lt;span class='keyword keyword_other keyword_other_special-method keyword_other_special-method_ruby'&gt;private&lt;/span&gt; &lt;span class='constant constant_other constant_other_symbol constant_other_symbol_ruby'&gt;:__&lt;/span&gt;&lt;span class='comment comment_line comment_line_number-sign comment_line_number-sign_ruby'&gt;#{id.to_i}__&lt;/span&gt;&lt;br /&gt;          &lt;span class='meta meta_function meta_function_method meta_function_method_without-arguments meta_function_method_without-arguments_ruby'&gt;&lt;span class='keyword keyword_control keyword_control_def keyword_control_def_ruby'&gt;def&lt;/span&gt;&lt;/span&gt; &lt;span class='comment comment_line comment_line_number-sign comment_line_number-sign_ruby'&gt;#{id.to_s}(*args, &amp;amp;block)&lt;/span&gt;&lt;br /&gt;            &lt;span class='support support_class support_class_ruby'&gt;Zlib&lt;/span&gt;&lt;span class='meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby'&gt;::&lt;span class='entity entity_name entity_name_function entity_name_function_ruby'&gt;Deflate&lt;/span&gt;&lt;/span&gt;&lt;span class='meta meta_function-call meta_function-call_method meta_function-call_method_with-arguments meta_function-call_method_with-arguments_ruby'&gt;.&lt;span class='entity entity_name entity_name_function entity_name_function_ruby'&gt;deflate&lt;/span&gt;&lt;/span&gt;(__&lt;span class='comment comment_line comment_line_number-sign comment_line_number-sign_ruby'&gt;#{id.to_i}__(*args, &amp;amp;block), Zlib::BEST_COMPRESSION )&lt;/span&gt;&lt;br /&gt;          &lt;span class='keyword keyword_control keyword_control_ruby'&gt;end&lt;/span&gt;&lt;br /&gt;        &lt;span class='keyword keyword_control keyword_control_ruby'&gt;end&lt;/span&gt;;&lt;br /&gt;      &lt;span class='keyword keyword_control keyword_control_ruby'&gt;end&lt;/span&gt;&lt;br /&gt;      &lt;span class='constant constant_language constant_language_ruby'&gt;nil&lt;/span&gt; &lt;span class='comment comment_line comment_line_number-sign comment_line_number-sign_ruby'&gt;# let's not return anything&lt;/span&gt;&lt;br /&gt;    &lt;span class='keyword keyword_control keyword_control_ruby'&gt;end&lt;/span&gt;&lt;br /&gt;  &lt;span class='keyword keyword_control keyword_control_ruby'&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span class='keyword keyword_control keyword_control_ruby'&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class='meta meta_class meta_class_ruby'&gt;&lt;span class='keyword keyword_control keyword_control_class keyword_control_class_ruby'&gt;class&lt;/span&gt; &lt;span class='entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby'&gt;Foo&lt;span class='entity entity_other entity_other_inherited-class entity_other_inherited-class_ruby'&gt; &amp;lt; Bar&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;  &lt;br /&gt;  &lt;span class='meta meta_function meta_function_method meta_function_method_without-arguments meta_function_method_without-arguments_ruby'&gt;&lt;span class='keyword keyword_control keyword_control_def keyword_control_def_ruby'&gt;def&lt;/span&gt; &lt;span class='entity entity_name entity_name_function entity_name_function_ruby'&gt;output&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;    (&lt;span class='string string_quoted string_quoted_single string_quoted_single_ruby'&gt;'a'&lt;/span&gt;..&lt;span class='string string_quoted string_quoted_single string_quoted_single_ruby'&gt;'z'&lt;/span&gt;)&lt;span class='meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby'&gt;.&lt;span class='entity entity_name entity_name_function entity_name_function_ruby'&gt;to_a&lt;/span&gt;&lt;/span&gt;&lt;span class='meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby'&gt;.&lt;span class='entity entity_name entity_name_function entity_name_function_ruby'&gt;join&lt;/span&gt;&lt;/span&gt; &lt;span class='keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby'&gt;*&lt;/span&gt; &lt;span class='constant constant_numeric constant_numeric_ruby'&gt;500&lt;/span&gt;&lt;br /&gt;  &lt;span class='keyword keyword_control keyword_control_ruby'&gt;end&lt;/span&gt;&lt;br /&gt;  compress &lt;span class='constant constant_other constant_other_symbol constant_other_symbol_ruby'&gt;:output&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;&lt;span class='keyword keyword_control keyword_control_ruby'&gt;end&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7665701969641921005-8874763037165167815?l=mumuki2.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7665701969641921005/posts/default/8874763037165167815'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7665701969641921005/posts/default/8874763037165167815'/><link rel='alternate' type='text/html' href='http://mumuki2.blogspot.com/2008/09/meta-programming-example-1.html' title='Meta Programming 101: A Compression Macro'/><author><name>J. Whiteman</name><uri>http://www.blogger.com/profile/05163279495847602913</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-7665701969641921005.post-8456705420867729887</id><published>2008-09-20T19:55:00.001-07:00</published><updated>2008-09-20T20:10:33.714-07:00</updated><title type='text'>Quicksort in PHP</title><content type='html'>Tonight I decided to write a Quicksort in PHP. Thank you Zend for create_function because Ruby has made me hopelessly closure dependent. Once I figured out that array_filter could take a lambda instead of a string I knew that &lt;em&gt;it was on&lt;/em&gt;.&lt;br /&gt;&lt;br /&gt;&lt;pre class="textmate-source"&gt;&lt;pre class="sunburst"&gt;&lt;span class='source source_php source_php_embedded source_php_embedded_block source_php_embedded_block_html'&gt;&amp;lt;?php&lt;br /&gt;&lt;span class='meta meta_function meta_function_php'&gt;&lt;span class='storage storage_type storage_type_function storage_type_function_php'&gt;function&lt;/span&gt; &lt;span class='entity entity_name entity_name_function entity_name_function_php'&gt;qsort&lt;/span&gt;(&lt;span class='meta meta_function meta_function_arguments meta_function_arguments_php'&gt;&lt;span class='meta meta_function meta_function_argument meta_function_argument_no-default meta_function_argument_no-default_php'&gt;&lt;span class='variable variable_other variable_other_php'&gt;$l&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; {&lt;br /&gt;  &lt;span class='keyword keyword_control keyword_control_php'&gt;if&lt;/span&gt; (&lt;span class='support support_function support_function_type support_function_type_php'&gt;is_array&lt;/span&gt;(&lt;span class='variable variable_other variable_other_php'&gt;$l&lt;/span&gt;) &lt;span class='keyword keyword_operator keyword_operator_logical keyword_operator_logical_php'&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class='support support_function support_function_construct support_function_construct_php'&gt;empty&lt;/span&gt;(&lt;span class='variable variable_other variable_other_php'&gt;$l&lt;/span&gt;)) { &lt;span class='keyword keyword_control keyword_control_php'&gt;return&lt;/span&gt; &lt;span class='meta meta_array meta_array_php'&gt;&lt;span class='support support_function support_function_construct support_function_construct_php'&gt;array&lt;/span&gt;()&lt;/span&gt;; }&lt;br /&gt;  &lt;span class='support support_function support_function_construct support_function_construct_php'&gt;list&lt;/span&gt;(&lt;span class='variable variable_other variable_other_php'&gt;$car&lt;/span&gt;, &lt;span class='variable variable_other variable_other_php'&gt;$cdr&lt;/span&gt;) &lt;span class='keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_php'&gt;=&lt;/span&gt; &lt;span class='meta meta_array meta_array_php'&gt;&lt;span class='support support_function support_function_construct support_function_construct_php'&gt;array&lt;/span&gt;(&lt;span class='support support_function support_function_array support_function_array_php'&gt;array_shift&lt;/span&gt;(&lt;span class='variable variable_other variable_other_php'&gt;$l&lt;/span&gt;)&lt;/span&gt;, &lt;span class='variable variable_other variable_other_php'&gt;$l&lt;/span&gt;);&lt;br /&gt;  &lt;span class='keyword keyword_control keyword_control_php'&gt;return&lt;/span&gt; &lt;span class='support support_function support_function_array support_function_array_php'&gt;array_merge&lt;/span&gt;(&lt;br /&gt;     &lt;span class='meta meta_function-call meta_function-call_php'&gt;qsort&lt;/span&gt;(&lt;span class='support support_function support_function_array support_function_array_php'&gt;array_filter&lt;/span&gt;(&lt;span class='variable variable_other variable_other_php'&gt;$cdr&lt;/span&gt;, &lt;span class='support support_function support_function_builtin_functions support_function_builtin_functions_php'&gt;create_function&lt;/span&gt;(&lt;span class='string string_quoted string_quoted_single string_quoted_single_php'&gt;'&lt;span class='meta meta_string-contents meta_string-contents_quoted meta_string-contents_quoted_single meta_string-contents_quoted_single_php'&gt;$e&lt;/span&gt;'&lt;/span&gt;, &lt;span class='string string_quoted string_quoted_double string_quoted_double_php'&gt;&amp;quot;&lt;span class='meta meta_string-contents meta_string-contents_quoted meta_string-contents_quoted_double meta_string-contents_quoted_double_php'&gt;return &lt;span class='constant constant_character constant_character_escape constant_character_escape_php'&gt;\$&lt;/span&gt;e &amp;lt;= &lt;span class='variable variable_other variable_other_php'&gt;$car&lt;/span&gt;;&lt;/span&gt;&amp;quot;&lt;/span&gt;))), &lt;br /&gt;     &lt;span class='meta meta_array meta_array_php'&gt;&lt;span class='support support_function support_function_construct support_function_construct_php'&gt;array&lt;/span&gt;(&lt;span class='variable variable_other variable_other_php'&gt;$car&lt;/span&gt;)&lt;/span&gt;, &lt;br /&gt;     &lt;span class='meta meta_function-call meta_function-call_php'&gt;qsort&lt;/span&gt;(&lt;span class='support support_function support_function_array support_function_array_php'&gt;array_filter&lt;/span&gt;(&lt;span class='variable variable_other variable_other_php'&gt;$cdr&lt;/span&gt;, &lt;span class='support support_function support_function_builtin_functions support_function_builtin_functions_php'&gt;create_function&lt;/span&gt;(&lt;span class='string string_quoted string_quoted_single string_quoted_single_php'&gt;'&lt;span class='meta meta_string-contents meta_string-contents_quoted meta_string-contents_quoted_single meta_string-contents_quoted_single_php'&gt;$e&lt;/span&gt;'&lt;/span&gt;, &lt;span class='string string_quoted string_quoted_double string_quoted_double_php'&gt;&amp;quot;&lt;span class='meta meta_string-contents meta_string-contents_quoted meta_string-contents_quoted_double meta_string-contents_quoted_double_php'&gt;return &lt;span class='constant constant_character constant_character_escape constant_character_escape_php'&gt;\$&lt;/span&gt;e &amp;gt; &lt;span class='variable variable_other variable_other_php'&gt;$car&lt;/span&gt;;&lt;/span&gt;&amp;quot;&lt;/span&gt;)))&lt;br /&gt;  );&lt;br /&gt;}&lt;br /&gt;&lt;span class='source source_php'&gt;?&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;And I was pleased to see that I could, more or less, emulate Ruby's select/find iterator:&lt;br /&gt;&lt;br /&gt;&lt;pre class="textmate-source"&gt;&lt;pre class="sunburst"&gt;&lt;span class='string string_regexp string_regexp_classic string_regexp_classic_ruby'&gt;/&lt;/span&gt;&lt;span class='string string_regexp string_regexp_classic string_regexp_classic_ruby'&gt;&lt;/span&gt;&lt;span class='string string_regexp string_regexp_classic string_regexp_classic_ruby'&gt;/&lt;/span&gt; &lt;span class='variable variable_other variable_other_constant variable_other_constant_ruby'&gt;Ruby&lt;/span&gt;&lt;br /&gt;cdr&lt;span class='meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby'&gt;.&lt;span class='entity entity_name entity_name_function entity_name_function_ruby'&gt;select&lt;/span&gt;&lt;/span&gt; {&lt;span class='meta meta_syntax meta_syntax_ruby meta_syntax_ruby_start-block'&gt; &lt;/span&gt;|&lt;span class='variable variable_other variable_other_block variable_other_block_ruby'&gt;x&lt;/span&gt;| x &lt;span class='keyword keyword_operator keyword_operator_comparison keyword_operator_comparison_ruby'&gt;&amp;lt;=&lt;/span&gt; car }&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre class="textmate-source"&gt;&lt;pre class="sunburst"&gt;/* in PHP */&lt;br /&gt;&lt;span class='source source_php source_php_embedded source_php_embedded_block source_php_embedded_block_html'&gt;&amp;lt;?php &lt;span class='support support_function support_function_array support_function_array_php'&gt;array_filter&lt;/span&gt;(&lt;span class='variable variable_other variable_other_php'&gt;$cdr&lt;/span&gt;, &lt;span class='support support_function support_function_builtin_functions support_function_builtin_functions_php'&gt;create_function&lt;/span&gt;(&lt;span class='string string_quoted string_quoted_single string_quoted_single_php'&gt;'&lt;span class='meta meta_string-contents meta_string-contents_quoted meta_string-contents_quoted_single meta_string-contents_quoted_single_php'&gt;$e&lt;/span&gt;'&lt;/span&gt;, &lt;span class='string string_quoted string_quoted_double string_quoted_double_php'&gt;&amp;quot;&lt;span class='meta meta_string-contents meta_string-contents_quoted meta_string-contents_quoted_double meta_string-contents_quoted_double_php'&gt;return &lt;span class='constant constant_character constant_character_escape constant_character_escape_php'&gt;\$&lt;/span&gt;e &amp;lt;= &lt;span class='variable variable_other variable_other_php'&gt;$car&lt;/span&gt;;&lt;/span&gt;&amp;quot;&lt;/span&gt;)); &lt;span class='source source_php'&gt;?&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;"But is it fast, Jim", you ask with baited breath. No. It could hardly be slower. PEAR has a nice little benchmarking package that will bring this point home (each sorting an array of 1000 random integers):&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;My Dumb Quicksort&lt;/strong&gt;&lt;br /&gt;&lt;code&gt;time: 0.3607&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;PHP's built in sort&lt;/strong&gt;&lt;br /&gt;&lt;code&gt;time: 0.0015&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;It isn't as nearly ugly as you'd expect it to be -- and still much easier to read than it would have been without the use of create_function. I'm always finding that I can do more with PHP than I thought I could.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7665701969641921005-8456705420867729887?l=mumuki2.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7665701969641921005/posts/default/8456705420867729887'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7665701969641921005/posts/default/8456705420867729887'/><link rel='alternate' type='text/html' href='http://mumuki2.blogspot.com/2008/09/quicksort-in-php.html' title='Quicksort in PHP'/><author><name>J. Whiteman</name><uri>http://www.blogger.com/profile/05163279495847602913</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-7665701969641921005.post-7644299482988695684</id><published>2008-09-16T17:52:00.000-07:00</published><updated>2008-09-16T17:56:17.316-07:00</updated><title type='text'>Creating Random Usernames and Passwords with Ruby</title><content type='html'>&lt;pre class="textmate-source"&gt;&lt;pre class="sunburst"&gt;&lt;span class='variable variable_other variable_other_constant variable_other_constant_ruby'&gt;NUMBER_OF_USERNAME_PASSWORDS&lt;/span&gt; &lt;span class='keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby'&gt;=&lt;/span&gt; &lt;span class='constant constant_numeric constant_numeric_ruby'&gt;10_000&lt;/span&gt;&lt;br /&gt;&lt;span class='variable variable_other variable_other_constant variable_other_constant_ruby'&gt;LENGTH&lt;/span&gt; &lt;span class='keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby'&gt;=&lt;/span&gt; &lt;span class='constant constant_numeric constant_numeric_ruby'&gt;8&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;passwords &lt;span class='keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby'&gt;=&lt;/span&gt; &lt;span class='support support_class support_class_ruby'&gt;Hash&lt;/span&gt;[ &lt;br /&gt;  &lt;span class='keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby'&gt;*&lt;/span&gt;&lt;span class='support support_class support_class_ruby'&gt;Array&lt;/span&gt;&lt;span class='meta meta_function-call meta_function-call_method meta_function-call_method_with-arguments meta_function-call_method_with-arguments_ruby'&gt;.&lt;span class='entity entity_name entity_name_function entity_name_function_ruby'&gt;new&lt;/span&gt;&lt;/span&gt;(&lt;span class='variable variable_other variable_other_constant variable_other_constant_ruby'&gt;NUMBER_OF_USERNAME_PASSWORDS&lt;/span&gt;) &lt;span class='keyword keyword_control keyword_control_ruby keyword_control_ruby_start-block'&gt;do&lt;/span&gt;&lt;br /&gt;    proc {&lt;span class='meta meta_syntax meta_syntax_ruby meta_syntax_ruby_start-block'&gt; &lt;/span&gt;|&lt;span class='variable variable_other variable_other_block variable_other_block_ruby'&gt;n&lt;/span&gt;| &lt;span class='support support_class support_class_ruby'&gt;Array&lt;/span&gt;&lt;span class='meta meta_function-call meta_function-call_method meta_function-call_method_with-arguments meta_function-call_method_with-arguments_ruby'&gt;.&lt;span class='entity entity_name entity_name_function entity_name_function_ruby'&gt;new&lt;/span&gt;&lt;/span&gt;(n) {&lt;span class='meta meta_syntax meta_syntax_ruby meta_syntax_ruby_start-block'&gt; &lt;/span&gt;(&lt;span class='constant constant_numeric constant_numeric_ruby'&gt;97&lt;/span&gt;..&lt;span class='constant constant_numeric constant_numeric_ruby'&gt;122&lt;/span&gt;)&lt;span class='meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby'&gt;.&lt;span class='entity entity_name entity_name_function entity_name_function_ruby'&gt;to_a&lt;/span&gt;&lt;/span&gt;[ &lt;span class='meta meta_function-call meta_function-call_ruby'&gt;&lt;span class='entity entity_name entity_name_function entity_name_function_ruby'&gt;rand&lt;/span&gt;&lt;/span&gt;(&lt;span class='constant constant_numeric constant_numeric_ruby'&gt;26&lt;/span&gt;) ]&lt;span class='meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby'&gt;.&lt;span class='entity entity_name entity_name_function entity_name_function_ruby'&gt;chr&lt;/span&gt;&lt;/span&gt; }&lt;span class='meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby'&gt;.&lt;span class='entity entity_name entity_name_function entity_name_function_ruby'&gt;join&lt;/span&gt;&lt;/span&gt; }[&lt;span class='variable variable_other variable_other_constant variable_other_constant_ruby'&gt;LENGTH&lt;/span&gt;]&lt;br /&gt;  &lt;span class='keyword keyword_control keyword_control_ruby'&gt;end&lt;/span&gt;&lt;br /&gt;]&lt;br /&gt;&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;In this case, the variable &lt;code&gt;passwords&lt;/code&gt; will be a hash of &lt;code&gt;{ :usernames =&gt; :passwords }&lt;/code&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7665701969641921005-7644299482988695684?l=mumuki2.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7665701969641921005/posts/default/7644299482988695684'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7665701969641921005/posts/default/7644299482988695684'/><link rel='alternate' type='text/html' href='http://mumuki2.blogspot.com/2008/09/creating-random-usernames-and-passwords.html' title='Creating Random Usernames and Passwords with Ruby'/><author><name>J. Whiteman</name><uri>http://www.blogger.com/profile/05163279495847602913</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-7665701969641921005.post-5981574072372280848</id><published>2008-09-08T22:07:00.000-07:00</published><updated>2008-09-16T14:12:59.073-07:00</updated><title type='text'>PHP: A Language Full of Ceremony</title><content type='html'>Porting some of the previous post into PHP:&lt;br /&gt;&lt;pre class="textmate-source"&gt;&lt;pre class="sunburst"&gt;&lt;span class='source source_php source_php_embedded source_php_embedded_block source_php_embedded_block_html'&gt;&amp;lt;?php&lt;br /&gt;&lt;span class='meta meta_class meta_class_php'&gt;&lt;span class='storage storage_type storage_type_class storage_type_class_php'&gt;class&lt;/span&gt; &lt;span class='entity entity_name entity_name_type entity_name_type_class entity_name_type_class_php'&gt;SillyReverse&lt;/span&gt; {&lt;/span&gt;&lt;br /&gt; &lt;br /&gt; &lt;span class='storage storage_modifier storage_modifier_php'&gt;private&lt;/span&gt; &lt;span class='variable variable_other variable_other_php'&gt;$string&lt;/span&gt;;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;&lt;span class='meta meta_function meta_function_php'&gt; &lt;span class='storage storage_type storage_type_function storage_type_function_php'&gt;function&lt;/span&gt; &lt;span class='support support_function support_function_magic support_function_magic_php'&gt;__construct&lt;/span&gt;(&lt;span class='meta meta_function meta_function_arguments meta_function_arguments_php'&gt;&lt;span class='meta meta_function meta_function_argument meta_function_argument_no-default meta_function_argument_no-default_php'&gt;&lt;span class='variable variable_other variable_other_php'&gt;$s&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; {&lt;br /&gt;  &lt;span class='variable variable_other variable_other_php'&gt;$this&lt;/span&gt;&lt;span class='keyword keyword_operator keyword_operator_class keyword_operator_class_php'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='variable variable_other variable_other_property variable_other_property_php'&gt;string&lt;/span&gt; &lt;span class='keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_php'&gt;=&lt;/span&gt; &lt;span class='variable variable_other variable_other_php'&gt;$s&lt;/span&gt;;&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;&lt;span class='meta meta_function meta_function_php'&gt; &lt;span class='storage storage_type storage_type_function storage_type_function_php'&gt;function&lt;/span&gt; &lt;span class='entity entity_name entity_name_function entity_name_function_php'&gt;reverse&lt;/span&gt;(&lt;span class='meta meta_function meta_function_arguments meta_function_arguments_php'&gt;&lt;/span&gt;)&lt;/span&gt; {&lt;br /&gt;  &lt;span class='keyword keyword_control keyword_control_php'&gt;return&lt;/span&gt; &lt;span class='variable variable_other variable_other_php'&gt;$this&lt;/span&gt;&lt;span class='keyword keyword_operator keyword_operator_class keyword_operator_class_php'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='meta meta_function-call meta_function-call_object meta_function-call_object_php'&gt;reverse_helper&lt;/span&gt;(&lt;span class='variable variable_other variable_other_php'&gt;$this&lt;/span&gt;&lt;span class='keyword keyword_operator keyword_operator_class keyword_operator_class_php'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='variable variable_other variable_other_property variable_other_property_php'&gt;string&lt;/span&gt;);&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;&lt;span class='meta meta_function meta_function_php'&gt; &lt;span class='storage storage_modifier storage_modifier_php'&gt;private &lt;/span&gt;&lt;span class='storage storage_type storage_type_function storage_type_function_php'&gt;function&lt;/span&gt; &lt;span class='entity entity_name entity_name_function entity_name_function_php'&gt;reverse_helper&lt;/span&gt;(&lt;span class='meta meta_function meta_function_arguments meta_function_arguments_php'&gt;&lt;span class='meta meta_function meta_function_argument meta_function_argument_no-default meta_function_argument_no-default_php'&gt;&lt;span class='variable variable_other variable_other_php'&gt;$string&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; {&lt;br /&gt;  &lt;span class='keyword keyword_control keyword_control_php'&gt;if&lt;/span&gt; (&lt;span class='variable variable_other variable_other_php'&gt;$this&lt;/span&gt;&lt;span class='keyword keyword_operator keyword_operator_class keyword_operator_class_php'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='meta meta_function-call meta_function-call_object meta_function-call_object_php'&gt;is_midpoint&lt;/span&gt;(&lt;span class='variable variable_other variable_other_php'&gt;$string&lt;/span&gt;)) {&lt;br /&gt;    &lt;span class='keyword keyword_control keyword_control_php'&gt;return&lt;/span&gt; &lt;span class='variable variable_other variable_other_php'&gt;$string&lt;/span&gt;;&lt;br /&gt;  } &lt;span class='keyword keyword_control keyword_control_php'&gt;else&lt;/span&gt; {&lt;br /&gt;    &lt;span class='keyword keyword_control keyword_control_php'&gt;return&lt;/span&gt; &lt;span class='variable variable_other variable_other_php'&gt;$this&lt;/span&gt;&lt;span class='keyword keyword_operator keyword_operator_class keyword_operator_class_php'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='meta meta_function-call meta_function-call_object meta_function-call_object_php'&gt;last_char&lt;/span&gt;(&lt;span class='variable variable_other variable_other_php'&gt;$string&lt;/span&gt;) &lt;span class='keyword keyword_operator keyword_operator_string keyword_operator_string_php'&gt;.&lt;/span&gt; &lt;br /&gt;           &lt;span class='variable variable_other variable_other_php'&gt;$this&lt;/span&gt;&lt;span class='keyword keyword_operator keyword_operator_class keyword_operator_class_php'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='meta meta_function-call meta_function-call_object meta_function-call_object_php'&gt;reverse_helper&lt;/span&gt;(&lt;span class='variable variable_other variable_other_php'&gt;$this&lt;/span&gt;&lt;span class='keyword keyword_operator keyword_operator_class keyword_operator_class_php'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='meta meta_function-call meta_function-call_object meta_function-call_object_php'&gt;middle&lt;/span&gt;(&lt;span class='variable variable_other variable_other_php'&gt;$string&lt;/span&gt;)) &lt;span class='keyword keyword_operator keyword_operator_string keyword_operator_string_php'&gt;.&lt;/span&gt; &lt;br /&gt;           &lt;span class='variable variable_other variable_other_php'&gt;$this&lt;/span&gt;&lt;span class='keyword keyword_operator keyword_operator_class keyword_operator_class_php'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='meta meta_function-call meta_function-call_object meta_function-call_object_php'&gt;first_char&lt;/span&gt;(&lt;span class='variable variable_other variable_other_php'&gt;$string&lt;/span&gt;); &lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;&lt;span class='meta meta_function meta_function_php'&gt; &lt;span class='storage storage_modifier storage_modifier_php'&gt;private &lt;/span&gt;&lt;span class='storage storage_type storage_type_function storage_type_function_php'&gt;function&lt;/span&gt; &lt;span class='entity entity_name entity_name_function entity_name_function_php'&gt;is_midpoint&lt;/span&gt;(&lt;span class='meta meta_function meta_function_arguments meta_function_arguments_php'&gt;&lt;span class='meta meta_function meta_function_argument meta_function_argument_no-default meta_function_argument_no-default_php'&gt;&lt;span class='variable variable_other variable_other_php'&gt;$string&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; {&lt;br /&gt;  &lt;span class='keyword keyword_control keyword_control_php'&gt;return&lt;/span&gt; &lt;span class='support support_function support_function_builtin_functions support_function_builtin_functions_php'&gt;strlen&lt;/span&gt;(&lt;span class='variable variable_other variable_other_php'&gt;$string&lt;/span&gt;) &lt;span class='keyword keyword_operator keyword_operator_comparison keyword_operator_comparison_php'&gt;==&lt;/span&gt; &lt;span class='constant constant_numeric constant_numeric_php'&gt;0&lt;/span&gt; &lt;span class='keyword keyword_operator keyword_operator_logical keyword_operator_logical_php'&gt;||&lt;/span&gt; &lt;span class='support support_function support_function_builtin_functions support_function_builtin_functions_php'&gt;strlen&lt;/span&gt;(&lt;span class='variable variable_other variable_other_php'&gt;$string&lt;/span&gt;) &lt;span class='keyword keyword_operator keyword_operator_comparison keyword_operator_comparison_php'&gt;==&lt;/span&gt; &lt;span class='constant constant_numeric constant_numeric_php'&gt;1&lt;/span&gt;;&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;&lt;span class='meta meta_function meta_function_php'&gt; &lt;span class='storage storage_modifier storage_modifier_php'&gt;private &lt;/span&gt;&lt;span class='storage storage_type storage_type_function storage_type_function_php'&gt;function&lt;/span&gt; &lt;span class='entity entity_name entity_name_function entity_name_function_php'&gt;last_char&lt;/span&gt;(&lt;span class='meta meta_function meta_function_arguments meta_function_arguments_php'&gt;&lt;span class='meta meta_function meta_function_argument meta_function_argument_no-default meta_function_argument_no-default_php'&gt;&lt;span class='variable variable_other variable_other_php'&gt;$string&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; {&lt;br /&gt;  &lt;span class='keyword keyword_control keyword_control_php'&gt;return&lt;/span&gt; &lt;span class='variable variable_other variable_other_php'&gt;$string&lt;/span&gt;[&lt;span class='support support_function support_function_builtin_functions support_function_builtin_functions_php'&gt;strlen&lt;/span&gt;(&lt;span class='variable variable_other variable_other_php'&gt;$string&lt;/span&gt;)&lt;span class='keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_php'&gt;-&lt;/span&gt;&lt;span class='constant constant_numeric constant_numeric_php'&gt;1&lt;/span&gt;];&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;&lt;span class='meta meta_function meta_function_php'&gt; &lt;span class='storage storage_modifier storage_modifier_php'&gt;private &lt;/span&gt;&lt;span class='storage storage_type storage_type_function storage_type_function_php'&gt;function&lt;/span&gt; &lt;span class='entity entity_name entity_name_function entity_name_function_php'&gt;first_char&lt;/span&gt;(&lt;span class='meta meta_function meta_function_arguments meta_function_arguments_php'&gt;&lt;span class='meta meta_function meta_function_argument meta_function_argument_no-default meta_function_argument_no-default_php'&gt;&lt;span class='variable variable_other variable_other_php'&gt;$string&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; {&lt;br /&gt;  &lt;span class='keyword keyword_control keyword_control_php'&gt;return&lt;/span&gt; &lt;span class='support support_function support_function_string support_function_string_php'&gt;substr&lt;/span&gt;(&lt;span class='variable variable_other variable_other_php'&gt;$string&lt;/span&gt;, &lt;span class='constant constant_numeric constant_numeric_php'&gt;0&lt;/span&gt;, &lt;span class='constant constant_numeric constant_numeric_php'&gt;1&lt;/span&gt;);&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;&lt;span class='meta meta_function meta_function_php'&gt; &lt;span class='storage storage_modifier storage_modifier_php'&gt;private &lt;/span&gt;&lt;span class='storage storage_type storage_type_function storage_type_function_php'&gt;function&lt;/span&gt; &lt;span class='entity entity_name entity_name_function entity_name_function_php'&gt;middle&lt;/span&gt;(&lt;span class='meta meta_function meta_function_arguments meta_function_arguments_php'&gt;&lt;span class='meta meta_function meta_function_argument meta_function_argument_no-default meta_function_argument_no-default_php'&gt;&lt;span class='variable variable_other variable_other_php'&gt;$string&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;)&lt;/span&gt; {&lt;br /&gt;  &lt;span class='keyword keyword_control keyword_control_php'&gt;return&lt;/span&gt; &lt;span class='support support_function support_function_string support_function_string_php'&gt;substr&lt;/span&gt;(&lt;span class='variable variable_other variable_other_php'&gt;$string&lt;/span&gt;, &lt;span class='constant constant_numeric constant_numeric_php'&gt;1&lt;/span&gt;, &lt;span class='keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_php'&gt;-&lt;/span&gt;&lt;span class='constant constant_numeric constant_numeric_php'&gt;1&lt;/span&gt;);&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class='variable variable_other variable_other_php'&gt;$sr&lt;/span&gt; &lt;span class='keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_php'&gt;=&lt;/span&gt; &lt;span class='keyword keyword_other keyword_other_new keyword_other_new_php'&gt;new&lt;/span&gt; &lt;span class='support support_class support_class_php'&gt;SillyReverse&lt;/span&gt;(&lt;span class='string string_quoted string_quoted_single string_quoted_single_php'&gt;'&lt;span class='meta meta_string-contents meta_string-contents_quoted meta_string-contents_quoted_single meta_string-contents_quoted_single_php'&gt;hello, world&lt;/span&gt;'&lt;/span&gt;);&lt;br /&gt;&lt;span class='support support_function support_function_construct support_function_construct_php'&gt;print&lt;/span&gt; &lt;span class='variable variable_other variable_other_php'&gt;$sr&lt;/span&gt;&lt;span class='keyword keyword_operator keyword_operator_class keyword_operator_class_php'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='meta meta_function-call meta_function-call_object meta_function-call_object_php'&gt;reverse&lt;/span&gt;() &lt;span class='keyword keyword_operator keyword_operator_string keyword_operator_string_php'&gt;.&lt;/span&gt; &lt;span class='string string_quoted string_quoted_double string_quoted_double_php'&gt;&amp;quot;&lt;span class='meta meta_string-contents meta_string-contents_quoted meta_string-contents_quoted_double meta_string-contents_quoted_double_php'&gt;&lt;span class='constant constant_character constant_character_escape constant_character_escape_php'&gt;\n&lt;/span&gt;&lt;/span&gt;&amp;quot;&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class='source source_php'&gt;?&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7665701969641921005-5981574072372280848?l=mumuki2.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7665701969641921005/posts/default/5981574072372280848'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7665701969641921005/posts/default/5981574072372280848'/><link rel='alternate' type='text/html' href='http://mumuki2.blogspot.com/2008/09/php-language-full-of-ceremony.html' title='PHP: A Language Full of Ceremony'/><author><name>J. Whiteman</name><uri>http://www.blogger.com/profile/05163279495847602913</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-7665701969641921005.post-1932628387547843923</id><published>2008-08-27T08:10:00.000-07:00</published><updated>2008-09-16T14:44:28.063-07:00</updated><title type='text'>Reversing Strings in Ruby: Two Different Kinds</title><content type='html'>Admittedly, reversing a string in Ruby is as easy as &lt;code&gt;string.reverse&lt;/code&gt;. But for the sake of &lt;a href="http://codekata.pragprog.com/"&gt;code katas&lt;/a&gt; (and preparing for Ruby job interviews) it's sometimes worth the effort to roll your own. Here are two different ways that I came up with.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;A smarter way (while not using C)&lt;/strong&gt;&lt;br /&gt;&lt;pre class="textmate-source"&gt;&lt;pre class="sunburst"&gt;&lt;span class='meta meta_class meta_class_ruby'&gt;&lt;span class='keyword keyword_control keyword_control_class keyword_control_class_ruby'&gt;class&lt;/span&gt; &lt;span class='entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby'&gt;String&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;  &lt;br /&gt;&lt;span class='comment comment_line comment_line_number-sign comment_line_number-sign_ruby'&gt;  # reversing in place&lt;/span&gt;&lt;br /&gt;  &lt;span class='meta meta_function meta_function_method meta_function_method_without-arguments meta_function_method_without-arguments_ruby'&gt;&lt;span class='keyword keyword_control keyword_control_def keyword_control_def_ruby'&gt;def&lt;/span&gt; &lt;span class='entity entity_name entity_name_function entity_name_function_ruby'&gt;reverse_i!&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;    (&lt;span class='constant constant_numeric constant_numeric_ruby'&gt;0&lt;/span&gt;...midpoint)&lt;span class='meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby'&gt;.&lt;span class='entity entity_name entity_name_function entity_name_function_ruby'&gt;each&lt;/span&gt;&lt;/span&gt; &lt;span class='keyword keyword_control keyword_control_ruby keyword_control_ruby_start-block'&gt;do &lt;/span&gt;|&lt;span class='variable variable_other variable_other_block variable_other_block_ruby'&gt;i&lt;/span&gt;| &lt;br /&gt;      &lt;span class='variable variable_language variable_language_ruby'&gt;self&lt;/span&gt;[i], &lt;span class='variable variable_language variable_language_ruby'&gt;self&lt;/span&gt;[&lt;span class='keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby'&gt;-&lt;/span&gt;(i&lt;span class='keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby'&gt;+&lt;/span&gt;&lt;span class='constant constant_numeric constant_numeric_ruby'&gt;1&lt;/span&gt;)] &lt;span class='keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby'&gt;=&lt;/span&gt; &lt;span class='variable variable_language variable_language_ruby'&gt;self&lt;/span&gt;[&lt;span class='keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby'&gt;-&lt;/span&gt;(i&lt;span class='keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby'&gt;+&lt;/span&gt;&lt;span class='constant constant_numeric constant_numeric_ruby'&gt;1&lt;/span&gt;)], &lt;span class='variable variable_language variable_language_ruby'&gt;self&lt;/span&gt;[i] &lt;br /&gt;    &lt;span class='keyword keyword_control keyword_control_ruby'&gt;end&lt;/span&gt; &lt;br /&gt;    &lt;br /&gt;    &lt;span class='variable variable_language variable_language_ruby'&gt;self&lt;/span&gt;&lt;br /&gt;  &lt;span class='keyword keyword_control keyword_control_ruby'&gt;end&lt;/span&gt;&lt;br /&gt;  &lt;br /&gt;  &lt;span class='keyword keyword_other keyword_other_special-method keyword_other_special-method_ruby'&gt;private&lt;/span&gt; &lt;br /&gt;  &lt;br /&gt;  &lt;span class='meta meta_function meta_function_method meta_function_method_without-arguments meta_function_method_without-arguments_ruby'&gt;&lt;span class='keyword keyword_control keyword_control_def keyword_control_def_ruby'&gt;def&lt;/span&gt; &lt;span class='entity entity_name entity_name_function entity_name_function_ruby'&gt;midpoint&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class='variable variable_language variable_language_ruby'&gt;self&lt;/span&gt;&lt;span class='meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby'&gt;.&lt;span class='entity entity_name entity_name_function entity_name_function_ruby'&gt;size&lt;/span&gt;&lt;/span&gt; &lt;span class='keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby'&gt;/&lt;/span&gt; &lt;span class='constant constant_numeric constant_numeric_ruby'&gt;2&lt;/span&gt;&lt;br /&gt;  &lt;span class='keyword keyword_control keyword_control_ruby'&gt;end&lt;/span&gt;&lt;br /&gt;  &lt;br /&gt;&lt;span class='keyword keyword_control keyword_control_ruby'&gt;end&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;strong&gt;A very pretty way (but would get you fired!)&lt;/strong&gt;&lt;br /&gt;&lt;pre class="textmate-source"&gt;&lt;pre class="sunburst"&gt;&lt;span class='meta meta_function meta_function_method meta_function_method_with-arguments meta_function_method_with-arguments_ruby'&gt;&lt;span class='keyword keyword_control keyword_control_def keyword_control_def_ruby'&gt;def&lt;/span&gt; &lt;span class='entity entity_name entity_name_function entity_name_function_ruby'&gt;reverse&lt;/span&gt;(&lt;span class='variable variable_parameter variable_parameter_function variable_parameter_function_ruby'&gt;s&lt;/span&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;span class='keyword keyword_control keyword_control_ruby'&gt;if&lt;/span&gt; s&lt;span class='meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby'&gt;.&lt;span class='entity entity_name entity_name_function entity_name_function_ruby'&gt;midpoint?&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;    s&lt;br /&gt;  &lt;span class='keyword keyword_control keyword_control_ruby'&gt;else&lt;/span&gt;&lt;br /&gt;    s&lt;span class='meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby'&gt;.&lt;span class='entity entity_name entity_name_function entity_name_function_ruby'&gt;last&lt;/span&gt;&lt;/span&gt; &lt;span class='keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby'&gt;+&lt;/span&gt; &lt;span class='meta meta_function-call meta_function-call_ruby'&gt;&lt;span class='entity entity_name entity_name_function entity_name_function_ruby'&gt;reverse&lt;/span&gt;&lt;/span&gt;(s&lt;span class='meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby'&gt;.&lt;span class='entity entity_name entity_name_function entity_name_function_ruby'&gt;middle&lt;/span&gt;&lt;/span&gt;) &lt;span class='keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby'&gt;+&lt;/span&gt; s&lt;span class='meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby'&gt;.&lt;span class='entity entity_name entity_name_function entity_name_function_ruby'&gt;first&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class='keyword keyword_control keyword_control_ruby'&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span class='keyword keyword_control keyword_control_ruby'&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class='comment comment_line comment_line_number-sign comment_line_number-sign_ruby'&gt;### helpers ###&lt;/span&gt;&lt;br /&gt;&lt;span class='meta meta_function meta_function_method meta_function_method_without-arguments meta_function_method_without-arguments_ruby'&gt;&lt;span class='keyword keyword_control keyword_control_def keyword_control_def_ruby'&gt;def&lt;/span&gt; &lt;span class='entity entity_name entity_name_function entity_name_function_ruby'&gt;midpoint?&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class='variable variable_language variable_language_ruby'&gt;self&lt;/span&gt;&lt;span class='meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby'&gt;.&lt;span class='entity entity_name entity_name_function entity_name_function_ruby'&gt;size&lt;/span&gt;&lt;/span&gt; &lt;span class='keyword keyword_operator keyword_operator_comparison keyword_operator_comparison_ruby'&gt;==&lt;/span&gt; &lt;span class='constant constant_numeric constant_numeric_ruby'&gt;0&lt;/span&gt; &lt;span class='keyword keyword_operator keyword_operator_logical keyword_operator_logical_ruby'&gt;or&lt;/span&gt;&lt;br /&gt;    &lt;span class='variable variable_language variable_language_ruby'&gt;self&lt;/span&gt;&lt;span class='meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby'&gt;.&lt;span class='entity entity_name entity_name_function entity_name_function_ruby'&gt;size&lt;/span&gt;&lt;/span&gt; &lt;span class='keyword keyword_operator keyword_operator_comparison keyword_operator_comparison_ruby'&gt;==&lt;/span&gt; &lt;span class='constant constant_numeric constant_numeric_ruby'&gt;1&lt;/span&gt;&lt;br /&gt;&lt;span class='keyword keyword_control keyword_control_ruby'&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class='meta meta_function meta_function_method meta_function_method_without-arguments meta_function_method_without-arguments_ruby'&gt;&lt;span class='keyword keyword_control keyword_control_def keyword_control_def_ruby'&gt;def&lt;/span&gt; &lt;span class='entity entity_name entity_name_function entity_name_function_ruby'&gt;first&lt;/span&gt;&lt;/span&gt;; &lt;span class='variable variable_language variable_language_ruby'&gt;self&lt;/span&gt;[&lt;span class='constant constant_numeric constant_numeric_ruby'&gt;0&lt;/span&gt;]&lt;span class='meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby'&gt;.&lt;span class='entity entity_name entity_name_function entity_name_function_ruby'&gt;chr&lt;/span&gt;&lt;/span&gt; &lt;span class='keyword keyword_control keyword_control_ruby'&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class='meta meta_function meta_function_method meta_function_method_without-arguments meta_function_method_without-arguments_ruby'&gt;&lt;span class='keyword keyword_control keyword_control_def keyword_control_def_ruby'&gt;def&lt;/span&gt; &lt;span class='entity entity_name entity_name_function entity_name_function_ruby'&gt;middle&lt;/span&gt;&lt;/span&gt;; &lt;span class='variable variable_language variable_language_ruby'&gt;self&lt;/span&gt;[&lt;span class='constant constant_numeric constant_numeric_ruby'&gt;1&lt;/span&gt;...&lt;span class='keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby'&gt;-&lt;/span&gt;&lt;span class='constant constant_numeric constant_numeric_ruby'&gt;1&lt;/span&gt;] &lt;span class='keyword keyword_control keyword_control_ruby'&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class='meta meta_function meta_function_method meta_function_method_without-arguments meta_function_method_without-arguments_ruby'&gt;&lt;span class='keyword keyword_control keyword_control_def keyword_control_def_ruby'&gt;def&lt;/span&gt; &lt;span class='entity entity_name entity_name_function entity_name_function_ruby'&gt;last&lt;/span&gt;&lt;/span&gt;; &lt;span class='variable variable_language variable_language_ruby'&gt;self&lt;/span&gt;[&lt;span class='keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby'&gt;-&lt;/span&gt;&lt;span class='constant constant_numeric constant_numeric_ruby'&gt;1&lt;/span&gt;]&lt;span class='meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby'&gt;.&lt;span class='entity entity_name entity_name_function entity_name_function_ruby'&gt;chr&lt;/span&gt;&lt;/span&gt; &lt;span class='keyword keyword_control keyword_control_ruby'&gt;end&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7665701969641921005-1932628387547843923?l=mumuki2.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7665701969641921005/posts/default/1932628387547843923'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7665701969641921005/posts/default/1932628387547843923'/><link rel='alternate' type='text/html' href='http://mumuki2.blogspot.com/2008/08/reversing-strings-in-ruby-two-different.html' title='Reversing Strings in Ruby: Two Different Kinds'/><author><name>J. Whiteman</name><uri>http://www.blogger.com/profile/05163279495847602913</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-7665701969641921005.post-1287989620587042519</id><published>2008-08-16T21:36:00.000-07:00</published><updated>2008-09-16T15:04:28.501-07:00</updated><title type='text'>More Hitchens</title><content type='html'>"The essence of the independent mind lies not in &lt;em&gt;what&lt;/em&gt; it thinks, but in &lt;em&gt;how&lt;/em&gt; it thinks."&lt;br /&gt;&lt;br /&gt;-- &lt;a href="http://tinyurl.com/55djgn"&gt;Christopher Hitchens&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7665701969641921005-1287989620587042519?l=mumuki2.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7665701969641921005/posts/default/1287989620587042519'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7665701969641921005/posts/default/1287989620587042519'/><link rel='alternate' type='text/html' href='http://mumuki2.blogspot.com/2008/08/note-to-self.html' title='More Hitchens'/><author><name>J. Whiteman</name><uri>http://www.blogger.com/profile/05163279495847602913</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-7665701969641921005.post-7903741119907555682</id><published>2008-06-26T16:16:00.001-07:00</published><updated>2008-09-16T14:37:09.691-07:00</updated><title type='text'>A Y-Combinator for Josh Susser</title><content type='html'>A couple of days ago Josh Susser posted a very &lt;a href="http://blog.hasmanythrough.com/2008/6/20/recursive-lambda"&gt;attractive recursive lambda&lt;/a&gt; in his blog.&lt;br /&gt;&lt;br /&gt;A couple of people in the comments said that a recursive lambda is a prime opportunity to use the Y-combinator.&lt;br /&gt;&lt;br /&gt;In Scheme? Sure. In a Rails application? I don't think so.&lt;br /&gt;&lt;br /&gt;While I think that functional programing represents a more powerful programming paradigm than what's typically used in Ruby, I think it's a mistake to parade Ruby around like it's Lisp (or Haskell, or  ML, etc). It can 'do' Lisp (sans macros) but it's so much better at being itself.&lt;br /&gt;&lt;br /&gt;Anyhoo, I whipped this thing up just to see what it would look like. I started writing in Ruby 1.9, but for some reason, when you coerce a lambda into  a block (i.e  function(&amp; my_lambda)) it turns hash iterations (i.e  |key,value|) into arrays ( |array| ). So I did it in 1.8 -- for which lambda syntax sucks. So I'm going to use &amp;lambda instead of lambda 'cuz it just looks good.&lt;br /&gt;&lt;br /&gt;&lt;pre class="textmate-source"&gt;&lt;pre class="sunburst"&gt;&lt;span class='meta meta_rails meta_rails_controller'&gt;&lt;span class='meta meta_class meta_class_ruby'&gt;&lt;span class='keyword keyword_control keyword_control_class keyword_control_class_ruby'&gt;class&lt;/span&gt; &lt;span class='entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby'&gt;ApplicationController&lt;span class='entity entity_other entity_other_inherited-class entity_other_inherited-class_ruby'&gt; &amp;lt; ActionController::Base&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class='support support_function support_function_actionpack support_function_actionpack_rails'&gt;before_filter&lt;/span&gt; {&lt;span class='meta meta_syntax meta_syntax_ruby meta_syntax_ruby_start-block'&gt; &lt;/span&gt;|&lt;span class='variable variable_other variable_other_block variable_other_block_ruby'&gt;controller&lt;/span&gt;| controller&lt;span class='meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby'&gt;.&lt;span class='entity entity_name entity_name_function entity_name_function_ruby'&gt;params&lt;/span&gt;&lt;/span&gt;&lt;span class='meta meta_function-call meta_function-call_method meta_function-call_method_with-arguments meta_function-call_method_with-arguments_ruby'&gt;.&lt;span class='entity entity_name entity_name_function entity_name_function_ruby'&gt;each&lt;/span&gt;&lt;/span&gt;(&lt;span class='keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby'&gt;&amp;amp;&lt;/span&gt;λ {&lt;span class='meta meta_syntax meta_syntax_ruby meta_syntax_ruby_start-block'&gt; &lt;/span&gt;|&lt;span class='variable variable_other variable_other_block variable_other_block_ruby'&gt;le&lt;/span&gt;|&lt;br /&gt;      λ {|&lt;span class='variable variable_other variable_other_block variable_other_block_ruby'&gt;f&lt;/span&gt;|&lt;br /&gt;        f[f]&lt;br /&gt;      }&lt;span class='meta meta_function-call meta_function-call_method meta_function-call_method_with-arguments meta_function-call_method_with-arguments_ruby'&gt;.&lt;span class='entity entity_name entity_name_function entity_name_function_ruby'&gt;call&lt;/span&gt;&lt;/span&gt;( λ {|&lt;span class='variable variable_other variable_other_block variable_other_block_ruby'&gt;f&lt;/span&gt;| le&lt;span class='meta meta_function-call meta_function-call_method meta_function-call_method_with-arguments meta_function-call_method_with-arguments_ruby'&gt;.&lt;span class='entity entity_name entity_name_function entity_name_function_ruby'&gt;call&lt;/span&gt;&lt;/span&gt;( λ {&lt;span class='meta meta_syntax meta_syntax_ruby meta_syntax_ruby_start-block'&gt; &lt;/span&gt;f[f] }) })&lt;br /&gt;    }&lt;span class='meta meta_function-call meta_function-call_method meta_function-call_method_with-arguments meta_function-call_method_with-arguments_ruby'&gt;.&lt;span class='entity entity_name entity_name_function entity_name_function_ruby'&gt;call&lt;/span&gt;&lt;/span&gt;(λ {|&lt;span class='variable variable_other variable_other_block variable_other_block_ruby'&gt;m&lt;/span&gt;|&lt;br /&gt;            λ {|&lt;span class='variable variable_other variable_other_block variable_other_block_ruby'&gt;k&lt;/span&gt;,&lt;span class='variable variable_other variable_other_block variable_other_block_ruby'&gt;v&lt;/span&gt;|&lt;br /&gt;              &lt;span class='keyword keyword_control keyword_control_ruby'&gt;case&lt;/span&gt; v&lt;br /&gt;                &lt;span class='keyword keyword_control keyword_control_ruby'&gt;when&lt;/span&gt; &lt;span class='variable variable_other variable_other_constant variable_other_constant_ruby'&gt;String&lt;/span&gt; &lt;span class='keyword keyword_control keyword_control_ruby'&gt;then&lt;/span&gt; v&lt;span class='meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby'&gt;.&lt;span class='entity entity_name entity_name_function entity_name_function_ruby'&gt;remove_accents!&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;                &lt;span class='keyword keyword_control keyword_control_ruby'&gt;when&lt;/span&gt; &lt;span class='variable variable_other variable_other_constant variable_other_constant_ruby'&gt;Hash&lt;/span&gt;   &lt;span class='keyword keyword_control keyword_control_ruby'&gt;then&lt;/span&gt; v&lt;span class='meta meta_function-call meta_function-call_method meta_function-call_method_with-arguments meta_function-call_method_with-arguments_ruby'&gt;.&lt;span class='entity entity_name entity_name_function entity_name_function_ruby'&gt;each&lt;/span&gt;&lt;/span&gt;(&lt;span class='keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby'&gt;&amp;amp;&lt;/span&gt;m&lt;span class='meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby'&gt;.&lt;span class='entity entity_name entity_name_function entity_name_function_ruby'&gt;call&lt;/span&gt;&lt;/span&gt;)&lt;br /&gt;              &lt;span class='keyword keyword_control keyword_control_ruby'&gt;end&lt;/span&gt;&lt;br /&gt;             }&lt;br /&gt;        }))&lt;br /&gt;   }&lt;br /&gt;&lt;/span&gt;&lt;span class='keyword keyword_control keyword_control_ruby'&gt;end&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;Well...it &lt;em&gt;is&lt;/em&gt; completely anonymous now. Are we having fun yet? Obviously, there are more readable ways to use Y but none of them result in anything nicer than what Josh wrote. This is basically a long way of saying avoid overly complicated code. You can never justify masturbatory programming because you're using strict FP -- especially in Ruby and even more so in Rails.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7665701969641921005-7903741119907555682?l=mumuki2.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7665701969641921005/posts/default/7903741119907555682'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7665701969641921005/posts/default/7903741119907555682'/><link rel='alternate' type='text/html' href='http://mumuki2.blogspot.com/2008/06/y-combinator-for-josh-susser.html' title='A Y-Combinator for Josh Susser'/><author><name>J. Whiteman</name><uri>http://www.blogger.com/profile/05163279495847602913</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-7665701969641921005.post-5662648755527634819</id><published>2008-04-27T23:29:00.000-07:00</published><updated>2008-09-16T18:14:32.581-07:00</updated><title type='text'>Smalltalk Best Practice Patterns</title><content type='html'>"Coding is where your fuzzy comfortable ideas awaken in the harsh dawn of reality."&lt;br /&gt;&lt;br /&gt;-- &lt;a href="http://tinyurl.com/6j6vxj"&gt;Kent Beck&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7665701969641921005-5662648755527634819?l=mumuki2.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7665701969641921005/posts/default/5662648755527634819'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7665701969641921005/posts/default/5662648755527634819'/><link rel='alternate' type='text/html' href='http://mumuki2.blogspot.com/2008/04/i-wish-i-had-written-this.html' title='Smalltalk Best Practice Patterns'/><author><name>J. Whiteman</name><uri>http://www.blogger.com/profile/05163279495847602913</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-7665701969641921005.post-912922434497963305</id><published>2008-04-22T15:27:00.000-07:00</published><updated>2008-09-16T14:47:15.202-07:00</updated><title type='text'>Testing #new in Ruby with RSpec and Mocha</title><content type='html'>Here's a trick I came up with:&lt;br /&gt;&lt;pre class="textmate-source"&gt;&lt;pre class="sunburst"&gt;&lt;span class='meta meta_class meta_class_ruby'&gt;&lt;span class='keyword keyword_control keyword_control_class keyword_control_class_ruby'&gt;class&lt;/span&gt; &lt;span class='entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby'&gt;Foo&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class='meta meta_function meta_function_method meta_function_method_without-arguments meta_function_method_without-arguments_ruby'&gt;&lt;span class='keyword keyword_control keyword_control_def keyword_control_def_ruby'&gt;def&lt;/span&gt; &lt;span class='entity entity_name entity_name_function entity_name_function_ruby'&gt;initialize&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;    my_nifty_init_method&lt;br /&gt;  &lt;span class='keyword keyword_control keyword_control_ruby'&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span class='keyword keyword_control keyword_control_ruby'&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;describe &lt;span class='variable variable_other variable_other_constant variable_other_constant_ruby'&gt;Foo&lt;/span&gt;, &lt;span class='string string_quoted string_quoted_double string_quoted_double_ruby'&gt;&amp;quot;#new&amp;quot;&lt;/span&gt; &lt;span class='keyword keyword_control keyword_control_ruby keyword_control_ruby_start-block'&gt;do&lt;/span&gt;&lt;br /&gt;  it &lt;span class='string string_quoted string_quoted_double string_quoted_double_ruby'&gt;&amp;quot;should call my_nifty_init_method&amp;quot;&lt;/span&gt; &lt;span class='keyword keyword_control keyword_control_ruby keyword_control_ruby_start-block'&gt;do&lt;/span&gt;&lt;br /&gt;    f &lt;span class='keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby'&gt;=&lt;/span&gt; &lt;span class='support support_class support_class_ruby'&gt;Foo&lt;/span&gt;&lt;span class='meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby'&gt;.&lt;span class='entity entity_name entity_name_function entity_name_function_ruby'&gt;allocate&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;    f&lt;span class='meta meta_function-call meta_function-call_method meta_function-call_method_with-arguments meta_function-call_method_with-arguments_ruby'&gt;.&lt;span class='entity entity_name entity_name_function entity_name_function_ruby'&gt;expects&lt;/span&gt;&lt;/span&gt;(&lt;span class='constant constant_other constant_other_symbol constant_other_symbol_ruby'&gt;:my_nifty_init_method&lt;/span&gt;)&lt;span class='meta meta_function-call meta_function-call_method meta_function-call_method_with-arguments meta_function-call_method_with-arguments_ruby'&gt;.&lt;span class='entity entity_name entity_name_function entity_name_function_ruby'&gt;returns&lt;/span&gt;&lt;/span&gt;(&lt;span class='constant constant_language constant_language_ruby'&gt;true&lt;/span&gt;)&lt;br /&gt;    f&lt;span class='meta meta_function-call meta_function-call_method meta_function-call_method_with-arguments meta_function-call_method_with-arguments_ruby'&gt;.&lt;span class='entity entity_name entity_name_function entity_name_function_ruby'&gt;send&lt;/span&gt;&lt;/span&gt;(&lt;span class='constant constant_other constant_other_symbol constant_other_symbol_ruby'&gt;:initialize&lt;/span&gt;)&lt;br /&gt;  &lt;span class='keyword keyword_control keyword_control_ruby'&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span class='keyword keyword_control keyword_control_ruby'&gt;end&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;Class#allocate creates an object without calling initialize. Pretty cool stuff.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7665701969641921005-912922434497963305?l=mumuki2.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7665701969641921005/posts/default/912922434497963305'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7665701969641921005/posts/default/912922434497963305'/><link rel='alternate' type='text/html' href='http://mumuki2.blogspot.com/2008/04/testing-new-in-ruby-with-rspec.html' title='Testing #new in Ruby with RSpec and Mocha'/><author><name>J. Whiteman</name><uri>http://www.blogger.com/profile/05163279495847602913</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-7665701969641921005.post-24186470901456180</id><published>2007-05-26T15:31:00.000-07:00</published><updated>2008-09-16T18:19:45.737-07:00</updated><title type='text'>Programming Erlang</title><content type='html'>Just got the PDF to &lt;a href="http://www.pragmaticprogrammer.com/titles/jaerlang/index.html"&gt;Programing Erlang&lt;/a&gt; a few weeks ago. Erlang is a functional language, and, from what I can tell, is even more terse than Scheme. The book has a very nice and very compact Quicksort in the second chapter. Here's my version in Ruby:&lt;br /&gt;&lt;pre class="textmate-source"&gt;&lt;pre class="sunburst"&gt;&lt;span class='meta meta_function meta_function_method meta_function_method_with-arguments meta_function_method_with-arguments_ruby'&gt;&lt;span class='keyword keyword_control keyword_control_def keyword_control_def_ruby'&gt;def&lt;/span&gt; &lt;span class='entity entity_name entity_name_function entity_name_function_ruby'&gt;qsort&lt;/span&gt;(&lt;span class='variable variable_parameter variable_parameter_function variable_parameter_function_ruby'&gt;l&lt;/span&gt;)&lt;/span&gt; &lt;br /&gt;   &lt;span class='keyword keyword_control keyword_control_pseudo-method keyword_control_pseudo-method_ruby'&gt;return&lt;/span&gt; [] &lt;span class='keyword keyword_control keyword_control_ruby'&gt;if&lt;/span&gt; l&lt;span class='meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby'&gt;.&lt;span class='entity entity_name entity_name_function entity_name_function_ruby'&gt;empty?&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;   car, &lt;span class='keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby'&gt;*&lt;/span&gt;cdr &lt;span class='keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby'&gt;=&lt;/span&gt; l&lt;br /&gt;   &lt;span class='meta meta_function-call meta_function-call_ruby'&gt;&lt;span class='entity entity_name entity_name_function entity_name_function_ruby'&gt;qsort&lt;/span&gt;&lt;/span&gt;(cdr&lt;span class='meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby'&gt;.&lt;span class='entity entity_name entity_name_function entity_name_function_ruby'&gt;select&lt;/span&gt;&lt;/span&gt; {&lt;span class='meta meta_syntax meta_syntax_ruby meta_syntax_ruby_start-block'&gt; &lt;/span&gt;|&lt;span class='variable variable_other variable_other_block variable_other_block_ruby'&gt;x&lt;/span&gt;| x &lt;span class='keyword keyword_operator keyword_operator_comparison keyword_operator_comparison_ruby'&gt;&amp;lt;=&lt;/span&gt; car }) &lt;span class='keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby'&gt;+&lt;/span&gt;&lt;br /&gt;     [car] &lt;span class='keyword keyword_operator keyword_operator_arithmetic keyword_operator_arithmetic_ruby'&gt;+&lt;/span&gt;&lt;br /&gt;     &lt;span class='meta meta_function-call meta_function-call_ruby'&gt;&lt;span class='entity entity_name entity_name_function entity_name_function_ruby'&gt;qsort&lt;/span&gt;&lt;/span&gt;(cdr&lt;span class='meta meta_function-call meta_function-call_method meta_function-call_method_without-arguments meta_function-call_method_without-arguments_ruby'&gt;.&lt;span class='entity entity_name entity_name_function entity_name_function_ruby'&gt;select&lt;/span&gt;&lt;/span&gt; {&lt;span class='meta meta_syntax meta_syntax_ruby meta_syntax_ruby_start-block'&gt; &lt;/span&gt;|&lt;span class='variable variable_other variable_other_block variable_other_block_ruby'&gt;x&lt;/span&gt;| x &lt;span class='keyword keyword_operator keyword_operator_comparison keyword_operator_comparison_ruby'&gt;&amp;gt;&lt;/span&gt; car })&lt;br /&gt;&lt;span class='keyword keyword_control keyword_control_ruby'&gt;end&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;Not nearly as nice as the one in the book, but still pretty small. I borrowed 'car' and 'cdr' from the Little Schemer...I suppose 'first' and 'rest' would have been more readable. The Erlang book users 'Pivot' and 'L'.  All in all, a very good book so far.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7665701969641921005-24186470901456180?l=mumuki2.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7665701969641921005/posts/default/24186470901456180'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7665701969641921005/posts/default/24186470901456180'/><link rel='alternate' type='text/html' href='http://mumuki2.blogspot.com/2007/04/programming-erlang.html' title='Programming Erlang'/><author><name>J. Whiteman</name><uri>http://www.blogger.com/profile/05163279495847602913</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-7665701969641921005.post-3238868785535140452</id><published>2007-05-11T19:33:00.000-07:00</published><updated>2008-09-17T06:01:45.090-07:00</updated><title type='text'>Take the Long Way Home...</title><content type='html'>I saw this little challenge a week ago &lt;a href="http://www.rubyonrailsblog.com/"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;The Goal:&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Take this array: [1,3,5,5,6,7,9,10,14,18,22,22,4,4,4,3,6]&lt;br /&gt;Turn it into this array: [5, 22, 6, 3, 4]&lt;br /&gt;&lt;br /&gt;In other words, return a set consisting of the duplicated elements.&lt;br /&gt;&lt;br /&gt;The author was looking for solutions in Ruby, but I chose to do it in Scheme instead, just for fun. You can get a nice Scheme IDE for your Mac (or PC) &lt;a href="http://download.plt-scheme.org/drscheme/"&gt;here&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;(define member?&lt;br /&gt;  (lambda (n l)&lt;br /&gt;    (letrec&lt;br /&gt;        ((A (lambda (l)&lt;br /&gt;              (cond&lt;br /&gt;                ((null? l) #f)&lt;br /&gt;                ((eq? (car l) n) #t)&lt;br /&gt;                (else&lt;br /&gt;                 (A (cdr l)))))))&lt;br /&gt;      (A l))))&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; (define eqset?&lt;br /&gt;   (lambda (s1 s2)&lt;br /&gt;     (if (subset? s1 s2)&lt;br /&gt;         (subset? s2 s1)&lt;br /&gt;         #f)))&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; (define subset?&lt;br /&gt;   (lambda (s1 s2)&lt;br /&gt;     (cond&lt;br /&gt;       ((null? s1) #t)&lt;br /&gt;       (else&lt;br /&gt;        (and (member? (car s1) s2)&lt;br /&gt;             (subset? (cdr s1) s2))))))&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;(define Y&lt;br /&gt;  (lambda (le)&lt;br /&gt;    ((lambda (f)&lt;br /&gt;       (f f))&lt;br /&gt;     (lambda (f)&lt;br /&gt;       (le (lambda (x) ((f f) x)))))))&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;(define dupes&lt;br /&gt;  (let ((result '()))&lt;br /&gt;    (lambda (l)&lt;br /&gt;      ((Y (lambda (f)&lt;br /&gt;            (lambda (l)&lt;br /&gt;              (cond&lt;br /&gt;                ((null? l) result)&lt;br /&gt;                ((and (member? (car l)&lt;br /&gt;                            (cdr l))&lt;br /&gt;                      (not (member? (car l)&lt;br /&gt;                                result)))&lt;br /&gt;                 (let ()&lt;br /&gt;                   (set! result (cons (car l)&lt;br /&gt;                              result))&lt;br /&gt;                   (f (cdr l))))&lt;br /&gt;                      (else&lt;br /&gt;                       (f (cdr l)))))))&lt;br /&gt;       l))))&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;;; test the results...&lt;br /&gt;(eq? (eqset?&lt;br /&gt;      (dupes '(1 3 5 5 6 7 9 10 14 18 22 22 4 4 4 3 6))&lt;br /&gt;      '(5 22 6 3 4)) #t)&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7665701969641921005-3238868785535140452?l=mumuki2.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7665701969641921005/posts/default/3238868785535140452'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7665701969641921005/posts/default/3238868785535140452'/><link rel='alternate' type='text/html' href='http://mumuki2.blogspot.com/2007/05/scheme-vs-ruby-not-really.html' title='Take the Long Way Home...'/><author><name>J. Whiteman</name><uri>http://www.blogger.com/profile/05163279495847602913</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-7665701969641921005.post-4556261067328361526</id><published>2007-05-08T17:20:00.000-07:00</published><updated>2007-05-12T20:51:09.807-07:00</updated><title type='text'>Pragmatic Studio: Denver</title><content type='html'>This is the first chance I've had to write since the &lt;a href="http://pragmaticstudio.com/rails/alumni.html#Denver2"&gt;Rails Studio in Denver&lt;/a&gt;. Dave, Mike, and Nicole are very nice people and the three days went more quickly than I would have liked. In hindsight I could have probably been ok in the Advanced Studio in Dallas, but I still learned more than enough to make the event worth while (the lunch at the Marriot was probably worth the price of admission by itself!). The &lt;a href="http://pragmaticstudio.com/"&gt;Pragmatic Guys&lt;/a&gt; seem to do everything top-notch and I can't imagine anyone regretting attending one of their events.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_qAg1VQBcYgs/RkE5wZ_qGhI/AAAAAAAAAAc/mQRo7Sgo9tc/s1600-h/denver1.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_qAg1VQBcYgs/RkE5wZ_qGhI/AAAAAAAAAAc/mQRo7Sgo9tc/s320/denver1.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5062390959915538962" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7665701969641921005-4556261067328361526?l=mumuki2.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7665701969641921005/posts/default/4556261067328361526'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7665701969641921005/posts/default/4556261067328361526'/><link rel='alternate' type='text/html' href='http://mumuki2.blogspot.com/2007/05/pragmatic-studio-denver.html' title='Pragmatic Studio: Denver'/><author><name>J. Whiteman</name><uri>http://www.blogger.com/profile/05163279495847602913</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_qAg1VQBcYgs/RkE5wZ_qGhI/AAAAAAAAAAc/mQRo7Sgo9tc/s72-c/denver1.jpg' height='72' width='72'/></entry></feed>
