<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <title>Aquabu - Home</title>
  <id>tag:aquabu.com,2010:mephisto/</id>
  <generator version="0.7.3" uri="http://mephistoblog.com">Mephisto Noh-Varr</generator>
  <link href="http://aquabu.com/feed/atom.xml" rel="self" type="application/atom+xml"/>
  <link href="http://aquabu.com/" rel="alternate" type="text/html"/>
  <updated>2010-02-18T18:38:01Z</updated>
  <entry xml:base="http://aquabu.com/">
    <author>
      <name>Noah</name>
    </author>
    <id>tag:aquabu.com,2010-02-18:437</id>
    <published>2010-02-18T18:32:00Z</published>
    <updated>2010-02-18T18:38:01Z</updated>
    <category term="Events"/>
    <category term="Generative Music"/>
    <category term="Ruby"/>
    <category term="Ruby on Rails"/>
    <link href="http://aquabu.com/2010/2/18/my-rubyconf-2009-audio-talk-posted-on-confreaks" rel="alternate" type="text/html"/>
    <title>My Rubyconf 2009 Audio Talk Posted on Confreaks</title>
<content type="html">
            My talk at Rubyconf 2009 on using Ruby for audio projects was posted. I focus on frequently unfamiliar open source libs that people may find useful and make reference to a number of BArCMuT presenter's projects. There's a lot of talk about using Ruby and Chuck, SuperCollider, solving sync issues, etc, etc. You can find the source code for the presentations on &quot;github here&quot;:http://github.com/aquabu


&amp;lt;embed allowfullscreen=&quot;true&quot; src=&quot;http://rubyconf2009.confreaks.com/player.swf&quot; flashvars=&quot;image=images%2F20-nov-2009-17-15-making-music-with-ruby-patterns-context-fun-noah-thorp-preview.png&amp;file=http%3A%2F%2Frubyconf2009.confreaks.com%2Fvideos%2F20-nov-2009-17-15-making-music-with-ruby-patterns-context-fun-noah-thorp-small.mp4&amp;plugins=viral-1&quot; allowscriptaccess=&quot;always&quot; height=&quot;380&quot; width=&quot;640&quot; /&gt;

One major Ruby discovery since then is that Charles Nutter (a primary author of jRuby) has a version of Ruby that uses static typing, runs on the JVM, and runs at the speed of Java! It's called duby and it's available &quot;here&quot;:http://github.com/headius/duby
          </content>  </entry>
  <entry xml:base="http://aquabu.com/">
    <author>
      <name>Noah</name>
    </author>
    <id>tag:aquabu.com,2010-01-24:436</id>
    <published>2010-01-24T22:28:00Z</published>
    <updated>2010-02-11T03:18:35Z</updated>
    <category term="Events"/>
    <category term="Music"/>
    <link href="http://aquabu.com/2010/1/24/barcmut-co-organization-constitution" rel="alternate" type="text/html"/>
    <title>BArCMuT Co-Organization Constitution </title>
<content type="html">
            &lt;p&gt;Over the last year I have been contemplating how to further democratize the Bay Area Computer Music Technology group ( &lt;a href=&quot;http://www.barcmut.org&quot;&gt;BArCMuT&lt;/a&gt; ) for more co-organization and stronger collaborative relationships, while maintaining a high quality of events. On my way back from &lt;span class=&quot;caps&quot;&gt;NAMM&lt;/span&gt; this idea for writing a constitution for BArCMuT bubbled up. The only receptacle for the idea on South West was this slightly waxy emergency bag.&lt;/p&gt;


	&lt;p&gt;&lt;img src=&quot;http://aquabu.com/assets/2010/1/24/IMG_0112.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;


	&lt;p&gt;Since then I have refined the constitutions guidelines and listed them below. If you need to skim this article just skip to the &#8220;BArCMuT Constitution&#8221; section. Before I get to the guidelines, I would like to share some background on how I arrived at the new form for BArCMuT&#8230;&lt;/p&gt;


	&lt;h2&gt;Some Background On BArCMuT&#8217;s Inspiration&lt;/h2&gt;


	&lt;p&gt;In 2003 I attended a Dorkbot event in which Tim Thompson presented Key Kit game controller hacks and Dr. Friendly presented a crazy wavelet feedback algorithm. My friend &lt;a href=&quot;http://www.rhiz.eu/person-475-en.html&quot;&gt;Zu&lt;/a&gt; who is an entertainment magazine editor in Poland asked me what I thought the coolest thing in San Francisco was and I told her about Dorkbot. I meant it.&lt;/p&gt;


	&lt;p&gt;Then, in early 07 at the SF Ruby Meetup I had my mind blown by awesome technical talks by Chris Wanstrath (now Github co-founder) and others. These events made me wonder &#8220;why doesn&#8217;t a group like this exist specifically for the computer music community?&#8221;.&lt;/p&gt;


	&lt;p&gt;I had recently quit my job at Digidesign thinking that I was going to develop this weird ontological DJ remixing algorithm while I contracted. I was constantly looking for the right technology to build it in. My max patches had gotten un-managable with 100+ sub-patches and lots of logic that was more suited to procedural programming. Java audio sucked. Chuck &#8211; what was that? Csound was cumbersome. I was unsure about the Supercollider licensing. Ruby had no audio libraries. Python was a little better supported but less familiar. I wanted to hear people tell me about this stuff first hand.&lt;/p&gt;


	&lt;p&gt;I started the Bay Area Computer Music Technology Group in the fall of 2007. On the first night, the event magically came together as community leaders like Tim Thompson, Ge Wang, Vlad Spears, Scot Gresham Lancaster, and David Wessel decended on the Space Gallery in the Tenderloin of San Francisco. Nobody seemed to care about the street noise as we watched Ge&#8217;s chuck demo while sitting on church pews next to a recently assembled indoor skateboarding ramp.&lt;/p&gt;


	&lt;p&gt;The group took off after that night. Now there are over 500 members and we have had over 35 succesful events all over the Bay Area (Stanford &lt;span class=&quot;caps&quot;&gt;CCRMA&lt;/span&gt;, Berkeley &lt;span class=&quot;caps&quot;&gt;CNMAT&lt;/span&gt;, Mills College, Digidesign, Dolby, Maker Faire, &lt;span class=&quot;caps&quot;&gt;GAAFTA&lt;/span&gt; etc). The presenters have been world class awesome and many of the members could just as easily be presenting or audiencing. I typically have to warn presenters that they will need to answer some very difficult questions from the expert tribunal refered to as the &#8220;audience&#8221;. Lots of people have told me how they acquired a job, met collaborators, changed product specs, or began an academic path at a BArCMuT event. This makes me happy and excited.&lt;/p&gt;


	&lt;p&gt;Fast forward to 2010. The community has gained a lot of great momentum with other groups like Phasor, Overlap.org, Learn Tech, Share San Jose, PyGame, and others. We&#8217;ve all been influencing eachother a lot and starting new projects. At an event at &lt;span class=&quot;caps&quot;&gt;CCRMA&lt;/span&gt;, Tim Thompson said how BArCMuT had been one of his inspirations for starting the Share San Jose group. This was both nice and funny because I had actually been inspired by his talk at Dorkbot to create BArCMuT in the first place. I think this illustrates how a cool community can inspire itself.&lt;/p&gt;


	&lt;p&gt;Despite the fact that our community really is a headless web, BArCMuT has formed as a benevolent dictatorship. In 2010 I would really like that to change. To do that I am symbolically stepping down as benevolent dictator and setting up a structure for co-organizing the group (aka the constitution). In fact, it&#8217;s weird to even think of the group as just being &#8220;BArCMuT members&#8221;. BArCMuT is actually just a tool for the community to organize itself, and I would like to re-org BArCMuT to reflect this.&lt;/p&gt;


	&lt;h2&gt;What&#8217;s In It For Me&lt;/h2&gt;


	&lt;p&gt;Part of cooperation is understanding why the people you are cooperating with are doing what they do.&lt;/p&gt;


	&lt;p&gt;At the bottom of my South West emergency bag BArCMuT constitution, there&#8217;s a section titled &#8220;WIIFM&#8221; (an abbreviation for &#8220;What&#8217;s in it for me&#8221;?). At the risk of being overly explicit, let me share why I organize BArCMuT:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;I want to participate in a community that I help to create&lt;/li&gt;
		&lt;li&gt;I want to meet cool collaborators and make cool s@&#38;#%! &lt;/li&gt;
		&lt;li&gt;I want to know about awesome new electronic art technology, libraries, and techniques&lt;/li&gt;
		&lt;li&gt;I want you to think that I am cool and well organized and include me in cool projects&lt;/li&gt;
		&lt;li&gt;I want you to return my phone calls and emails&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Conspicuously missing is any sort of profit motive. BArCMuT is an Open Source inspired organization, vis a vis Eric S. Raymond. The way I see it, collaboration creates value through network effects rather than through hording.&lt;/p&gt;


	&lt;p&gt;To get semi-technical, personal sub-optimization (greed) in a commons reduces the benefit of the commons as a whole and ultimately limits its abilities to benefit community members thus trashing the commons. For the mildly cynical or economics obsessed, building a commons can be thought of as &#8220;enlightened self interest&#8221;. But really, this technical framing doesn&#8217;t capture the spirit of why I built BArCMuT. For those who follow their heart, this approach can be described as just feeling good and creating community.&lt;/p&gt;


	&lt;h2&gt;Envisioning The Computer Music Commons&lt;/h2&gt;


	&lt;p&gt;To further the goals that I listed and I believe that many community members share, I want to reform BArCMuT as a durable commons for the computer music community. My strategy from the beginning has been to remove any frictions to having a neutral commons &#8211; such as such as pursuing direct monetary gain or gratuitous advertising. Now that BArCMuT exists as a community asset, the next step in reducing friction on the commons is to change the structure of BArCMuT from a tree to a graph.&lt;/p&gt;


	&lt;p&gt;Part of the strategy for limiting the politics that can exist within a group, is to limit the scope of what BArCMuT does. I hope to reduce politics by: not having a shared treasury, only allowing free events, and limiting the scope to events relevant to learning about or creating electronic arts (e.g. no concert audience promotion). BArCMuT definitely should support the excellent commercial work that is being done within our community ecosystem, but as a commons it should be clearly differentiated from these ventures.&lt;/p&gt;


	&lt;h2&gt;The BArCMuT Constitution&lt;/h2&gt;


	&lt;p&gt;Every group needs some guidelines &#8211; the more lightweight the better. Here&#8217;s my first attempt at codifying a group constitution for a co-organized BArCMuT. Please post your feedback.&lt;/p&gt;


Goals of the constitution:
	&lt;ul&gt;
	&lt;li&gt;Create a durable commons that is not reliant on a single member (i.e. not a benevolent dictatorship run by me)&lt;/li&gt;
		&lt;li&gt;Further enable the Bay Area computer music community to stay informed about technical talks, hack sessions, and community events&lt;/li&gt;
		&lt;li&gt;Create a neutral commons for members to find collaborators, employment, teachers, and students&lt;/li&gt;
		&lt;li&gt;Filter events to maintain a high level of quality&lt;/li&gt;
	&lt;/ul&gt;


Participants:
	&lt;ul&gt;
	&lt;li&gt;There are four general participant types: co-organizers, hosts, presenters, and attendees &lt;/li&gt;
		&lt;li&gt;Initial co-organizers will be invited by me&lt;/li&gt;
		&lt;li&gt;Additional co-organizers can be added or removed by an 80% group vote (I could use some additional advice on the official decision making process).&lt;/li&gt;
		&lt;li&gt;Co-organizers can schedule official BArCMuT events if they fit the guidelines. An official BArCMuT event is one that sends RSVPs and is listed on the main page of &lt;a href=&quot;http://www.barcmut.org&quot;&gt;barcmut.org&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;Co-organizers, hosts, and presenters are encouraged to list their logo on the barcmut home page&lt;/li&gt;
	&lt;/ul&gt;


BArCMuT event guidelines:
	&lt;ul&gt;
	&lt;li&gt;events must include a technical talk about electronic art technology&lt;/li&gt;
		&lt;li&gt;events must be free to members&lt;/li&gt;
		&lt;li&gt;events must be in the Bay Area&lt;/li&gt;
		&lt;li&gt;hosts, presenters, and co-organizers are encouraged to mention upcoming electronic art events (free or not), job positions, and products. Although community relevant promoting is encouraged as a vital part of the ecosystem, this should not dominate the event.&lt;/li&gt;
		&lt;li&gt;co-organizers can list events (even if they are not official BArCMuT events) in the BArCMuT calendar. It would be great if we could announce all upcoming events listed in the calendar at official BArCMuT events.&lt;/li&gt;
		&lt;li&gt;there will be no shared treasury or treasurer for BArCMuT&lt;/li&gt;
		&lt;li&gt;venues, presentations, and co-organization are offered for free &lt;/li&gt;
		&lt;li&gt;expenses will be payed by co-organizers or by donation (e.g. for security gaurds, snacks, etc.)&lt;/li&gt;
	&lt;/ul&gt;


I am inviting trusted community members who I have organized events with in the past to be BArCMuT co-organizers. These co-organizers can schedule events that fit the BArCMuT guidelines. These include:
	&lt;ul&gt;
	&lt;li&gt;Ge Wang (CCRMA, Smule)&lt;/li&gt;
		&lt;li&gt;Sasha Leitman, Linnea Williams, Carr Wilkerson (CCRMA)&lt;/li&gt;
		&lt;li&gt;Tim Thompson (Share San Jose, Visual Music Meetup, ZeroOne)&lt;/li&gt;
		&lt;li&gt;David Wessel, Adrian Freed, Andy Schmeder (CNMAT)&lt;/li&gt;
		&lt;li&gt;Barry Threw (GAFFTA, Overlap.org, etc.)&lt;/li&gt;
		&lt;li&gt;Vlad Spears (Phasor, Overlap.org)&lt;/li&gt;
		&lt;li&gt;Harry Tormey (PyGame, Digidesign)&lt;/li&gt;
		&lt;li&gt;Chris Brown (Mills)&lt;/li&gt;
		&lt;li&gt;Scot Gresham-Lancaster (Cogswell, The Hub)&lt;/li&gt;
		&lt;li&gt;Rich &#38; Moldover (Learntech, LoveTech)&lt;/li&gt;
		&lt;li&gt;If you are not on the list and you think you should be let me know&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;A note about scheduling. If there are too many events (e.g &amp;gt; 4 per month) we may need to thin things out. One strategy would be to to list events that repeat frequently once as official BArCMuT &lt;span class=&quot;caps&quot;&gt;RSVP&lt;/span&gt; events and then list them in the non &lt;span class=&quot;caps&quot;&gt;RSVP&lt;/span&gt; calendar to be announced at other events.&lt;/p&gt;


	&lt;h2&gt;Conclusion&lt;/h2&gt;


	&lt;p&gt;In conclusion, I am excited about being part of more great events this year as a &lt;strong&gt;co-organizer&lt;/strong&gt;. My plan is to work towards a durable commons through transparency and establishing light weight and usable guidelines. If I am doing something that seems to work against this plan, please tell me. I&#8217;m not perfect and I would appreciate the feedback.&lt;/p&gt;


	&lt;p&gt;Even before this article has been completed I have had some great conversations with other organizers about creating this commons. 2010 is going to be a great year for community!&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://aquabu.com/">
    <author>
      <name>Noah</name>
    </author>
    <id>tag:aquabu.com,2009-07-21:355</id>
    <published>2009-07-21T03:15:00Z</published>
    <updated>2010-01-23T02:08:16Z</updated>
    <category term="Ruby"/>
    <category term="Ruby on Rails"/>
    <link href="http://aquabu.com/2009/7/21/jquery-wherefore-doth-thy-includes-go" rel="alternate" type="text/html"/>
    <title>jQuery Wherefore Doth Thy Includes Go?</title>
<content type="html">
            h2. Whither Javascript

Recently I have been working on a Rails project with lots of Javascript include complexity ( &quot;Ashbury Music Hall&quot;:http://www.ashburymusichall.com ). Here's the challenge:


* Some larger libraries and plugins only need to appear on single pages (e.g. Thickbox, FCKEditor).
* Some Ajax page renders depend on core libraries (e.g. jQuery) but shouldn't be loaded more than once by layouts and partials
* When Ajax page renders degrade to linked pages they may be in alternate layouts and include different Javascript libraries or have different load orders
* Rails partials load *before* layouts and potentially include Javascript files specified in them before core libraries
* Page and partial specific Javascript (e.g. myview/my_page.js ) presents even more complexity
* Pages appear to load faster if Javascript is loaded on the bottom of the page

Oh what a tangled web we weave.

h2. Thither

The solution I arrived at is to specify sectional order of libraries, accumulate them, deduplicate them, and include them at the end of the page request. This allows definition of core libraries at the top of a layout page for all partials and inclusion of librararies in plugins on any view or partial without duplicate loading or core library omissions.  To do this I defined two Application Helpers as follows:

&lt;pre&gt;&lt;code&gt;# Use accumulate_js to accumulate javascript paths throughout the application
# it deduplicates them and then they should be included by calling include_accumulated_js
# at the foot of the page.
def accumulate_js(key, path)
  @javascript_list ||= {} 
  @javascript_list[key] ||= []      

  if path.class == Array || path.class == String
    @javascript_list[key].&amp;lt;&amp;lt;(path)
    @javascript_list[key].flatten! # for some reason + was not working properly for arrays
    @javascript_list[key].uniq!
  else 
    raise ArgumentError
  end
  @javascript_list
end

# call accumulate_js first to use the default @javscript_list instance var
def include_accumulated_js(order_array, path_hash = @javascript_list)
  result = &quot;&quot;

  order_array.each do |key|
    next unless path_hash[key]
    result += path_hash[key].inject(&quot;&quot;) do |result, path|
      result += javascript_include_tag(path)
    end
  end
  result
end&lt;/code&gt;&lt;/pre&gt;

Then wherever Javascript is called for a request (layout, view, or partial) the names of the libraries are accumulated:

&lt;pre&gt;&lt;code&gt;accumulate_js(:core, [&quot;jquery-1.3.2.min.js&quot;, &quot;jquery-ui-1.7.1.custom.min.js&quot;])
accumulate_js(:plugins, &quot;beautytips/jquery.bt.min.js&quot;)
accumulate_js(:application, &quot;application&quot;)&lt;/code&gt;&lt;/pre&gt;

All load path strings from the public/javascripts directories are specified. The library order is maintained but additional loads are de-duplicated. Then all of the libraries are loaded at the foot of the document, ordered by type with a command like this:

&lt;pre&gt;&lt;code&gt;include_accumulated_js([:core,:plugins,:application,:page,:partial])&lt;/code&gt;&lt;/pre&gt;

For the specifics of what it does, here's the rspec spec:

&lt;pre&gt;&lt;code&gt;describe &quot;javascript library acuumulation&quot; do
  it &quot;accumulates javascripts associated with a specific key&quot; do
    accumulate_js(:core,[&quot;a&quot;,&quot;b&quot;])
    accumulate_js(:core,&quot;c&quot;).should == {:core =&gt; [&quot;a&quot;,&quot;b&quot;,&quot;c&quot;]}
  end

  it &quot;can accumulate a list of javascripts used on a web page&quot; do
    accumulate_js(:core, &quot;library.js&quot;)
    accumulate_js(:core, &quot;another/library.js&quot;).should == {:core =&gt; [&quot;library.js&quot;, &quot;another/library.js&quot;]}
  end

  it &quot;can take combinations of arrays and strings&quot; do
    accumulate_js(:foo, [&quot;lib1.js&quot;,&quot;lib2.js&quot;])
    accumulate_js(:foo, &quot;lib3.js&quot;)
    accumulate_js(:foo, [&quot;lib4.js&quot;,&quot;lib5.js&quot;]).should == {:foo =&gt; [&quot;lib1.js&quot;,&quot;lib2.js&quot;,&quot;lib3.js&quot;,&quot;lib4.js&quot;,&quot;lib5.js&quot;]}
  end

  it &quot;raises an error if it is of an unknown type&quot; do
    lambda do
     accumulate_js(:foo, 1)
    end.should raise_error(ArgumentError)
  end

  it &quot;deduplicates and preserves order&quot; do
    accumulate_js(:baz, [&quot;a&quot;,&quot;b&quot;,&quot;a&quot;,&quot;c&quot;,&quot;b&quot;,&quot;c&quot;]).should == {:baz, [&quot;a&quot;,&quot;b&quot;,&quot;c&quot;]}
  end
end

describe &quot;including accumulated javascript&quot; do
  before(:each) do
    accumulate_js(:foo, [&quot;foo_1&quot;,&quot;foo_2&quot;])
    accumulated = accumulate_js(:baz, [&quot;baz_1&quot;,&quot;baz_2&quot;])
    @result = include_accumulated_js([:baz, :foo], accumulated)
  end

  it &quot;returns javascript includes&quot; do
    @result.should =~ /script.*src.*javascripts\/baz_1.js.*type.*text\/javascript/ 
  end

  it &quot;includes javascripts in the specified order&quot; do
    @result.should =~ /baz_1.*baz_2.*foo_1.*foo_2/m
  end
  it &quot;can handle nil values&quot; do
    accumulated = accumulate_js(:foo, [&quot;foo_1&quot;,&quot;foo_2&quot;])
    lambda do
      include_accumulated_js([:baz, :not_in_there], accumulated)
    end.should_not raise_error
  end
end&lt;/code&gt;&lt;/pre&gt;

h2. Accolades

&quot;Marc Grabanski&quot;:http://marcgrabanski.com, excellent jQuery developer that he is, contributed his sage advice to this solution.

h2. Epilogue

I might put this in a plugin and post to github, but just seems a little silly since there are only two helper methods. What think ye? If this blog post is good enough for you, then it's good enough for me. Obviously, I'm busy enough that I've gone bonky and resorted to archaic english - but if you request a plugin or some other container I may be obliged.
          </content>  </entry>
  <entry xml:base="http://aquabu.com/">
    <author>
      <name>Noah</name>
    </author>
    <id>tag:aquabu.com,2009-06-25:353</id>
    <published>2009-06-25T23:40:00Z</published>
    <updated>2010-01-23T02:06:45Z</updated>
    <category term="Ruby"/>
    <category term="Ruby on Rails"/>
    <link href="http://aquabu.com/2009/6/25/ruby-value-to-boolean-method" rel="alternate" type="text/html"/>
    <title>Ruby Value To Boolean Method</title>
<content type="html">
            It's a common problem that does not seem to have a standard solution. Sometimes you need to coerce a value to a boolean (e.g. from a web form). Here's a simple implementation I wrote that handles common strings and numbers and gives flexibility in how to treat nils.


Here's the behavior we want:
&lt;pre&gt;&lt;code&gt;  describe &quot;#to_boolean&quot; do                                                                         
    it &quot;converts false values&quot; do                                                                   
      [&quot;no&quot;,&quot;false&quot;,false, &quot;0&quot;, 0].each do |value|                                                  
        to_boolean(value).should == false                                                           
      end                                                                                           
    end                                                                                             
                                                                                                    
    it &quot;converts true values&quot; do                                                                    
      [&quot;yes&quot;,&quot;true&quot;,true, &quot;1&quot;, 1].each do |value|                                                   
        to_boolean(value).should == true                                                            
      end                                                                                           
    end                                                                                             
                                                                                                    
    it &quot;is case insensitive for strings&quot; do                                                         
      to_boolean(&quot;YeS&quot;).should == true                                                              
      to_boolean(&quot;NO&quot;).should == false                                                              
      to_boolean(&quot;TruE&quot;).should == true                                                             
      to_boolean(&quot;FalSe&quot;).should == false                                                           
    end                                                                                             
                                                                                                    
    it &quot;converts nil to false by default&quot; do                                                        
      to_boolean(nil).should == false                                                               
    end                                                                                             
                                                                                                    
    it &quot;can return nil as nil&quot; do                                                                   
      to_boolean(nil, nil).should == nil                                                            
    end                                                                                             
                                                                                                    
    it &quot;converts unmatched strings to true&quot; do                                                      
      to_boolean(&quot;a string&quot;).should == true                                                         
    end                                                                                             
  end&lt;/code&gt;&lt;/pre&gt;

Here's the source code that satisfies the desired behavior:

&lt;pre&gt;&lt;code&gt;def to_boolean(value, nil_value = false)
  value.downcase! if value.class == String
  case value
  when &quot;no&quot;,&quot;false&quot;,false, &quot;0&quot;, 0
    false
  when &quot;yes&quot;,&quot;true&quot;,true, &quot;1&quot;, 1
    true
  when nil
    nil_value 
  else
    !!value
  end
end&lt;/code&gt;&lt;/pre&gt;
          </content>  </entry>
  <entry xml:base="http://aquabu.com/">
    <author>
      <name>Noah</name>
    </author>
    <id>tag:aquabu.com,2009-03-26:338</id>
    <published>2009-03-26T01:36:00Z</published>
    <updated>2009-03-26T01:42:26Z</updated>
    <category term="Ruby"/>
    <category term="Ruby on Rails"/>
    <link href="http://aquabu.com/2009/3/26/restful_authentication-and-rspec-rails" rel="alternate" type="text/html"/>
    <title>restful_authentication and rspec-rails 1.2.2 </title>
<content type="html">
            If you are getting something like this:
&lt;pre&gt;&lt;code&gt;Test::Unit::AssertionFailedError in 'SessionsController route generation should route the create sessions correctly'
The recognized options &amp;lt;{&quot;action&quot;=&gt;&quot;show&quot;, &quot;controller&quot;=&gt;&quot;sessions&quot;}&gt; did not match &amp;lt;{&quot;action&quot;=&gt;&quot;create&quot;, &quot;controller&quot;=&gt;&quot;sessions&quot;}&gt;, difference: &amp;lt;{&quot;action&quot;=&gt;&quot;create&quot;}&gt;
./spec/controllers/sessions_controller_spec.rb:108:&lt;/code&gt;&lt;/pre&gt;

You need to fix your restful_authentication specs to something like this (from my git diff):
&lt;pre&gt;&lt;code&gt;     it &quot;should map #edit&quot; do
-      route_for(:controller =&gt; &quot;assets&quot;, :action =&gt; &quot;edit&quot;, :id =&gt; 1).should == &quot;/assets/1/edit&quot; 
+      route_for(:controller =&gt; &quot;assets&quot;, :action =&gt; &quot;edit&quot;, :id =&gt; &quot;1&quot;).should == &quot;/assets/1/edit&quot; 
     end 

     it &quot;should map #update&quot; do
-      route_for(:controller =&gt; &quot;assets&quot;, :action =&gt; &quot;update&quot;, :id =&gt; 1).should == &quot;/assets/1&quot; 
+      route_for(:controller =&gt; &quot;assets&quot;, :action =&gt; &quot;update&quot;, :id =&gt; &quot;1&quot;).should == {:path =&gt; &quot;/assets/1&quot;, :method =&gt; :put}
     end &lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Essentially you need to change your == match to be a hash which includes a :method key. Also, numbers for the :id param should be quoted.&lt;/p&gt;


	&lt;p&gt;This will probably be fixed on the restful_authentication side since &lt;a href=&quot;http://github.com/dchelimsky/restful-authentication/commit/ad92c6cb52500c37ef81e30ac4e79adffc2f4d39&quot;&gt;David Chelimsky has posted a patch&lt;/a&gt; on github (thanks David!). But, if you created these specs with the restful_authentication generator you may want to just go in and change them yourself. Onward!&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://aquabu.com/">
    <author>
      <name>Noah</name>
    </author>
    <id>tag:aquabu.com,2008-11-20:321</id>
    <published>2008-11-20T07:22:00Z</published>
    <updated>2008-11-20T07:27:36Z</updated>
    <category term="Music"/>
    <link href="http://aquabu.com/2008/11/20/rabbit-s-rum-is-an-independent-music-awards-finalist" rel="alternate" type="text/html"/>
    <title>My Band Rabbit's Rum is an Independent Music Awards Finalist</title>
<content type="html">
            My music project &quot;Rabbit's Rum&quot;:http://www.rabbitsrum.com has just been nominated as an Independent Music Awards finalist. &quot;Check it out!&quot;:http://tinyurl.com/6mtzfh
          </content>  </entry>
  <entry xml:base="http://aquabu.com/">
    <author>
      <name>Noah</name>
    </author>
    <id>tag:aquabu.com,2008-11-04:320</id>
    <published>2008-11-04T19:04:00Z</published>
    <updated>2010-01-23T02:06:16Z</updated>
    <category term="Ruby"/>
    <category term="Ruby on Rails"/>
    <link href="http://aquabu.com/2008/11/4/activerdf-and-redland-up-and-running" rel="alternate" type="text/html"/>
    <title>ActiveRDF and Redland - Up and Running</title>
<content type="html">
            Conveniently the Redland libraries have been added to macports. To install them you will need to install both the Redland and Redland-Bindings library. In my case I installed them with the +ruby option although it's hard to tell if this is required given sparse documentation:

&lt;pre&gt;&lt;code&gt;sudo port install redland +ruby
sudo port install redland-bindngs +ruby&lt;/code&gt;&lt;/pre&gt;

Then to test that Redland is working it is recommended that you run the example.rb file. Since it's good to have the source around anyway you can get it from the Redland subversion repository here:
&lt;pre&gt;&lt;code&gt;svn export http://svn.librdf.org/repository/bindings/trunk/&lt;/code&gt;&lt;/pre&gt;

To run the example and make sure things are working, cd into the ruby directory and enter this per the &quot;Redland Ruby Binding instructions&quot;:http://librdf.org/docs/ruby.html :

&lt;pre&gt;&lt;code&gt;ruby -I. -Ilib example.rb file:../data/dc.rdf rdfxml&lt;/code&gt;&lt;/pre&gt;

You should get output like this:
&lt;pre&gt;&lt;code&gt;found statement: {[http://www.dajobe.org/], [http://purl.org/dc/elements/1.1/description], &quot;The generic home page of Dave Beckett.&quot;}
found statement: {[http://www.dajobe.org/], [http://purl.org/dc/elements/1.1/creator], &quot;Dave Beckett&quot;}
found statement: {[http://www.dajobe.org/], [http://purl.org/dc/elements/1.1/title], &quot;Dave Beckett's Home Page&quot;}
Parsing added 3 statements
Printing all statements
Statement: {[http://www.dajobe.org/], [http://purl.org/dc/elements/1.1/title], &quot;Dave Beckett's Home Page&quot;}
Statement: {[http://www.dajobe.org/], [http://purl.org/dc/elements/1.1/creator], &quot;Dave Beckett&quot;}
Statement: {[http://www.dajobe.org/], [http://purl.org/dc/elements/1.1/description], &quot;The generic home page of Dave Beckett.&quot;}
Querying for dc:titles:
{
  0= [http://www.dajobe.org/]
  1= Dave Beckett's Home Page
}
Serialized query results to JSON as a string size 296 bytes
Writing model to test-out.rdf as rdf/xml
Serialized to ntriples as a string size 292 bytes
Done&lt;/code&gt;&lt;/pre&gt;

Also you should have the test output in the test-out.rdf file. Something like this:
&lt;pre&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&amp;lt;rdf:rdf xmlns:rdf=&quot;http://www.w3.org/1999/02/22-rdf-syntax-ns#&quot; xmlns:dc=&quot;http://purl.org/dc/elements/1.1/&quot;&gt;
  &amp;lt;rdf:description rdf:about=&quot;http://www.dajobe.org/&quot;&gt;
    &amp;lt;dc:title&gt;Dave Beckett's Home Page&amp;lt;/dc:title&gt;
  &amp;lt;/rdf:description&gt;
  &amp;lt;rdf:description rdf:about=&quot;http://www.dajobe.org/&quot;&gt;
    &amp;lt;dc:creator&gt;Dave Beckett&amp;lt;/dc:creator&gt;
  &amp;lt;/rdf:description&gt;
  &amp;lt;rdf:description rdf:about=&quot;http://www.dajobe.org/&quot;&gt;
    &amp;lt;dc:description&gt;The generic home page of Dave Beckett.&amp;lt;/dc:description&gt;
  &amp;lt;/rdf:description&gt;
&amp;lt;/rdf:rdf&gt;&lt;/code&gt;&lt;/pre&gt;

Cool!

Next, lets setup ActiveRDF. If something goes wrong in your install or you want more information, the ActiveRDF install instructions are &quot;here&quot;:http://wiki.activerdf.org/GettingStartedGuide

Now, for ActiveRDF install these gems:
&lt;pre&gt;&lt;code&gt;sudo gem install activerdf --include-dependencies -y
sudo gem install activerdf_sparql
sudo gem install activerdf_redland&lt;/code&gt;&lt;/pre&gt;

Don't forget the activerdf_redland gem or you will get the error: unknown adapter redland

Enter this code from the ActiveRDF getting started &quot;guide&quot;:http://wiki.activerdf.org/GettingStartedGuide into a file called *active_rdf_demo.rb*:
&lt;pre&gt;&lt;code&gt;require 'rubygems'
require 'active_rdf'
adapter = ConnectionPool.add_data_source :type =&gt; :redland
adapter.load &quot;test_person_data.nt&quot;
Namespace.register :test, 'http://activerdf.org/test/'
ObjectManager.construct_classes

# we can access all RDF properties of a person as Ruby attributes:
 eyal = TEST::Person.new 'http://activerdf.org/test/eyal'
 puts eyal.age
 puts eyal.eye
 puts eyal.class

 # lets create an instance of one of the classes, that were constructed in that 
 # way armin will be of rdfs:type test:person
 armin = TEST::Person.new 'http://armin-haller.com/#me'

 # now lets search for something in the triple store
 all_resources = RDFS::Resource.find_all

 # print all the people, and their friends
 all_people = TEST::Person.find_all
 all_people.each do |person|
     puts &quot;#{person} has #{person.eye} eyes&quot; 
 end

 # find all people aged 27
 almost_thirties = TEST::Person.find_by_age(27)

 puts &quot;the following people are almost thirty: #{almost_thirties}&quot; &lt;/code&gt;&lt;/pre&gt;

Download the test data &quot;here&quot;:http://activerdf.org/data/test_person_data.nt and put it in the same folder as your active_rdf_demo.rb file.

Run active_rdf_demo.rb:
&lt;pre&gt;&lt;code&gt;ruby active_rdf_demo.rb&lt;/code&gt;&lt;/pre&gt;

You should get some output like this:
&lt;pre&gt;&lt;code&gt;27
blue
TEST::Person
&amp;lt;http: /&gt; has blue eyes
the following people are almost thirty: &lt;/code&gt;&lt;/pre&gt;

Congrats! ActiveRDF is now working with Redland using the Redland Ruby bindings.

Now if by chance you get this error next time you run script/server for a rails app:
&lt;pre&gt;&lt;code&gt;/opt/local/lib/ruby/vendor_ruby/1.8/rubygems/custom_require.rb:27:in `gem_original_require': no such file to load -- /opt/local/lib/ruby/gems/1.8/gems/activerdf-1.6.10/lib/activerdf/init.rb (MissingSourceFile)&lt;/code&gt;&lt;/pre&gt;

This is because some versions of the ActiveRDF gem (e.g. 1.6.10) do not have an init.rb file created. This is a bug. Here's how you can get around it (the directory to cd into will be the one from your error):
&lt;pre&gt;&lt;code&gt;sudo su
cd /opt/local/lib/ruby/gems/1.8/gems/activerdf-1.6.10/lib/
mkdir activerdf
touch activerdf/init.rb&lt;/code&gt;&lt;/pre&gt;
          </content>  </entry>
  <entry xml:base="http://aquabu.com/">
    <author>
      <name>Noah</name>
    </author>
    <id>tag:aquabu.com,2008-07-16:237</id>
    <published>2008-07-16T09:25:00Z</published>
    <updated>2010-01-23T02:10:23Z</updated>
    <category term="Ruby"/>
    <category term="Ruby on Rails"/>
    <link href="http://aquabu.com/2008/7/16/scruffy-ruby-gem-debugging" rel="alternate" type="text/html"/>
    <title>Scruffy Ruby Gem Debugging</title>
<content type="html">
            !http://www.aquabu.com/assets/2008/7/16/cast.jpg!

In the process of creating some graphs in ruby I decided to go upstream from ruport and use the scruffy gem directly. I made some discoveries along the way that touch on issues that could be encountered by various permutations of scruffy, macport, and rubygems users.

h2. A Storm Brewing

The first issue I encountered was this error:
&lt;pre&gt;&lt;code&gt;testing_scruffy.rb:2:Warning: require_gem is obsolete.  Use gem instead.
/opt/local/lib/ruby/vendor_ruby/1.8/rubygems.rb:304:in `report_activate_error': Could not find RubyGem Scruffy (&gt;= 0.0.0) (Gem::LoadError)
	from /opt/local/lib/ruby/vendor_ruby/1.8/rubygems.rb:238:in `activate'
	from /opt/local/lib/ruby/vendor_ruby/1.8/rubygems.rb:76:in `active_gem_with_options'
	from /opt/local/lib/ruby/vendor_ruby/1.8/rubygems.rb:61:in `require_gem'
	from testing_scruffy.rb:2&lt;/code&gt;&lt;/pre&gt;

This seems like a straightforward case of not installing the gem. However, in my case the the gem *was* installed and there was additional strange behavior: require 'scruffy' would load the library in irb but not from a script (even with require 'rubygems' before it).This seemed inconsistent because $LOAD_PATH (aka $:) variables were identical in irb and in the script. After investigating a number of possibilities I updated rubygems (which was at 0.9.4) to 1.2.0 and this seem to resolve the blatantly bizarre behavior.

You can check which version of ruby gems you are running with &quot;gem -v&quot;. If you are using macports you may have an older version of ruby gems, in which case you may find it useful to update rb-rubygems. Caveat emptor: dependent updates may also be installed - such as ruby. Here's how you can update your macport rb-rubygems library on OS X:

&lt;pre&gt;&lt;code&gt;sudo port upgrade rb-rubygems&lt;/code&gt;&lt;/pre&gt;

h2. Scruffy Needs A Shave

If you do upgrade ruby gems you may run into the another issue. With an updated version of ruby gems the require_gem method is obsolete. Because of this you may see the following error since scruffy 0.2.2 is not updated to use the *gem*  method instead of *require_gem*:

&lt;pre&gt;&lt;code&gt;NoMethodError: undefined method `require_gem' for main:Object
	from /opt/local/lib/ruby/gems/1.8/gems/scruffy-0.2.2/lib/scruffy.rb:18
	from /opt/local/lib/ruby/vendor_ruby/1.8/rubygems/custom_require.rb:32:in `gem_original_require'
	from /opt/local/lib/ruby/vendor_ruby/1.8/rubygems/custom_require.rb:32:in `require'
	from (irb):3&lt;/code&gt;&lt;/pre&gt;

I used the hack below to get around this and to avoid unpacking the gem in to my project directory for modifications. Once again caveat emptor - you may ultimately be better off unpacking (freezing) the gem into a local directory and including it in your application directly. Here's the hack which simply creates an alias to suspend the deprecation of the require_gem method indefinitely:

&lt;pre&gt;&lt;code&gt;require 'rubygems'
alias require_gem gem #later versions of gem use gem instead of require_gem
require 'scruffy'&lt;/code&gt;&lt;/pre&gt;

h2. Case Of The Missing Pie

Ah, but that's not all. It appears that tutorials and documentation are out of sync with the rubygem download... see example code at &quot;http://scruffy.rubyforge.org/&quot;:http://scruffy.rubyforge.org/ which suggests this usage (with my require hack at the top):

&lt;pre&gt;&lt;code&gt;require 'rubygems'
alias require_gem gem
require 'scruffy'

graph = Scruffy::Graph.new
graph.title = &quot;Favourite Snacks&quot;
graph.renderer = Scruffy::Renderers::Pie.new

graph.add :pie, '', {
      'Apple' =&gt; 20,
      'Banana' =&gt; 100,
      'Orange' =&gt; 70,
      'Taco' =&gt; 30
}

graph.render :to =&gt; &quot;pie_test.svg&quot;
graph.render :width =&gt; 300, :height =&gt; 200, :to =&gt; &quot;pie_test.png&quot;, :as =&gt; 'png'&lt;/code&gt;&lt;/pre&gt;

Running the sample code throws this error:

&lt;pre&gt;&lt;code&gt;test_scruffy.rb:7: uninitialized constant Scruffy::Renderers::Pie (NameError)&lt;/code&gt;&lt;/pre&gt;

Well, this error occurs because there is no such class as Scruffy::Renderers::Pie. It's not in the docs and if you do grep -r &quot;pie&quot; . from within the scruffy-0.2.2 folder it comes up with nothing that would lead to the creation of such a class. FYI, the docs are visible online here &quot;http://scruffy.rubyforge.org/doc/&quot;:http://scruffy.rubyforge.org/doc/

Well, it's hard to use a class that doesn't exist. It appears that this may be present in scruffy 0.2.3 released on July 13th - but as of this writing it's not downloaded via sudo gem update scruffy. If you need this and it it is not yet available through ruby gems - you may need to do a manual install. In the mean time let's try something else instead.

h2. Steady Into Port (Mind The Wireshark)

&lt;pre&gt;&lt;code&gt;graph = Scruffy::Graph.new
graph.title = &quot;Sample Line Graph&quot;
graph.renderer = Scruffy::Renderers::Standard.new

graph.add :line, 'Example', [20, 100, 70, 30, 106]

graph.render :to =&gt; &quot;line_test.svg&quot;
graph.render  :width =&gt; 300, :height =&gt; 200, :to =&gt; &quot;line_test.png&quot;, :as =&gt; 'png'&lt;/code&gt;&lt;/pre&gt;

Well if you have RMagick installed that may have worked for you. If not you will need to make sure rmagick is installed. On my machine I had to remove some dependencies before reinstalling tiff with different compilation options. Here are the commands I ran. You will probably have different dependencies, so know what you are doing. Don't just blindly run these commands or you may uninstall something you need:

&lt;pre&gt;&lt;code&gt;sudo port uninstall wireshark
sudo port uninstall gtk2
sudo port uninstall tiff @3.8.2_1+macosx
sudo port install tiff -macosx imagemagick +q8 +gs +wmf
sudo gem install rmagick&lt;/code&gt;&lt;/pre&gt;

Note that installing and compiling rmagick took several minutes. I would suggest looking at the &quot;rmagick installation page&quot;:http://rmagick.rubyforge.org/install-osx.html if you need to install this. 

At this point you should be able to output your svg and png files.

h2. Conclusion
 
Careful, or due to &quot;environmental conditions&quot; you could set out expecting a simple three hour tour happily outputting beautifully rendered svgs as you sail effortlessly through graph land; but instead, end up whistling along sympathetically to the Gilligan's Island theme song as you set ground on the shore of an uncharted desert isle. Hopefully this will help you through some of the things you may run into, and you can have a smooth sail enjoying scruffy.
          </content>  </entry>
  <entry xml:base="http://aquabu.com/">
    <author>
      <name>Noah</name>
    </author>
    <id>tag:aquabu.com,2008-06-18:233</id>
    <published>2008-06-18T17:42:00Z</published>
    <updated>2008-06-18T17:42:49Z</updated>
    <category term="Ruby"/>
    <category term="Ruby on Rails"/>
    <link href="http://aquabu.com/2008/6/18/proc-new-lambda-and-proc" rel="alternate" type="text/html"/>
    <title>Proc.new, lambda, and proc</title>
<content type="html">
            In response to the &quot;harmony of thought posting on good ruby interview questions&quot;:http://blog.ritirisi.com/2008/06/17/15-questions-to-ask-during-a-ruby-interview I wrote the following (posted here for interest and to preserve formatting)...

One thing about lambdas and procs. Even though they appear to be the same class they do not behave completely the same. From running my_lambda.inspect and seeing the Proc instance you would never guess it but they are different.

Essentially lambda and Proc.new handle arguments and the &quot;return&quot; statement differently. Also the &quot;proc&quot; method returns a lambda not a Proc.

Here's some code to prove the point. The argument handling is the easiest to demo:

&lt;pre&gt;&lt;code&gt;my_proc = Proc.new {|x,y| print x,y}
my_lambda = lambda {|x,y| print x,y}
my_other_proc = proc {|x,y| print x,y}

# pass in one variable instead of 2
my_proc.call(1) #this doesn't throw an error and sets y to nil
my_lambda.call(1) #this throws an error
my_other_proc.call(1) #this throws an error like a lambda because it actually is a lambda not a proc in ruby 1.8.6&lt;/code&gt;&lt;/pre&gt;

Also in Ruby 1.9 I think that the &quot;proc&quot; method (as seen in line three) will actually return a Proc and not a lambda. Ruby 1.9 will also add a &quot;lambda?&quot; method for you to clarify the difference between a Proc and a lambda.

O'Reilly's book &quot;The Ruby Programming Language&quot; by Matz (Yukihiro Matsumoto) and David Flanagen has a great chapter on this.
          </content>  </entry>
  <entry xml:base="http://aquabu.com/">
    <author>
      <name>Noah</name>
    </author>
    <id>tag:aquabu.com,2008-06-13:232</id>
    <published>2008-06-13T23:43:00Z</published>
    <updated>2008-06-16T21:44:32Z</updated>
    <category term="Class &amp; Event Notes"/>
    <link href="http://aquabu.com/2008/6/13/hosting-and-the-woes-engine-yard-panel" rel="alternate" type="text/html"/>
    <title>Railsconf 2008 Scribblings: Hosting and the Woes (Engine Yard Panel)</title>
<content type="html">
            5/30/2008, 11:45AM, Portland, OR&lt;br /&gt;

Here are some of my notes from Railsconf 2008. Warning these notes are only vaguely edited (but arguably still useful). There are certainly typos and errors. If executing code from one of these articles, your mileage may vary (from spontaneous self destruction of everything you know and love to spontaneous coolness). Also, you may want to double check â€œfactsâ€. You definitely should not use these articles as a spelling reference. Feel free to post corrections.

Engine Yard Panel:
* Tom Mornini - CTO
* Taylor Weibley - Application Support Director
* Edward Muller - Automation Manager (fluent in binary)
* Ezra Zygomowitz -  System Architect
* Jamie van Dyke

Problems they have had and how they solved most of them. Then questions and answers.

h2. Main problem with rails is active_record

Great for quickly building with RESTful resources. But...
* find(:all).each do |leak|
* testing is usually with 20 records.
* no indexes.

Engineyard has a team of SQL guys to optimize in this area. 

One of the first problem they noticed that you need indexes on all foreign keys. If you don't have them they are full table scans. Migrations automatically index ids but not foreign keys. Basically anything that ends with _id needs an index. There may be some database experts that will disagree but this is not usually the case. Use explain in mysql /G to make sure that the indexes are being used in the queries. Take a look at the new Relic optimization stuff it's super cool.

h2. Plugins that give common problems

* Most common and hated plugin is ferret. Indexes grow past 1G and indexes frequently corrupted. Use sphinx instead. Sphinx will just update indexes on the delta.
* Image Science uses ruby inline which needs environment variables to be set. Can be used perfectly in development and then when they shift to production monit clears those variables out. Not a huge problem but you should be aware of it.
* Hodel 3000 loggers default is a verbose logging tool and it can generate huge log files. Adjust settings. Logging should be set to info.

h2. How much traffic can you take?

*Depends on coding* 

General stats:
* Digg 10,0000+ visitors and 1% signup. What should you do? Cache it. At engine yard a slice could handle this quite easily. Customers are often concerned with this sudden out of the blue Digg or TechCrunch. But in reality you usually are and there is no surprise. Makes it so you can be ahead of the curve.
* TechCrunch 1000+ visitors but they are more interested in what you are doing.
* Ruby Inside / Flow 500 - 1000 visitors a day, also don't get many sign ups. It's more about what can the visitor do.
* The Today Show - 100,000+ visitors in the first hour or so. Can get up to 10,000 signups in the first couple hours. You will have advance warning which is great.
* Fox Business - 2000+ connections.

h2. How many queries can your site take? 

It depends on code.
* Queries per page
* But you should cache!
* Best way to handle hike in traffic is cache / memcache
* Keep file input output down as low as possible
* Separate out to different disks, you don't want simultaneous reads and writes

h2. Deployment

Lots of customers not up to speed on Capistrano, git / subversion. Engine yard gives deploy.rb (shameless plug from them :-)
gem source - a http://www.engineyard.com ... Includes cap examples list of extra tasks - loads of things that it can do.

h2. ebb | mongrel | thin. Which do customers prefer?  

Alternatives to mongrel are possible but not necessarily production ready (ebb). Don't need to be super concerned about it unless you are doing 1,000 hits per second. The bottleneck is usually the user code, this is far more relevent. That said, thin may be 13% faster but you need to be in the top 5% of internet traffic for this to matter.

h2. Audience Q&amp;A

What happened with NGINX?
You haven't heard about much new because it's in use and it just works. They haven't really had any problems with NGINX. Some minor issues but they have been ironed very quickly. They have seen 40MB/sec of static images served and not show up top command.

Interpreters?&lt;br /&gt;
Rubinius and Modrubinius are going to be the way to go in the future.

Thin instead of mongrel because of lower memory footprint?&lt;br /&gt;
There are a lot reasons to save memory but mongrel is a minor concern. More than 3-4 mongrels per CPU is pointless. The bottleneck is file io rather than memory. A common misconception is that you need more mongrels. Thin tends to backup processes more than mongrel. It is important to watch the real behavior of the app because every app uses resources differently.

Should static files be local or shared across cluster?&lt;br /&gt;
Cluster is fine @ Engine Yard, but depends on file system. NFS was cool in 1979...

How to handle asynchronous background processes?&lt;br /&gt;
Background Job (BJ) is pleasurable to work with. Written by NGINX.

Do you leave keep alive with NGINX?&lt;br /&gt;
Untested. But historical use with apache pre-rails was not succesful.

Seperate server for search workload? How should resources be distributed across server farm and how does this map to virtualization?
Engine Yard are strong believers of virtualization. Intended from earlier on to only have virtualized servers. The more that they have gotten involved in it they have discovered that if you have a well built virtualization environment you quickly get the sense that you are operating on separate machines. NGINX, 3 Mongrels, and an memcache per instance. If you have a solid architecture you could have databases on multiple instances. Single server rack at engine yard with 18 servers would run bottom 97% of all internet apps. There's huge CPU capacity in a virtualization environment. CPUs are not typically the bottleneck (unless you are doing fluid dynamic calculations).

What is the Engine Yard uptime?&lt;br /&gt;
3-4 9s up time. Rack Space rates using a questionable rating system.
          </content>  </entry>
  <entry xml:base="http://aquabu.com/">
    <author>
      <name>Noah</name>
    </author>
    <id>tag:aquabu.com,2008-06-13:231</id>
    <published>2008-06-13T23:26:00Z</published>
    <updated>2008-06-13T23:27:53Z</updated>
    <link href="http://aquabu.com/2008/6/13/maglev-ruby-that-scales-talk-with-avi-bryant-and-bob-walker" rel="alternate" type="text/html"/>
    <title>Railsconf 2008 Scribblings - MagLev: Ruby That Scales</title>
<content type="html">
            Talk with Avi Bryant and Bob Walker&lt;br /&gt;
5/30/2008, 3:40PM, Portland, OR&lt;br /&gt;

Here are some of my notes from Railsconf 2008. Warning these notes are only vaguely edited (but arguably still useful). There are certainly typos and errors. If executing code from one of these articles, your mileage may vary (from spontaneous self destruction of everything you know and love to spontaneous coolness). Also, you may want to double check &quot;facts&quot;. You definitely should not use these articles as a spelling reference. Feel free to post corrections.

MagLev is rails that go fast. Typically have mongrel cluster talking to storage device and memcache instance for each server. Maglev unifies this stack: Storage, Cache, and Ruby

Example:
&quot;Ordinary ruby shells&quot;. Two terminals using the same shared objects! You can do this for any number of boxes across the entire system.
Local state is not shared, global variables ($hat).

Ruby shell has transactions as you are used them. Transactions are there for mutable state.Commits don't only go to in memory caching, they go to disk and if there is a failure then the machines can be rebooted with the existing state. Could this be on multiple machines? Yes. The storage can be greater than ram because they can be persisted to disk.

The system does not currently run rails, but it will be soon. Can currently run webrick with hello world.

Question: Is the ruby spec implemented and at what level?
Next phase is implementing the ruby specs against this.

Question: What happens to files and sockets?
Each VM will have it's own seperate copy of that resource and they will be nil'ed out when brought over.

Question: Is this a written from scratch ruby machine?
Yes, it is not MRI.

Gemstone founded in 1982 in Portland.
* Cretated GemStone smalltalk
* Enterprise proven technology
* Production systems deployed worldwide
* Support domains that are not well served by relational database systems

* Worldwide container
* Intelligence
* Telecom
* Etc.

MagLev
* 1 dual core up to really large systems
* Mutliple ruby virtual machines
* Oject Caches/Repository
* Transactional
* Distributed
* Scalable

They are currently 100 days into the implementation process.
* Dynamic Language VM
* Based on Gemsone/s 64VM
* Well tuned garbage collection
* Extended with new byte codes for Ruby
* JIT native code generation

Object Caching
* Shared caching uses shared memory
* Repository objects are read into the cache
...

Transactional
* Fully recoverable ACID Transactions
* Simple API
* Conflict management

Persistence
* Transparent
* Native Language
* Simple API
* You can store a trillion instances
* Up to 17PB

Benchmarks
* bm_so_exceptions 5.6 x faster than MRI
* fib 12.5 x MRI
* vm2 method 24 x MRI
* bm_so_sieve 68.4 times
* bm_loop_whileloop2 111.5 x MRI
&quot;Holy Shit&quot; -Antonio Gangiano (Great Ruby Shootout)
Numbers will be independently verified shortly.

Audience question. What is missing from Ruby that will decrease this performance?
The plan is ruby spec and core library.

But does it scale?
Yes.

What's the vision?
Rails - taking it to a different level of scalability.

What Else?
* Open Community Involvement
* Ruby Spec Compliance
* MagLev Ruby open source
* Free version of MagLev will be feature limited for small to medium scale
* Info @ maglev.gemstone.come

A lot of rails makes use of the relational database structure and indices. Will Maglev address these?
Yes. And you will be able to make your queries in the native language. Will likely clone the API but run gemstone underneath.

Continuations?
Yes. They are supported in smalltalk.

How to optomize? Will it be a linear scan?
Gemstone does will do an linear scan for a basic select but gemstone does have various indexing.

Will the Gemstone VM be open sourced (asked by Charles Nutter from jRuby team):
Bob: &quot;In a world of infinite possibilities it's possible.&quot;

Will existing extensions in C be possible to integrate?
Not currently. Rubinius has done some good work in this area and it may be possible to use a similar approach for Gemstone. C extensions may not be necisary in certain cases.

However rails depends on C like BigDecimal(Wilson)?
Will solve those problems when they get to them.

ActiveRecord uses SQL fragments. How would that work since it's not part of ruby?
To port a rails app may require getting rid of optomizations done in sql.... this is an area where feedback will be welcome. This is yet to be designed built.

Which pieces are open source?
All of the stuff at the ruby level is hopefully to be shared with Rubinius. ActiveRecord API will be. But as for the underlying VM Bob answered that earlier (e.g. &quot;in a world of infinite possiblities....&quot;).

Is the persistent store distributable?
More like typical SQL statement. Master slave replication...

How is the VM implemented?
In short... in C.

When is going to be ready?
Pay attention to what we are doing. More info in September.
          </content>  </entry>
  <entry xml:base="http://aquabu.com/">
    <author>
      <name>Noah</name>
    </author>
    <id>tag:aquabu.com,2008-06-13:230</id>
    <published>2008-06-13T23:17:00Z</published>
    <updated>2008-06-13T23:17:47Z</updated>
    <category term="Class &amp; Event Notes"/>
    <link href="http://aquabu.com/2008/6/13/railsconf-2008-scribblings-joel-spolsky-keynote" rel="alternate" type="text/html"/>
    <title>Railsconf 2008 Scribblings: Joel Spolsky (Keynote)</title>
<content type="html">
            5/30/2008, 9:15am, Portland, OR

Here are some of my notes from Railsconf 2008. Warning these notes are only vaguely edited (but arguably still useful). There are certainly typos and errors. If executing code from one of these articles, your mileage may vary (from spontaneous self destruction of everything you know and love to spontaneous coolness). Also, you may want to double check &quot;facts&quot;. You definitely should not use these articles as a spelling reference. Feel free to post corrections.

Intro by DHH on Joel:
* Joel is author of Joel On Software
* Generated programming language to generate other programming language
* fighting complexity (anti-architect astronaut)

h2. Joel's Talk Begins...

Why does Brad Pitt make so much more money and have a bigger brand than Ian Somerhalder?
What becomes &quot;blue chip software&quot; rather than off brand?

Herman Miller Aeron Chair was the bluechip chair. All types of people make clones.
Clones didn't have market share. This happens in every field.
Happens in music as well.

Great software has three components that make them blue chip:
* Make people happy
* Obsess over aesthetics
* Observing the culture code

h2. Make People Happy (Agency)

[Very funny example about logging in to windows to post a photo and then having to install windows downloads and then use original install a file from the insert original install disk. In a word you feel enslaved (you are not in control of the process)]

Martin Seligman pioneering psychologist of &quot;Learned Helplessness&quot; liked to study happy people which is rare amongst psychologists. 

Example: Someone dies &gt; you are stuck in bed depressed &gt; you loose your job and that you begin to believe that you lack agency and then you begin to teach yourself that you are helpless. Seligman's strategy was to teach people that they have power over there environment through tricking the brain into a virtuous cycle of having agency (initially through accomplishment of simple tasks).

Abercrombie ecommerce checkout forces you through 4 pages. Amazon gives you all the options at once (change address, shipping options, etc). This is Joel's first example of giving the user agency.

Make people happy by putting them in control (speed of response is also important here - the business case for AJAX).

h2. Obsess over aesthetics

Samsumg Blackjack vs iPhone.
* Blackjack faster
* iphone bricks if you install third party software
* Blackjack ugly &amp; iphone is seamless and shiny (if you accidentally swallowed one it would go right down)
* Blackjack replaceable battery - iphone doesn't (avoids the non aesthetic seam). Another example is looking at the bottom of the MacBook vs. thinkpad.

Apple design decisions are about fashion. Another example is a historical Paris apartment building in Paris has no fire escapes. It turns out fire escapes are zoned, but the appartment buildings are reclasified as monuments and they are not inspected. This is another example of taking aesthetics as more important than core functionality.

Programers call this lipstick and say I want to work in the guts (the 90% of the iceberg below the surface). But it turns out that aesthetics are very important. To programmers it is not clear why artists such as Basquaiat etc. sell paintings for $50+ million. Specifically programmers don't get modernist architecture.

Modernist principles remove all decoration from architecture. There is a parallel here between the programers gravitation to the command line vs. glossy operating systems.

h2. The Culture Code

Example: the promotion of sport utility vehicles.
Deaths per million cars:
* Toyota Camry 41
* Ford Explorer 88

This has to do with a number of factors. But you feel safe in these vehicals. This has to do with promotion (see the culture code).
* Everything around you should be round and soft
* You should be up high (on the reptilion level if you feel tall you feel you are dominating)
* Key element of safety as a child is being fed if everything is round, soft, high, and you feel fed (cupholders) you feel safe.

Another example like this is the word &quot;Enterprise&quot;. Recalls tokyo at night, a clean server room, the starship enterprise, people in clean business suits looking up(image).

Another example is Web 2.0. Lots of logos. They don't have visions they go to parties... etc. Why the luck stiff :-) 
How could beauty, happiness, motivation, pride, pleaseure, enthusiasm be involved in coding.
Very funny counter examples for python and java go here...

This all boils down to Misattribution. You have a physical reaction and you think that it has something to do with the mental plane but it doesn't. People on the right hand side of the movie have 10% greater ratings than the left.
          </content>  </entry>
  <entry xml:base="http://aquabu.com/">
    <author>
      <name>Noah</name>
    </author>
    <id>tag:aquabu.com,2008-05-27:198</id>
    <published>2008-05-27T07:55:00Z</published>
    <updated>2008-05-29T06:21:38Z</updated>
    <link href="http://aquabu.com/2008/5/27/installing-vim-with-ruby-or-enable-rubyinterp-on-os-x-10-5-2" rel="alternate" type="text/html"/>
    <title>Installing vim with +ruby or --enable-rubyinterp on OS X 10.5.2</title>
<content type="html">
            The problem: When installing vim from source with --enable-rubyinterp option you are receiving numerous unsolvable errors (such as ncurses cannot be found when it is installed and you are directing ./configure to it using --with-tlib ncurses). Or, you are trying to install vim +ruby using MacPorts and you are getting similar errors. 

The solution: install vim using MacPorts and install Ruby first.
&lt;pre&gt;&lt;code&gt;sudo port install ruby
sudo port install vim +ruby +huge&lt;/code&gt;&lt;/pre&gt;

Newly installed version is in /opt/local/var/macports/software/vim/7.1.270_0+huge+ruby/opt/local/bin

After launching this version of vim it responds to:
&lt;pre&gt;&lt;code&gt;:ruby puts &quot;hello world!&quot;&lt;/code&gt;&lt;/pre&gt;

If you have the following in your .bash_profile or .profile file and you reopen your terminal, the newly installed MacPort will take precedence over the default OS X install of vim:
&lt;pre&gt;&lt;code&gt;export PATH=/opt/local/bin:/opt/local/sbin:$PATH&lt;/code&gt;&lt;/pre&gt;

Note that having your MacPort ruby install take precedence over your default ruby installation can modify your environment. Particularly, it may cause ruby to look for a different gem library. You can verify you are using the correct configuration by checking your gem path, version, and gems that you have installed:
&lt;pre&gt;&lt;code&gt;which gem
gem -v
gem list --local&lt;/code&gt;&lt;/pre&gt;

If your MacPorts gem version is taking precedence over other gem libraries that you would prefer to use, you can modify the file name or remove the version of the gem that you do not want to use. It is likely that MacPorts is referencing /opt/local/bin/gem and you would like it to reference /usr/bin/gem.
          </content>  </entry>
  <entry xml:base="http://aquabu.com/">
    <author>
      <name>Noah</name>
    </author>
    <id>tag:aquabu.com,2008-02-16:13</id>
    <published>2008-02-16T20:00:00Z</published>
    <updated>2009-10-22T01:31:24Z</updated>
    <category term="Erlang"/>
    <link href="http://aquabu.com/2008/2/16/fibonacci-sequence-recursion-in-erlang" rel="alternate" type="text/html"/>
    <title>Fibonacci Sequence Recursion in Erlang</title>
<content type="html">
            Erlang uses recursion extensively - so lets do some classic &quot;Fibonacci sequence&quot;:http://en.wikipedia.org/wiki/Fibonacci_number recursion code katas for Erlang. Note, that I define things a little differently than the Wikipedia example I just linked to. In the algorithms below, I have defined the first first two elements as = 1 and there is no N defined for 0. So: fib(1) = 1, fib(2)=1, and fib(N) where N &gt; 2 = fib(N -1) + fib(N - 2).

For fun, lets try a few different algorithmic approaches to this sequence. The classic example of Fibonacci sequence recursion is a literal representation of the algorithm, which ends up being rather computationally intensive. It looks rather elegant but starts getting massively slow around N = 35. This is because N is recomputed recursively every time it is used!

&lt;pre&gt;&lt;code&gt;fib_slow(1) -&gt; 1;
fib_slow(2) -&gt; 1;
fib_slow(N) -&gt; fib_slow(N-1) + fib_slow(N-2).&lt;/code&gt;&lt;/pre&gt;

Here's an example of a different algorithm, where each value is accumulated in a list and looked up rather than recomputed. There also is a io:format print statement that returns the final sequence of N numbers. This method is a lot faster than the inefficient version above. You can set N = 1,000 without much fuss. If you comment out the print statement you can get to N = 20,000 speedily.

&lt;pre&gt;&lt;code&gt;fib_list(1) -&gt; io:format(&quot;~p~n&quot;,[[1]]);
fib_list(2) -&gt; io:format(&quot;~p~n&quot;,[[1,1]]);
fib_list(N) when N &gt; 2 -&gt; 
	hd( fib_list1(N-1,[1,1]) ).

% delegate for numbers greater than 2
fib_list1(1,L) -&gt;
	io:format(&quot;~p~n&quot;,[lists:reverse(L)]),
	L;
fib_list1(N,L) -&gt;
	[H1,H2|_T] = L,
	fib_list1(N-1,[H1 + H2 | L]).&lt;/code&gt;&lt;/pre&gt;

The final method computes the value but does not store it in a list. This one is the fastest (although I have not benchmarked them). This method also eliminates the risk of filling up memory with the list of previous numbers. N = 50,000 breezes by with this algorithm on my 2.2 Ghz Intel Dual Core MacBook Pro.

&lt;pre&gt;&lt;code&gt;fib(1) -&gt; 1;
fib(2) -&gt; 1;
fib(N) when N &gt; 2 -&gt; fib1(N,1,1).

fib1(3,P1,P2) -&gt; P1 + P2; 
fib1(N,P1,P2) -&gt;
	fib1(N-1,P2, P1 + P2).&lt;/code&gt;&lt;/pre&gt;

Here are all of the different approaches (in reverse orer) in a module.

&lt;pre&gt;&lt;code&gt;-module(fib2).
-compile(export_all).
% get nth fibonacci no storage
% quite fast, get's nth number with no list storage

test() -&gt;
	13 = fib(7),
	13 = fib_list(7),
	13 = fib_slow(7),
	horray.

fib(1) -&gt; 1;
fib(2) -&gt; 1;
fib(N) when N &gt; 2 -&gt; fib1(N,1,1).

fib1(3,P1,P2) -&gt; P1 + P2; 
fib1(N,P1,P2) -&gt;
	fib1(N-1,P2, P1 + P2).
	
% fib sequence made by accumulating values in a list
% pretty fast even at N = 20,000.
fib_list(1) -&gt; io:format(&quot;~p~n&quot;,[[1]]);
fib_list(2) -&gt; io:format(&quot;~p~n&quot;,[[1,1]]);
fib_list(N) when N &gt; 2 -&gt; 
	hd( fib_list1(N-1,[1,1]) ).

%delegate for numbers &gt; 2
fib_list1(1,L) -&gt;
	io:format(&quot;~p~n&quot;,[lists:reverse(L)]),
	L;
fib_list1(N,L) -&gt;
	[H1,H2|_T] = L,
	fib_list1(N-1,[H1 + H2 | L]).

% ineficient recursive method for fibonacci computation
% very slow at N = 35
fib_slow(1) -&gt; 1;
fib_slow(2) -&gt; 1;
fib_slow(N) -&gt; fib_slow(N-1) + fib_slow(N-2).&lt;/code&gt;&lt;/pre&gt;
          </content>  </entry>
  <entry xml:base="http://aquabu.com/">
    <author>
      <name>Noah</name>
    </author>
    <id>tag:aquabu.com,2008-02-15:12</id>
    <published>2008-02-15T19:07:00Z</published>
    <updated>2008-02-16T19:08:18Z</updated>
    <category term="Class &amp; Event Notes"/>
    <category term="Erlang"/>
    <link href="http://aquabu.com/2008/2/15/erlang-pragmatic-studio-day-3-notes" rel="alternate" type="text/html"/>
    <title>Erlang Pragmatic Studio - Day 3 Notes</title>
<content type="html">
            &lt;p&gt;Erlang Pragmatic Studio with Joe Armstrong &#38; Dave Thomas &#8211; Chicago, Feb 13-25, 2008.&lt;/p&gt;


	&lt;h2&gt;Day 3 &#8211; Feb 14,2008.&lt;/h2&gt;


	&lt;p&gt;Here are my notes from Day 3 of the Pragmatic Studio Erlang course. Note that these notes are only vaguely edited. Be aware that these are notes so there are certainly typos and errors.&lt;/p&gt;


	&lt;h2&gt;Beginning of the Day&lt;/h2&gt;


	&lt;p&gt;Always good to develop from the specific to the general. e.g. make a simple app, then parameterize it with functions. Universal server that evaluates F is a very powerful generalization of a specific application (e.g. messaging).&lt;/p&gt;


can send a message to your self:
&lt;pre&gt;&lt;code&gt;self ! a. % Could tie into recursion&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;a lot of users
Erlang guru&#8217;s (tailf, Kredita) don&#8217;t use &lt;span class=&quot;caps&quot;&gt;OTP&lt;/span&gt;, as they participated in the &lt;span class=&quot;caps&quot;&gt;OTP&lt;/span&gt; creation. But if you build up the Gen server from incremental steps, you may find it not so difficult. The question is, does &lt;span class=&quot;caps&quot;&gt;OTP&lt;/span&gt; really fit the problem at hand.&lt;/p&gt;


	&lt;p&gt;If you do spawn_link from the shell, report errors back to the shell.&lt;/p&gt;


	&lt;p&gt;erl -bootstart sasle % spelling system application support library. Get error logger and a few other items.&lt;/p&gt;


	&lt;p&gt;sasle libraries were added into Erlang at a later date for historical reasons.&lt;/p&gt;


	&lt;h2&gt;Bit Syntax&lt;/h2&gt;


In ruby or other languages would be fairly tedious (ands, ors, bitshifts, etc). Erlang has a high level syntax that lets you specify the structure of binary data.
&lt;pre&gt;&lt;code&gt;Red = 2, Green=61, Blue=20.
=&gt; 20
Bin = &amp;lt;&amp;lt;red:5&gt;&gt;
=&gt; &amp;lt;&amp;lt;23&gt;&gt;
io:format(&quot;~8.2.0B~8.2.0b~n&quot;, binary_to_list(Bin)).
=&gt; 00010111 10110100&lt;/code&gt;&lt;/pre&gt;

	&lt;h2&gt;Bit Twiddling History:&lt;/h2&gt;


	&lt;p&gt;Erlang had lots of protocols internally in Erickson. Decided to implement every &lt;span class=&quot;caps&quot;&gt;RFC&lt;/span&gt; &#8211; but was too difficult. Lots of bit twiddling. Because of this they made a sub-language for doing this bit-twiddling so that this was implement any protocol. Optimal and efficient unpacking of datastructures.&lt;/p&gt;


	&lt;p&gt;1/3rd of details were in the Erlang book. The rest needs to be found in the man pages.&lt;/p&gt;


	&lt;p&gt;There are also bit comprehensions &#8211; generators of bit stream. Good for huffman encodings, &lt;span class=&quot;caps&quot;&gt;MIPS&lt;/span&gt; processing, etc. Very efficient. This is in the experimental phase but will be integrated into the system. Undocumented items are not official and may be changed. Once the docs are written it&#8217;s official.&lt;/p&gt;


	&lt;p&gt;Erlang mailing list erlang.org &amp;gt; FAQs and mailing lists.&lt;/p&gt;


	&lt;p&gt;Book page 86 great shoutcast server for distributed audio. There is an excercise for bit processing, but we are skipping it in the interest of time.&lt;/p&gt;


	&lt;h2&gt;file at a time I/O&lt;/h2&gt;


	&lt;p&gt;Reading file at at time is about 10-20 times faster than reading line at a time. Erlang is not as efficient as some other languages for string matching. Use [H|T] to parse. Only multi-gig pattern are difficult for this. binary input and output is definitely fastest.&lt;/p&gt;


	&lt;p&gt;file:consult(File) -&amp;gt; {ok, Term} | {error, Why}&lt;/p&gt;


Term Access &#8211; read configuration file
&lt;pre&gt;&lt;code&gt;-module(test4).
-
read_config() -&gt;
    {ok,[{host,Host,port,Port}]} = file:consult(...)
    ...&lt;/code&gt;&lt;/pre&gt;

Term IO
	&lt;ul&gt;
	&lt;li&gt;inefficient&lt;/li&gt;
	&lt;/ul&gt;


&lt;pre&gt;&lt;code&gt;io:read('enter a term').
enter a term &gt; {hello, &quot;joe&quot;}
io:get_line(...) %read from a shell

erl_scan:string(&quot;abc,123,{hello,joe}&quot;). % turn into erlang tokens - very efficient
% written with explicit recursion that is more efficient than regex

file:pread ...&lt;/code&gt;&lt;/pre&gt;

map onto standard file manipulations:
&lt;pre&gt;&lt;code&gt;file:list_file(Dir)
file:delete()
...

filename:split(FileName) =&gt; [Component]&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;DNS&lt;/span&gt; servers are actually fairly easy. In a real &lt;span class=&quot;caps&quot;&gt;DNS&lt;/span&gt; server there is tree walking for the sub-domain, domain, and tld xxx.xxxx.xxx&lt;/p&gt;


	&lt;p&gt;lots of &lt;span class=&quot;caps&quot;&gt;DNS&lt;/span&gt; servers have interesting traffic patterns&#8230; tie ins with advertising sites, etc.&lt;/p&gt;


	&lt;p&gt;Erlang doesn&#8217;t link code into it&#8217;s Kernal. Need to establish a socket for C libs. Send messages using binary.&lt;/p&gt;


Orientation:
	&lt;ul&gt;
	&lt;li&gt;nodes &#8211; when you say erl it starts a node. Doesn&#8217;t register this node by default.&lt;/li&gt;
		&lt;li&gt;distributed erlang consists of a number of nodes that know about eachother.&lt;/li&gt;
		&lt;li&gt;&lt;span class=&quot;caps&quot;&gt;SMP&lt;/span&gt; takes advantage of multi-core &#8211; this is not distributed Erlang&lt;/li&gt;
		&lt;li&gt;Socket distribution &#8211; is also not distributed Erlang&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;same network:
erl -sname %short name
erl -name % different names&lt;/p&gt;


	&lt;p&gt;There is a magic cookie that they must share. Simple challenge request, traffic is not encrypted. Can communicate over &lt;span class=&quot;caps&quot;&gt;SSH&lt;/span&gt;. DNS and name recognition systems are often poorly configured and this causes some difficulties for setting up distributed erlang apps. There are som FAQs on debugging distributed Erlang.&lt;/p&gt;


Three new primitives:
	&lt;ul&gt;
	&lt;li&gt;spawn(Node, Mod, Func, Args) &#8211; links work the same&lt;/li&gt;
		&lt;li&gt;alive(Node) &#8211; tell the system you are alive&lt;/li&gt;
	&lt;/ul&gt;


Main libs:
	&lt;ul&gt;
	&lt;li&gt;rcp&lt;/li&gt;
		&lt;li&gt;global&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Test on local nodes, then over a cluster.
Dave: mnesias cool be cause you can query it using list comprehensions.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;erl -sname dave

rpc:call('joe@Daves-Powerbook', erlang, node, []).
rpc:call('joe@Daves-Powerbook', erlang, exit, [kill]).
rpc:call('joe@Daves-Powerbook', erlang, halt, []).&lt;/code&gt;&lt;/pre&gt;

Shell commands for interacting with erl nodes:
	&lt;ul&gt;
	&lt;li&gt;^g gets you into the shell&lt;/li&gt;
		&lt;li&gt;j &#8211; jobs&lt;/li&gt;
		&lt;li&gt;r &#8216;dave@Daves-Powerbook&#8217; % open a remote shell&lt;/li&gt;
		&lt;li&gt;c 2 &#8211; change to the second  process&lt;/li&gt;
		&lt;li&gt;now at (dave@Daves-Powerbook)&amp;gt;&lt;/li&gt;
		&lt;li&gt;toolbar:start(). % show current processes &#8211; queries &lt;span class=&quot;caps&quot;&gt;OTP&lt;/span&gt; structure&lt;/li&gt;
	&lt;/ul&gt;


Security:
	&lt;ul&gt;
	&lt;li&gt;Security on distributed Erlang is very course grain. It&#8217;s all access or nothing.&lt;/li&gt;
		&lt;li&gt;Perfect for a fire-walled corporate cluster.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Need to shore cookie to other machines. Check your home directory &#8211; .erlang.cookie&lt;/p&gt;


	&lt;h2&gt;&lt;span class=&quot;caps&quot;&gt;OTP&lt;/span&gt; &#8211; Open Telecomms Platform&lt;/h2&gt;


This is the platform / framework for building Erlang applications.
	&lt;ul&gt;
	&lt;li&gt;Error logs&lt;/li&gt;
		&lt;li&gt;Hot swapping modules&lt;/li&gt;
		&lt;li&gt;Common tasks that everyone needs&lt;/li&gt;
		&lt;li&gt;etc.&lt;/li&gt;
		&lt;li&gt;Mnesia&lt;/li&gt;
		&lt;li&gt;&lt;span class=&quot;caps&quot;&gt;SASL&lt;/span&gt;&lt;/li&gt;
		&lt;li&gt;&lt;span class=&quot;caps&quot;&gt;SNMP&lt;/span&gt; Agents&lt;/li&gt;
		&lt;li&gt;Web Server&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Lots of undocumented corners. Programming Erlang book is very helpful. It&#8217;s Open Source in the sense that you can see the source. But commit rights are controlled. It is product quality. There is no difference between Erickson&#8217;s products released and the Open Source distribution. There are 15 people working full time to maintain this &#8211; stable, battle tested.&lt;/p&gt;


&lt;span class=&quot;caps&quot;&gt;OTP&lt;/span&gt; Principles
	&lt;ul&gt;
	&lt;li&gt;Joe Armstron &lt;span class=&quot;caps&quot;&gt;PHD&lt;/span&gt; Thesis&lt;/li&gt;
		&lt;li&gt;erlang.org/doc/design_principles/part_frame.html&lt;/li&gt;
		&lt;li&gt;client-server gen_server&lt;/li&gt;
		&lt;li&gt;finite state machines gen_fsm&lt;/li&gt;
		&lt;li&gt;event handling gen_event&lt;/li&gt;
		&lt;li&gt;supervisor gen_sup&lt;/li&gt;
		&lt;li&gt;Applications &#8211; e.g. mnesia, standard libraries, collections of processes shipped in it&#8217;s own right. start and stop etc.&lt;/li&gt;
		&lt;li&gt;Releases &#8211; 4-5 applications combined form a product&lt;/li&gt;
		&lt;li&gt;Application upgrade &#8211; upgrade a running system&lt;/li&gt;
	&lt;/ul&gt;


Finite state machines
	&lt;ul&gt;
	&lt;li&gt;State x Event -&amp;gt; State1 x Action&lt;/li&gt;
		&lt;li&gt;Way of writing pattern matching on state and event.&lt;/li&gt;
	&lt;/ul&gt;


gen_event
	&lt;ul&gt;
	&lt;li&gt;no reply back (error log)&lt;/li&gt;
		&lt;li&gt;event to new state, no reply&lt;/li&gt;
	&lt;/ul&gt;


Order of reading:
	&lt;ul&gt;
	&lt;li&gt;Joe&#8217;s thesis &#8211; best intro to &lt;span class=&quot;caps&quot;&gt;OTP&lt;/span&gt;: sics.se/~joe/thesis&lt;/li&gt;
		&lt;li&gt;erlang.org/doc/design_principles/part_frame.html&lt;/li&gt;
		&lt;li&gt;forthcoming O&#8217;Reilly book&lt;/li&gt;
	&lt;/ul&gt;


Behaviors:
	&lt;ul&gt;
	&lt;li&gt;&lt;span class=&quot;caps&quot;&gt;OTP&lt;/span&gt; name for &#8220;design patterns&#8221; &lt;/li&gt;
		&lt;li&gt;Callback module&lt;/li&gt;
	&lt;/ul&gt;


Case studies:
	&lt;ul&gt;
	&lt;li&gt;&lt;span class=&quot;caps&quot;&gt;AXD301&lt;/span&gt; &#8211; 1.6 million lines of Erlang, built using &lt;span class=&quot;caps&quot;&gt;OTP&lt;/span&gt;.&lt;/li&gt;
		&lt;li&gt;Nortel Networks&lt;/li&gt;
	&lt;/ul&gt;


Factoids:
	&lt;ul&gt;
	&lt;li&gt;gen_server is the most used behavior.&lt;/li&gt;
		&lt;li&gt;supervisor bridge &#8211; allows a C module to be fault tolerant in use with Erlang.&lt;/li&gt;
		&lt;li&gt;gen_server &#8211; A generic client-server model&lt;/li&gt;
	&lt;/ul&gt;


Types of Supervision:
	&lt;ul&gt;
	&lt;li&gt;1:1 vs 1:N supervision&lt;/li&gt;
		&lt;li&gt;1:1 &#8211; if child dies only 1 is restarted&lt;/li&gt;
		&lt;li&gt;1:N &#8211; if challed dies all child sibling processes restarted&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;trapexit.org is a good site.&lt;/p&gt;


Distributed applications:
	&lt;ul&gt;
	&lt;li&gt;Must have the same beam code on all machines. There are checksums.&lt;/li&gt;
		&lt;li&gt;Must have the same version of Erlang.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;One way of solving this is to have the share the same backend &lt;span class=&quot;caps&quot;&gt;NFS&lt;/span&gt; system.&lt;/p&gt;


Explicit code distribution. Send the code in a message:
&lt;pre&gt;&lt;code&gt;{ok, Bin} = file:read_file(&quot;xxx.beam&quot;),
Term = {apply, erlang, load_module, [Mod, Bin]}),
gen_tcp:send(Socket, term_to_binary(Term))&lt;/code&gt;&lt;/pre&gt;

run it:
&lt;pre&gt;&lt;code&gt;{apply, xxx, start, [...]}&lt;/code&gt;&lt;/pre&gt;

dynamic code upgrade:
	&lt;ul&gt;
	&lt;li&gt;Mod:Func(Args, ...) the latest version of Mod is called&lt;/li&gt;
		&lt;li&gt;If you reload Mod then you can run two versions of the code at the same time&lt;/li&gt;
		&lt;li&gt;You can only have two versions of the code running at the same time, an old and a new version&lt;/li&gt;
		&lt;li&gt;To load a third version you must call erlang:purge_module(Mod) before reloading the module (think of this as  a two place shift register)&lt;/li&gt;
		&lt;li&gt;to load code call erlang:load_module(Mod, BeamCodeBin)&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;You can find all the number of processes running a particular version of a module. Some may never change, those you may have to kill.&lt;/p&gt;


	&lt;p&gt;When you load new code you get old and new code running at the same time. You must call purge_code before you add a third version of the code. This is going to effect 0.0x of people using erlang. After a crash you need to look at these issues.&lt;/p&gt;


	&lt;p&gt;This code swapping is not well documented. Mailing list may be helpful for this area.&lt;/p&gt;


	&lt;h2&gt;Q &#38; A With Joe Armstrong&lt;/h2&gt;


	&lt;h3&gt;What is the relationship between processes on the OS and Erlang?
One process per whole Erlang instance on the OS.&lt;/h3&gt;


	&lt;p&gt;When you spawn there is a run queue. The process that currently gets to the top of the queue. Every time you do a function call it&#8217;s called a reduction. If it&#8217;s waiting to receive a message, it&#8217;s taken out of the scheduling queue and is put into the waiting for message queue. If mail is delivered it&#8217;s put back in the run queue. There is no polling that is used. When you send a message to a processor and it hasn&#8217;t used all it&#8217;s reductions &#8211; may preempt &#8230;&lt;/p&gt;


	&lt;h3&gt;Consider exposing schedule to Erlang?
This would be very dangerous. But GC and as many things as possible should be written in Erlang.&lt;/h3&gt;


	&lt;h3&gt;What do you do in an app to seperate tests into a seperate file?
Hierarchy of tests:
	&lt;ul&gt;
	&lt;li&gt;Unit test framework that comes from France (used by ejabber). &lt;/li&gt;
		&lt;li&gt;Erickson has a test server that is distributed with Erlang. Massive regression and unit tests.&lt;/li&gt;
		&lt;li&gt;Credita has modified to run test any time anything is checked into their repositories.&lt;/li&gt;
		&lt;li&gt;Quick check written by John Hues. Was written in Haskell has been ported to Erling. Generates random tests that satisfy certain properties. Does some automatic reduction of code execution to minimize error conditions. This is an expensive use.&lt;/li&gt;
		&lt;li&gt;E Unit &#8211; Dave found this somewhat cumbersom. Straight pattern matching was easier. Didn&#8217;t seem to have a huge value add. Would like to see how he can use differen&#8217;t naming conventions to automate and have some sort of runner. Find *.erl run anything named test and report if it doesn&#8217;t return a pass. Gen server seems easily testible by calling handler methods.&lt;/li&gt;
	&lt;/ul&gt;&lt;/h3&gt;


	&lt;h3&gt;Diagraming conventions for Erlang?
Not currently.&lt;/h3&gt;


	&lt;h3&gt;Petri Nets or activity diagrams?&lt;/h3&gt;


	&lt;p&gt;Message sequence diagrams are used frequently. Joe is not a fan of drawing programs. Although, message sequence diagrams are extremely useful (Y = Time. X = Process). Joe is writing a program for animating Erlang.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;erlang:trace(Pid, [Msgs, Call, list of things to trace]). &lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;This process get&#8217;s lots of messages. Joe is writing a program that stores these in a file and then animates the activities of these processes over time. Working with a games developer to animate this.&lt;/p&gt;


	&lt;h3&gt;Erlyweb?&lt;/h3&gt;


	&lt;p&gt;Joe &#8211; hasn&#8217;t spent much time with this and &lt;span class=&quot;caps&quot;&gt;YAWS&lt;/span&gt; (Yet Another Web Server).&lt;/p&gt;


	&lt;h3&gt;Erlang graphic user interface?&lt;/h3&gt;


	&lt;p&gt;Lots written. Tend to be hard to use &#8211; wswidgets being used for 3D process modeling. Interfaces to &lt;span class=&quot;caps&quot;&gt;SDL&lt;/span&gt;, GTK, Cairo, etc. &lt;span class=&quot;caps&quot;&gt;TCL&lt;/span&gt; library is the mainly supported one that works everywhere. Lots of people have been doing GUIs in web browsers &#8211; action script 3 and flex. Can also use flex2 as a device driver for Erlang &#8211; e.g. video stream. Makes it possible to make these applications more portable. Therefore can use Flash as a device driver. Drop dead beautiful &#8211; flash with &lt;span class=&quot;caps&quot;&gt;AIR&lt;/span&gt; may be the way to go.&lt;/p&gt;


	&lt;h3&gt;Redeployable packaging?&lt;/h3&gt;


	&lt;p&gt;Erlang is packaged for win, linux, and mac. &lt;span class=&quot;caps&quot;&gt;CEAN&lt;/span&gt; (Comprehensive Erlang Application &#8230;) ... Wings. Martin Logan, faxian. Martin Logan also has generator applications for Erlang (Erlware?).&lt;/p&gt;


	&lt;h3&gt;Good frameworks for doing ontological modeling and reasoning?&lt;/h3&gt;


	&lt;p&gt;Expert systems shell. University of Corona. Reported at the Erlang user conferences. Multi agent listener but not generalized to owl.&lt;/p&gt;


	&lt;h3&gt;List of reference projects?&lt;/h3&gt;


	&lt;p&gt;No canonical reference. But check trapexit.org.&lt;/p&gt;


	&lt;h3&gt;Where is Erlang center of gravity?&lt;/h3&gt;


	&lt;p&gt;Attracting lots of interest in Financials &#8211; especially in London. Finance industry targeted conference coming up in London. Much bank interest &#8211; extreme real time demands. Number of pure erlang based trading companies. Debt buying company &#8211; purchases debt and collect. Buys these debts a few moments after the transaction. Mnesia founder involved.&lt;/p&gt;


	&lt;h3&gt;Future changes &#8211; where is it going?&lt;/h3&gt;


	&lt;p&gt;Not many changes to the language. Millions of legacy lines of code needed for compatibility &#8211; syntax unlikely to change. But, implementation speed optimization and multi-processor support is likely to improve.&lt;/p&gt;


	&lt;h3&gt;Embedded Erlang?&lt;/h3&gt;


	&lt;p&gt;4MB probably the minimum size. Used to be 640k but may be a better domain for C.&lt;/p&gt;


	&lt;h3&gt;String localization &#8211; &lt;span class=&quot;caps&quot;&gt;UTF8&lt;/span&gt;?&lt;/h3&gt;


	&lt;p&gt;In a sense it is solved. In another sense it is not solved. In Erlang there is no string type &#8211; it is a list of integers. &lt;span class=&quot;caps&quot;&gt;UTF8&lt;/span&gt; is an integer and can be stored. However, the interpreter from text to binary and back is not written. However, it is not difficult. It is in fact a library change.&lt;/p&gt;


	&lt;h3&gt;What is a good candidate for Erlang?&lt;/h3&gt;


	&lt;p&gt;Telecomm applications, lots of small processes. Individual processes have low ammount of short computations. Good at coordination, concurrency, switching. Not good at matrix multiplication, gif encoding etc. Financial applications fit the erlang profile.&lt;/p&gt;


	&lt;h3&gt;Libraries for interfacing to &lt;span class=&quot;caps&quot;&gt;SQL&lt;/span&gt; databases?&lt;/h3&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;ODBC&lt;/span&gt; libraries. Could just open a socket to the DB. Java has a good arbitrary support for sockets. Check Yariv&#8217;s Erly web implementation.&lt;/p&gt;


	&lt;h2&gt;Summary&lt;/h2&gt;


	&lt;p&gt;Fault tolerance drives a lot of the design decisions behind Erlang.
Simple functional language.
Function selection is by pattern matching
Variables are immutable&lt;/p&gt;


Concurrent Erlang
	&lt;ul&gt;
	&lt;li&gt;3 primitives: Spawn, Send, Receive &#8211; very simplified from Object Oriented model.&lt;/li&gt;
		&lt;li&gt;register / unregister can be used to associate a name with a process&lt;/li&gt;
	&lt;/ul&gt;


Fault Tolerant
	&lt;ul&gt;
	&lt;li&gt; catch .. throw, try &#8230; catch &#8230; end&lt;/li&gt;
		&lt;li&gt;link, process_flag(trap_exit, true)&lt;/li&gt;
	&lt;/ul&gt;


Distributed Erlang
	&lt;ul&gt;
	&lt;li&gt;spawn(Node, Mod, Func, Args)&lt;/li&gt;
		&lt;li&gt;or explicit term passing&lt;/li&gt;
	&lt;/ul&gt;


Benefits of Erlang:
	&lt;ul&gt;
	&lt;li&gt;Technologies becoming more concurrent and people are looking for solutions to that probelm. Cooperative applications, etc. Erlang is a working solution. Not operating system dependent. 20 &#8211; 30 years of experience with fault tolerance measured in years.&lt;/li&gt;
		&lt;li&gt;Multi-Core ready&lt;/li&gt;
		&lt;li&gt;Processes in the language&lt;/li&gt;
	&lt;/ul&gt;


Some projects to research:
	&lt;ul&gt;
	&lt;li&gt;&lt;span class=&quot;caps&quot;&gt;AXD301&lt;/span&gt; &#8211; biggest Erlang and Functional programming ever made 60 programmers x 3 years. Runs backbone of british telecom. Market leading in that sector. Peaked at 9&#215;9s of reliability. This wasn&#8217;t a commercial project on 2-3% of the market.&lt;/li&gt;
		&lt;li&gt;Kreditor (Kreditor.se) &#8211; buys debt. #2 IP startup in sweden. $150 year. Self funded. Founded by alumni of Blue Tail.&lt;/li&gt;
		&lt;li&gt;SimpleDB (Amazon)&lt;/li&gt;
		&lt;li&gt;CouchDB (text db)&lt;/li&gt;
		&lt;li&gt;MociWeb (Mochimedia)&lt;/li&gt;
		&lt;li&gt;Ejabberd (jabber server &#8211; by extension Twitter?)&lt;/li&gt;
		&lt;li&gt;ErlyWeb (Erlang web framework inspired by Rails)&lt;/li&gt;
	&lt;/ul&gt;
          </content>  </entry>
</feed>
