<?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:blogger='http://schemas.google.com/blogger/2008' 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-1042801964488488185</id><updated>2026-04-09T18:20:14.755-05:00</updated><category term="Code"/><category term="Apprenticeship"/><category term="Rails"/><category term="commentary"/><category term="Ruby"/><category term="RSpec"/><category term="Metrics"/><category term="metric_fu"/><category term="Flog"/><category term="complexity"/><category term="RailsConf2009"/><category term="git"/><category term="RubyConf2008"/><category term="test_coverage"/><category term="Bugs"/><category term="Mocking"/><category term="craftsman_swap"/><category term="not_code"/><category term="testing"/><category term="Agile2009"/><category term="Amazon"/><category term="refactoring"/><category term="ActiveRecord"/><category term="Linux"/><category term="LoneStarRubyConf2008"/><category term="Saikuro"/><category term="XP"/><category term="churn"/><category term="design"/><category term="Fixtures"/><category term="JRuby"/><category term="LoneStarRubyConf2009"/><category term="Math"/><category term="Obtiva"/><category term="RailsConf2007"/><category term="Rake"/><category term="Rcov"/><category term="RubyKaigi2010"/><category term="Svn"/><category term="legacy_code"/><category term="Flay"/><category term="GLSEC"/><category term="Mingle"/><category term="RailsConf2010"/><category term="SQuiD"/><category term="TextMate"/><category term="Windows"/><category term="WindyCityRails"/><category term="javascript"/><category term="lean"/><category term="Backstop"/><category term="DUST"/><category term="EVDO"/><category term="IO"/><category term="MacRuby"/><category term="OSX"/><category term="Routes"/><category term="RubyMidwest2010"/><category term="RubyWorks"/><category term="Tomcat"/><category term="attachment_fu"/><category term="cache-fu"/><category term="citcon"/><category term="consulting"/><category term="craftsmanship"/><category term="iPhone"/><category term="interview"/><category term="mac"/><category term="memcached"/><category term="oracle"/><category term="ord_sessions"/><category term="pairing"/><category term="restful_authentication"/><title type='text'>Jake Scruggs</title><subtitle type='html'>writes ruby/wears crazy shirts</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://jakescruggs.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1042801964488488185/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://jakescruggs.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/1042801964488488185/posts/default?start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>Jake Scruggs</name><uri>http://www.blogger.com/profile/16274380203959781950</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://farm1.static.flickr.com/200/441258345_b0379aaf00_m.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>218</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1042801964488488185.post-2961146054780300228</id><published>2016-01-31T23:02:00.001-06:00</published><updated>2016-01-31T23:07:52.130-06:00</updated><title type='text'>Clojure ‘def’, ‘declare’, and ‘concat’</title><content type='html'>&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;I hit the Aeron hard and asked my pair &lt;a href=&quot;https://twitter.com/ebethme&quot; target=&quot;_blank&quot;&gt;Liz&lt;/a&gt; “what’s up?” I’d been sick and she had been working on a tricky &lt;a href=&quot;http://www.datomic.com/&quot; target=&quot;_blank&quot;&gt;Datomic&lt;/a&gt; &lt;a href=&quot;http://www.learndatalogtoday.org/&quot; target=&quot;_blank&quot;&gt;datalog&lt;/a&gt; query in my absence. She claimed to have solved the whole problem but the tests would not pass when run as a whole vs. when run individually.&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;A classic problem with a big Clojure twist. I, being no stranger to this terribleness, eventually shook the sick out of my head and asked if she had tried running the singular test file by itself. Good news: it failed too.&amp;nbsp; What? I’ll explain.&amp;nbsp; We use a classic trick here at Backstop when running tests in the Clojure REPL: ‘:reload-all’&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;pre&gt;(require &#39;[clojure.test :refer [run-tests]])
(require &#39;your-ns.example-test)
(run-tests ‘your-ns.example-test) ; First time

(require &#39;your-ns.example-test :reload-all) ; Picks up new changes in the files
(run-tests ‘your-ns.example-test) 
&lt;/pre&gt;
&lt;pre&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;/pre&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;

&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;Otherwise we’d spend all day waiting for the JVM to start up every time we run our tests. It’s a cool trick but it has its limitations. We were clearly dealing with one of those limitations as the tests would fail once in a fresh REPL but succeed on a second run.&amp;nbsp; Those who’ve already guessed the answer &lt;a href=&quot;https://www.backstopsolutions.com/careers&quot; target=&quot;_blank&quot;&gt;please apply for a job here&lt;/a&gt;. For all us other mere mortals who need to think it through I’ll present this example of what we were trying to do and what happened:&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre&gt;(declare a-vector)
#&#39;user/a-vector
(def time-bomb (concat [1 2 3] a-vector))
#&#39;user/time-bomb
(def a-vector [4])
#&#39;user/a-vector
time-bomb
IllegalArgumentException Don&#39;t know how to create ISeq from:&amp;nbsp;&lt;/pre&gt;
&lt;pre&gt;clojure.lang.Var$Unbound  clojure.lang.RT.seqFrom (RT.java:505)
&lt;/pre&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;

&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span class=&quot;s1&quot;&gt;But if you asked for time-bomb again:&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;pre&gt;time-bomb
(1 2 3)
&lt;/pre&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;Everything is, er, fine?!?&amp;nbsp; Except &#39;a-vector&#39; has disappeared and a &#39;function&#39; has returned different things for the same lack of input. &amp;nbsp;So, of course, “concat” is part of the problem here. As Stuart Sierra&lt;span class=&quot;s2&quot;&gt;&amp;nbsp;&lt;/span&gt;pointed out in &lt;a href=&quot;http://stuartsierra.com/2015/04/26/clojure-donts-concat&quot;&gt;http://stuartsierra.com/2015/04/26/clojure-donts-concat&lt;/a&gt;, &amp;nbsp;“concat” is a lazily evaluated join so it can hide many bombs.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;If we had instead used “into,” which is not lazily evaluated, all would have blown up in a nice normal manner:&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;pre&gt;(declare b-vector)
#&#39;user/b-vector
(def now-bomb (into [1 2 3] b-vector))
CompilerException java.lang.IllegalArgumentException: Don&#39;t know how to create&amp;nbsp;&lt;/pre&gt;
&lt;pre&gt; ISeq from: clojure.lang.Var$Unbound,&lt;/pre&gt;
&lt;pre&gt; compiling:(form-init1552771854893412833.clj:1:15)
&lt;/pre&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;Well, not a great error but at least the line number would have given us a clue as to where the problem was instead of the stack trace starting where ever the “time-bomb” was evaluated.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;However, “a-vector” is defined by the time “time-bomb” is evaluated. So why doesn’t the lazy “concat” use the available “a-vector”? “Concat” seems to freeze the temporary nature of clojure.lang.Var$Unbound and not evaluate a later defined “a-vector.”&amp;nbsp; Weird. Is this a bug?&amp;nbsp; Or just a known evaluation order thing? I verified this behavior in 1.5,1.6,1.7, and 1.8 so it seems here to stay.&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;In case you are wondering, without a “declare” this code would blow up right away on the right line number:&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;pre&gt;(def nope (concat [1 2 3] nothing-at-all))
CompilerException java.lang.RuntimeException:&amp;nbsp;&lt;/pre&gt;
&lt;pre&gt;  Unable to resolve symbol: nothing-at-all in this context,&amp;nbsp;&lt;/pre&gt;
&lt;pre&gt;  compiling:(/tmp/form-init1552771854893412833.clj:1:11)
&lt;/pre&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;

&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;Why did we use declare instead of just order the code so it compiles? As a team, we’ve adopted a code standard where we try to push private functions down to the bottom of a file and “declare” helps us declare things that will be coming to the compiler/jvm/macro-magic-factory. It works really well with “defn” so we applied similar principles to public “def”s (for use outside the namespace) and “def”s we didn’t think should be part of a namespace’s API.&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;s1&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span class=&quot;s1&quot;&gt;

&lt;/span&gt;&lt;br /&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;The combination of testing in the REPL, code conventions, the lazy nature of “concat,” and when “def” gets evaluated created a lot of confusion for us. Hopefully, this blog post helps you figure out some similar problems.&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://jakescruggs.blogspot.com/feeds/2961146054780300228/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1042801964488488185/2961146054780300228' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1042801964488488185/posts/default/2961146054780300228'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1042801964488488185/posts/default/2961146054780300228'/><link rel='alternate' type='text/html' href='http://jakescruggs.blogspot.com/2016/01/clojure-def-declare-and-concat.html' title='Clojure ‘def’, ‘declare’, and ‘concat’'/><author><name>Jake Scruggs</name><uri>http://www.blogger.com/profile/16274380203959781950</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://farm1.static.flickr.com/200/441258345_b0379aaf00_m.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1042801964488488185.post-4030889116052258046</id><published>2015-11-25T15:06:00.000-06:00</published><updated>2015-11-25T15:06:03.078-06:00</updated><title type='text'>Lutz’s Super Truthful Murder-ball adventure</title><content type='html'>&lt;div class=&quot;p1&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;a href=&quot;http://jakescruggs.blogspot.com/2015/11/lutzs-completely-accurate-dnd-summary.html&quot; target=&quot;_blank&quot;&gt;&lt;span class=&quot;s1&quot;&gt;&lt;/span&gt;For backstory checkout out the previous DnD post.&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;Landing in a pile on a large stone table in a massive room from out of a swilling green magic portal is very disorienting. However, it did lead to Lutz shaking off his magical blindness. First sight: Many intense dudes some covered in lacquer armor — Lutz didn’t even know lacquer was a thing you could make armor from. While Lutz pondered the truth of his eyesight, Lord Valparaiso threw a little fit. One: He was mighty pissed that his evil portal trap has ensnared him in addition to our heroes. Two: The portal had clearly been hijacked to another mysterious and far away land. The land was so strange and far from their home that Raest couldn’t feel his god Palore anymore which meant no spells.&amp;nbsp; Essentially this changed his role in the party from from healer/crappy fighter to, um, crappy fighter. That single set of footprints on the beach are not from Palore carrying Raest during his darkest hour.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;The team had many questions but lacking a common language they were ignored, shoved out of the big room, down a hallway, and into a smaller room with a chalkboard. A very painful session of explanation ensued. Drawings of stick figures and angry gestures soon left both sides exhausted. The time had come, once again, for Lutz to put the team on his back. Working with noted jerky-owner and consumer Bran they managed to extract salt from beef jerky infused water with heat from a torch. That pinch of salt combined with a pinch of soot plus Lutz’s NEW FOUND ARCANE TRICKSTER POWERS meant he could cast a Comprehend Languages spell. Clutch.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;Now that they could understand what was being said, via Lutz, the strangers in a strange land understood that they must play a spirited game of foots-ball with big bats and a medicine ball. There would also be giant walking trees that shoot hurt-y needles if you get too close. Hitting other players was allowed and encouraged but the ultimate goal was to get the 2 foot wide medicine ball into the goal by any means necessary. Winner gets not to die. Best 2 out of 3. Classy.&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;Our ambassador/coach/warden gave the team a (perhaps) last meal. It kinda seemed she might have an interest in seeing team Lutz win. Was betting involved? Who’s to say? Mind your own business. The important part of this last feast was that everyone got a rest and Lutz hid away a small amount of alcohol.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;Upon reaching the field for the first match the team saw their competitors. From far away they appeared to be a bunch of imps and a man.&amp;nbsp; As they came closer the dread increased as our brave band of adventurers saw one 9 foot tall center and a bunch of good sized dudes.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;At the start of the match more bad news came pretty fast: Clustering around the ball made the team susceptible to a sleep spell from the safely 50 foot back magic user. The other team had “forwards” running down the wings, defenders hanging back, and an actual strategy. Peren, Lutz, Bran, and Raytheon had more of a “swarming bees” strategy that kinda played right into team bad guys’ “cast a sleep spell and send a man down the side lines” strategy.&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;You might think the gang got out of this one with some clever thinking, but no, they mostly just whacked everything nearby which included the ball. Ray-ray, in particular, took out his frustrations over losing all of his promising new cult by smashing every opponent excessively: Often from behind. Somehow this aggressive flailing got the ball past the team jerk face’s front line and rolling. The big bad, being not very big on smarts, crushed the ball towards the wall which was about 90 degrees off from his target goal. Lutz used his superior speed and agility to do 2 things in the time another would merely perform one. He wake up the sleeping members of his team and flanked the opposition. Bran got all “angry barbarian” and made like Lutz with the 2 to 1 actions. Unfortunately the other team had a double attacker too - lots of hustle displayed on the pitch that day. The first match was won by Lutz picking up the ball, using his crazy moves to break the ankles of the other team, and bursting on through to the goal.&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;During the break Lutz cast a False Life upon himself with his fly arcane trickster powers using the dram of alcohol he had acquired from the “last supper.” Palore, wherever he may be, did not favor Raest with the heal spell he so desperately needed. Only a jerk would have pointed out that necromancy had succeeded where religion had failed. A bit more rested than before the team braced for the coming match. How would the other team solve the “Lutz problem?”&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;Well how could you? He’s just too damn fast and agile.&amp;nbsp; Like they used to say about famed foots-ball player Mycroft Jordan-Hammer: You can’t stop a Lutz, you can only hope to contain him. Once again Lutz woke up sleepy members of the team, picked up the ball, and made a break for it. Problem was that this time a terror tree decided to get between Lutz and the goal. Now a normal thief, pick pocket, 2nd story man, or even assassin would perhaps have turned tail at that point. Lutz sucked up his courage, cast “Thunder Wave,” and knocked the terror tree aside. An entire walking tree pushed back 10 feet by a skinny studded leather wearing punk of an 18 year old. Just picture it. Now picture a bunch of jerks chasing Lutz for a few long seconds as it is became apparent to all that it was going to be a 2-0 sweep. Clutch.&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;Now that they won the right not be slaughtered for a god’s favor, how will these heroes be treated in a land even Palore has forgotten? Tune in next time to find out.&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://jakescruggs.blogspot.com/feeds/4030889116052258046/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1042801964488488185/4030889116052258046' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1042801964488488185/posts/default/4030889116052258046'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1042801964488488185/posts/default/4030889116052258046'/><link rel='alternate' type='text/html' href='http://jakescruggs.blogspot.com/2015/11/lutzs-super-truthful-murder-ball.html' title='Lutz’s Super Truthful Murder-ball adventure'/><author><name>Jake Scruggs</name><uri>http://www.blogger.com/profile/16274380203959781950</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://farm1.static.flickr.com/200/441258345_b0379aaf00_m.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1042801964488488185.post-6292809144729724364</id><published>2015-11-17T17:44:00.000-06:00</published><updated>2015-11-17T17:44:30.373-06:00</updated><title type='text'>Our Purely Functional Microservice in Production</title><content type='html'>&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;Recently I was interviewing a candidate for &lt;a href=&quot;https://www.backstopsolutions.com/careers&quot; target=&quot;_blank&quot;&gt;a job on my team at BackstopSolutions&lt;/a&gt; and he said something like: “I read &lt;a href=&quot;http://jakescruggs.blogspot.com/2015/04/microservices-vs-david-heinemeier.html&quot; target=&quot;_blank&quot;&gt;your blog post about Microservices&lt;/a&gt; and was wondering if the lack of follow up meant the project was a failure.” He actually expressed this sentiment in a much nicer way as this was an interview but still it got me thinking:&lt;/span&gt;&amp;nbsp;&quot;I should do an update on the status of our microservice and explain how it could be purely functional.&quot;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;The service is implemented in Clojure, uses Datomic for persistence, and integrates via REST.&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;The service has been in production for several months now and has gone through a number of versions of its API. Implementing HATEAOS worked out well as it allows us decouple having to keep the service and front end in lock step. Since this is a microservice, we could keep both applications in step with each other as we own both ends of the interface. However this co-ordination is not without cost.&amp;nbsp; Release dates slip b/c of bugs in either system.&amp;nbsp; There are less bottlenecks in production releases as the front and back end can be deployed to production independently of each other. Not having to co-ordinate releases is a wondrous decoupling. It didn’t take long to implement HATEAOS and maintenance costs for the discoverability aspect have not materialized.&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;Datomic is a special snowflake of a database and that it why I believe it is the future. That is a bold statement deserving of a whole other blog post so I will merely list a few of Datomic’s features that we exploit:&lt;/span&gt;&lt;/div&gt;
&lt;ol class=&quot;ol1&quot;&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;span class=&quot;s2&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;It never forgets. Think of it like source control but with transactions replacing commits.&lt;/span&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;span class=&quot;s2&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;Time is a first class citizen. This is really an outgrowth of the above feature but is worth pointing out on its own.&lt;/span&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;span class=&quot;s2&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;It uses the incredibly compose-able Datalog query language instead of SQL and can include clojure.core expressions in its queries.&lt;/span&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;span class=&quot;s2&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;It can easily be used as a graph database.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;Those are some crazy advantages. Since Datomic never forgets, ANY query to our service that specifies a time can never have a different return value. That is what I mean when I say that our service is “purely functional.”&amp;nbsp; This enables the Rails app that works with our micro service to cache every query it makes FOREVER. The service without caching is still crazy fast considering the incredibly complex queries is has to run. Like any graph database, speed is determined by what percentage of the graph a node can access. Even if a customer stretches the engine to its maximum, our ability to cache forever means they will take that hit but once. Of course you can query our microservice with no time specified where it will default to now and not cache. This is used only for debugging and is never used by our Rails application. &amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;The graph database aspect of Datomic combined with its understanding of clojure.core enable us to spend days instead of months (or even years) implementing custom business logic. Backstop Solutions is a Business to Business (B2B) Software As A Service (SAAS) firm.&amp;nbsp; In B2B there is but one constant:&amp;nbsp; All business’ processes are unique. Period: End of story.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;There may be some similarities and generalities between companies in the same competitive space but these similarities are revealed to be mostly illusionary when you try to implement specific customers. Drill down into any business’ rules and you will find unique requests from every client.&amp;nbsp; Think of it this way: In an efficient market what use is there for complete duplication? The clients who&#39;s processes are a competitive advantage hate any SAAS offering that can not implement aspects of their system in the SAAS product. With this microservice we can. The actual challenge is to get clients to simplify their rules enough so that they themselves can understand the rules. This may seem confusing until you consider that Backstop Solutions has clients with many offices in many different lands so we are often the first people to implement a logically consistent system that fits all of their needs, people, and processes.&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;Datalog is a subset of Prolog. Prolog is a logic based language as is SQL. Where it crushes SQL like a bug is its compose-ability. You can create a bunch of “rules” and mix and match these rules just like you are used to composing functions. This is amazing. I can not stress this enough. I continually implement stories in a fraction of the estimated time because I discover that most of the query is already written and I just have to tack a little on the end, or beginning, or middle.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;What is even more wonderful is that even if I ever get into a tight corner with Datalog I can fall back on all the functions in clojure.core.&amp;nbsp; How many times has it infuriated you that the version of SQL you are using can’t support a completely logical function and so you have to do something horrible? Now imagine being able to use all of clojure.core in SQL. Exactly.&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;I should stop and point out that I had the idea for this service 4 years ago during a conversation with David Chelimsky. As he described a problem he was solving with a graph database I realized that we had a completely different but functionally similar problem where I work. Thanks for always being inspiring David.&lt;/span&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://jakescruggs.blogspot.com/feeds/6292809144729724364/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1042801964488488185/6292809144729724364' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1042801964488488185/posts/default/6292809144729724364'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1042801964488488185/posts/default/6292809144729724364'/><link rel='alternate' type='text/html' href='http://jakescruggs.blogspot.com/2015/11/our-purely-functional-microservice-in.html' title='Our Purely Functional Microservice in Production'/><author><name>Jake Scruggs</name><uri>http://www.blogger.com/profile/16274380203959781950</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://farm1.static.flickr.com/200/441258345_b0379aaf00_m.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1042801964488488185.post-7831534849474175463</id><published>2015-11-09T21:14:00.001-06:00</published><updated>2015-11-09T21:18:32.683-06:00</updated><title type='text'>Lutz’s completely accurate DnD summary for those who weren’t there</title><content type='html'>The “Curious Case of the Tiny Thieves” is being joined in progress and so a little backstory is necessary:&lt;br /&gt;
&lt;br /&gt;
The dexterous and rather handsome rouge Lutz was investigating these “Tiny Thieves” with his band of mostly merry adventurers: Raest a cleric of Palore, Bran the mighty barbarian, Torment the super naive atheist paladin, a wild magic user called Very Forgettable Name, and Iesha or Aida or Ada AKA: the old lady magic user who casts a lot of sleep spells. They discovered the little thieves trying to abscond with their solid gold cat statue which they received as a gift for returning a talking cat to an old lady who was really a dragon in human form — long story.&lt;br /&gt;
&lt;br /&gt;
Turns out the whole town hated these mini scofflaws as they has been on a veritable spree of the crime variety. &amp;nbsp;A reward was offered and pursued by our fairly fearless heroes. As far as they knew the criminals were: 6-8 inches tall, never seen in full light, and immune to sleep spells. Lutz made a super cool trap for these minute miscreants but they avoided it perhaps because the gang had left the lights on. Seems obvious in retrospect… They did find tiny foot prints in the fireplace the next day! &amp;nbsp;They were also found the same footprints the next room over where a very expensive necklace had been stolen. Tiny thieves: 1. Adventurers: 0.&lt;br /&gt;
&lt;br /&gt;
That was all prologue, believe it or not.&lt;br /&gt;
&lt;br /&gt;
Upon investigating the roof and dirt surrounding the “Sleepy Dragon” the team supreme found evidence of rope used to climb down the chimney and footprints leading away from the inn. &amp;nbsp;Following the trail of regular sized footprints the gang pretty much got lost right away. &amp;nbsp;Sigh. &amp;nbsp;The trail was definitely headed south and that’s about all they knew. In that direction lay: &amp;nbsp;The bad part of town, The duke who had suspiciously never been robbed, and a new unknown church that ministered to the poor in said bad party of town. “Why not stop in at the working class church and ask around?” thought pretty much everyone. &amp;nbsp;Raest, who apparently has more money than sense, decided that 5 gold was an appropriate bribe/offering to a dirt poor chump. Not 5 copper, mind you, but 5 gold. As in 500 copper. &amp;nbsp;Bran had been invited in to the small place of worship by Raest in a move that was so very sensible it belied his previous insane tipping/bribing strategy. I feel like I’m focusing on this too much… But seriously 5 gold. FIVE DAMN GOLD. It makes a rouge wretch to think of it.&lt;br /&gt;
&lt;br /&gt;
Iesha noticed the lay priest was totally lying about everything with her wicked awesome old lady perception skilz. However that information was disclosed after Raest and Bran had disappeared into the hovel/church.&lt;br /&gt;
&lt;br /&gt;
Lucky Lutz, the super awesome leader of the group, had wisely decided to keep his ear to the door and therefore heard screams from within. First through the door and down the stairs Lutz &amp;nbsp;sprinted only to be held up by the barbarian’s massive size in the stairwell. Bran had been stopped by…&lt;br /&gt;
&lt;br /&gt;
The Tiny Thieves! They were clearly automatons (explaining why they could not be put to sleep) &amp;nbsp;and surprisingly strong as they managed to subdue the brick shit house that is Bran and even Lutz: the slipperiest rouge in the land. Unfortunately for those wee jerks, Torment has a bewildering talent with his net. He effortlessly swept them off of Lutz from 10 feet away!&lt;br /&gt;
But what of Raest and his terrible ability to estimate bribes? &amp;nbsp;He was in another corner of the savage basement of heck getting all perforated by the lay priest of a bad guy god. That’s right: Raest had paid 5 gp for an invitation to an underground murder party.&lt;br /&gt;
&lt;br /&gt;
Raest cast a quick command spell which, as you may know, can be only one word. That word was “retch.” &amp;nbsp;Cult-y McJerk Face then heaved up his lunch while getting pulverized via mace to the face. He died fast in a bewildering flurry of vomit and steel. Despite this early success Raest was lit up like a Christmas tree by a bunch of magic bolts from a pair of magic jerks. &amp;nbsp;Torment barely missed falling into a pit trap and then charged the head cult guy who&#39;s name probably starts with a V. Sadly V(icky?) introduced Torment to the Xmas tree experience mortally wounding the paladin. Torment collapsed to the ground unconscious and bleeding out. Bran and Raest kicked ass for awhile but succumbed to the combined forces of the tiny thieves and dickhead magic users. Low on health, they were put into a magical sleep and were soon to be easy pickings. Surely Lutz could have saved the day had he not been magically blinded and therefore unable to help his friend Torment dying just a few feet away. Aida was upstairs drinking water and that other guy was investigating the latrine. Really. They may or may not have had a slap fight while getting down the stairs.&lt;br /&gt;
&lt;br /&gt;
Things looked dire for our rag tag group of misfits until the cult leader made a mistake. Which was good because the only thing stopping his dance of diabolical destruction was the late arriving, but very hydrated, team of Aida and wild magic guy. Did V(oldemort?) over estimate the strength of his magic portal’s vacuum power? Or did he simply slip like the jackass he was and always will be? Maybe we’ll find out next time because everyone but the old bat and a mostly dead Torment got sucked through the portal into another land.&lt;br /&gt;
&lt;br /&gt;
Another land of suck. 5 seconds of being in the new place revealed 2 things:&lt;br /&gt;
1) The new bad guys are plentiful and way into lacquer armor.&lt;br /&gt;
2) Lutz and company are to be offerings of some sort. Which doesn’t sound good at all.&lt;br /&gt;
&lt;br /&gt;
Cliffhanger!&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://jakescruggs.blogspot.com/feeds/7831534849474175463/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1042801964488488185/7831534849474175463' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1042801964488488185/posts/default/7831534849474175463'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1042801964488488185/posts/default/7831534849474175463'/><link rel='alternate' type='text/html' href='http://jakescruggs.blogspot.com/2015/11/lutzs-completely-accurate-dnd-summary.html' title='Lutz’s completely accurate DnD summary for those who weren’t there'/><author><name>Jake Scruggs</name><uri>http://www.blogger.com/profile/16274380203959781950</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://farm1.static.flickr.com/200/441258345_b0379aaf00_m.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1042801964488488185.post-854274285947506588</id><published>2015-04-30T08:13:00.000-05:00</published><updated>2015-04-30T08:13:00.143-05:00</updated><title type='text'>Microservices vs David Heinemeier Hansson</title><content type='html'>&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;Hearing that &lt;a href=&quot;http://david.heinemeierhansson.com/&quot; target=&quot;_blank&quot;&gt;David Heinemeier Hansson&lt;/a&gt; had slammed &lt;a href=&quot;http://martinfowler.com/articles/microservices.html&quot; target=&quot;_blank&quot;&gt;microservices&lt;/a&gt; in his Rails Conf 2015 keynote was a bit disorienting as I was developing a microservice at the time. I leaned over to the other senior developer and said: “What’s his deal?” Toby Tripp, who had just watched the keynote, explained that when David’s team implemented&amp;nbsp;microservices they had terrible trouble managing all the versions between 3&amp;nbsp;systems. “Isn’t that why we use a lookup call to get the URI-map?” I asked.&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;“Yep” he said.&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;“That and never remove a return key/value (pair), only add new ones until you can prove they are not used anymore” He added.&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;I returned to adding in some caching to our service calls.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;Later, I watched the video which is here:&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s2&quot;&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=oMlX9i9Icno&quot;&gt;https://www.youtube.com/watch?v=oMlX9i9Icno&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;David has a meandering style but he mostly discusses&amp;nbsp;microservices between 43:00 and 52:00.&amp;nbsp; The “what’s in your backpack” stuff is all about his earlier zombie apocalypse metaphor that you can watch if you like.&amp;nbsp; He claims his team implemented&amp;nbsp;microservices right, loved them on day 5 but hated ‘em in year&amp;nbsp;2 (paraphrase). I don’t understand how I will regret my microservice architecture decision if we implement &lt;a href=&quot;http://en.wikipedia.org/wiki/HATEOAS&quot; target=&quot;_blank&quot;&gt;HATEOAS&lt;/a&gt; (Hypermedia as the Engine of Application State).&amp;nbsp; You may remember HATEOAS as the thing from &lt;a href=&quot;http://en.wikipedia.org/wiki/Representational_state_transfer&quot; target=&quot;_blank&quot;&gt;REST&lt;/a&gt; that all the eggheads complained was missing from Rails’ “&lt;a href=&quot;http://guides.rubyonrails.org/v2.3.11/routing.html#restful-routes&quot; target=&quot;_blank&quot;&gt;RESTful-routes&lt;/a&gt;.” “Sure, the routes were REST but what about the discoverable URI-map?” they may have said.&amp;nbsp; They were, of course, right (jerks).&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;I’m not saying HATEOAS is perfect.&amp;nbsp; I was in the middle of adding LOTS of caching to our client so it almost never has to call our service for one of the two calls you must, at a minimum, make with a HATEOAS service. Why two calls?&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;To get the URI-map (A map of how to call the service for all resources)&lt;/li&gt;
&lt;li&gt;Actually make the call (Using the above map)&lt;/li&gt;
&lt;li&gt;What? There’s a 3? Yup, that second call could return another URI-map&lt;/li&gt;
&lt;li&gt;It could continue&lt;/li&gt;
&lt;/ol&gt;
&lt;br /&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;I know this seems insane, to make 2 or more http calls for every one request, but the benefits outweigh the costs. Old calls will always work. Less bugs. More confident software.&amp;nbsp; Also, you can cache the hell out of all the URI map requests from the client side.&amp;nbsp; When you need to expire that cache you can do it upon release of new functionality because, this being a microservice, you own all sides of the interface. Just work it into your deploy script and you’re done. Extra bonus: No URI ever has a stupid v7 in it. &amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;The last call is a bit of a bummer over http. Even servers right next to each other in the cage have important amounts of latency for many services.&amp;nbsp; HATEOAS isn’t for every service. Although, with virtual machines, I run my service on the same physical box in another vm: Somewhat mitigating network latency.&amp;nbsp; Double Extra Bonus:&amp;nbsp; My service is purely functional so I can cache all of its responses forever. That bold claim, however, is another blog post.&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;Anyway, Tripp is leaving my team to go be the king of software at some company I refuse to promote out of spite. How would you like to work at Backstop Solutions? I’m looking for a senior Ruby dev with a bunch of Clojure experience but, to be honest, I don’t really expect to find one. So if you’ve got some decent Ruby skills and can learn Clojure while pair programming you should apply.&amp;nbsp; &lt;a href=&quot;https://www.backstopsolutions.com/careers&quot;&gt;&lt;span class=&quot;s2&quot;&gt;https://www.backstopsolutions.com/careers&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;Mention you read this article in the interview and you’ll get to see a man in a crazy shirt blush.&lt;/span&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://jakescruggs.blogspot.com/feeds/854274285947506588/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1042801964488488185/854274285947506588' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1042801964488488185/posts/default/854274285947506588'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1042801964488488185/posts/default/854274285947506588'/><link rel='alternate' type='text/html' href='http://jakescruggs.blogspot.com/2015/04/microservices-vs-david-heinemeier.html' title='Microservices vs David Heinemeier Hansson'/><author><name>Jake Scruggs</name><uri>http://www.blogger.com/profile/16274380203959781950</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://farm1.static.flickr.com/200/441258345_b0379aaf00_m.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1042801964488488185.post-4279697093838322199</id><published>2014-09-16T19:46:00.000-05:00</published><updated>2014-09-16T19:46:14.408-05:00</updated><title type='text'>Why Group Texts Must Die</title><content type='html'>Recently I re-tweeted this thought from Pete Holmes:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote class=&quot;twitter-tweet&quot; lang=&quot;en&quot;&gt;
top reasons for divorce.

1984: 
1. financial problems. 2. religious differences. 

2014:
1. constant inclusion in group texts. 2. no wifi.&lt;br /&gt;
— Pete Holmes (@peteholmes) &lt;a href=&quot;https://twitter.com/peteholmes/status/511294811949641728&quot;&gt;September 14, 2014&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; charset=&quot;utf-8&quot; src=&quot;//platform.twitter.com/widgets.js&quot;&gt;&lt;/script&gt;

because I&#39;m in the middle of a communication crisis.&amp;nbsp; I do &quot;knowledge work&quot; so it’s considered inappropriate to have a device constantly making little beeps and boops while the person next to me is working on some insane LibXML (you don’t wanna know) bug.&amp;nbsp; Programming requires extreme concentration and distractions are to be avoided.&amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
The rub of it is that I’m “on call” if our software product bursts into flames.&amp;nbsp; Therefore, I must keep my phone in a mode capable of disturbing me so I don’t eat lunch, play ping-pong, or just code right through the disastrous failure of our software.&amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
This used to be fine back when text messages were either:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Time sensitive&lt;/li&gt;
&lt;li&gt;Important&lt;/li&gt;
&lt;li&gt;From one person&lt;/li&gt;
&lt;/ul&gt;
In first two cases the beeps my phone made were appropriate and in the last case I could simply text back to that person that I was busy if they didn’t get the me ignoring them hint.&amp;nbsp; However, as we all sadly know, the plague of group texts has completely disrupted how we handle notifications.&amp;nbsp; Now when my mother in-law, a nice person who likes to share, sends me and 10 other contacts a pic of a lake I spend the rest of the afternoon getting “Nice!,” “Did you take a swim?,” “No, it’s too cold”, “where are you guys?” etc. texts.&amp;nbsp; Every one of those I should probably check to make sure it isn’t an important work thing — just in case.&amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
Why not a mass email? Why do I get group texts trying to plan something days or weeks away? Shouldn’t that be an email thread?&amp;nbsp; The answer is as obvious as it is sad-making: People have given up on email.&amp;nbsp; For every &lt;a href=&quot;http://www.43folders.com/izero&quot; target=&quot;_blank&quot;&gt;Inbox Zero&lt;/a&gt; zealot, there are a hundred people who’ve essentially let their inbox run wild with clutter.&amp;nbsp; Missed important emails because of that clutter? — better move to text messages For Everything.&amp;nbsp; Of course, this leads to cluttered text messages. Plenty of times I’ve been furiously searching through my email to find someone’s reply only to remember “Oh, they’re one of those text-y people, I better scroll through all the various group texts threads they’ve been involved in… Sigh.”&lt;br /&gt;
&lt;br /&gt;
A small aside:&amp;nbsp; Some people don’t have unlimited text messages on their phone.&amp;nbsp; The horror, right?&amp;nbsp; My boss consistently crashes through her text message limit b/c of “friendly” group messages.&lt;br /&gt;
&lt;br /&gt;
The problem of communication clutter isn’t going away.&amp;nbsp; Ever. Abandoning email for texts just moves the problem.&amp;nbsp; I implore you to take charge of your inbox, people.&amp;nbsp; Getting emails you never read? Unsubscribe or Block! Can’t bring yourself to do that? Well, how about creating a rule that moves your daily…&lt;br /&gt;
&lt;br /&gt;
Hold on, got a text…&amp;nbsp; yup, a silly friendly chatty one from a friend who never emails anymore.&amp;nbsp; I really like this guy but such frivolity is a tweet or an email or a Facebook or a Whatever but not a text that demands my attention.&lt;br /&gt;
&lt;br /&gt;
Where was I…&amp;nbsp; Oh yeah, create rules in your email client of choice that automatically move “less often read” messages to a folder for later (read: never) reading. If you’re still getting a flood then you must keep going. Unsubscribing, blocking, and rules are your new watchwords. If you can’t handle this fire hose of information now what do you think is going happen when everyone can send “animated emojis” on a whim from their Apple Watch (or some other wearable computer thing)?&lt;br /&gt;
&lt;br /&gt;
Your “inbox” is not just your email inbox.&amp;nbsp; It is Every Damn Message you receive in Any form. They all via for your attention and giving up on any one communication form only annoys your friends while providing, at best, temporary relief. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Apology:&amp;nbsp; I’m sorry if you’ve sent me a group text in the past and see this as an attack.&amp;nbsp; I really do want to hear about your cats, see your kid’s pics, and ponder your stray thoughts… In an appropriate medium.&amp;nbsp; Does that sound bitchy?&amp;nbsp; </content><link rel='replies' type='application/atom+xml' href='http://jakescruggs.blogspot.com/feeds/4279697093838322199/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1042801964488488185/4279697093838322199' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1042801964488488185/posts/default/4279697093838322199'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1042801964488488185/posts/default/4279697093838322199'/><link rel='alternate' type='text/html' href='http://jakescruggs.blogspot.com/2014/09/why-group-texts-must-die.html' title='Why Group Texts Must Die'/><author><name>Jake Scruggs</name><uri>http://www.blogger.com/profile/16274380203959781950</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://farm1.static.flickr.com/200/441258345_b0379aaf00_m.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1042801964488488185.post-1244655054000776185</id><published>2014-06-09T22:53:00.000-05:00</published><updated>2014-06-09T22:53:42.624-05:00</updated><title type='text'>The Definition of Garbage</title><content type='html'>&lt;i&gt;The views and opinions expressed here are my own and don’t necessarily represent positions, strategies, or opinions of Backstop Solutions Group.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Recently we released episode 3 of the &lt;a href=&quot;http://softwareapprenticeship.libsyn.com/&quot; target=&quot;_blank&quot;&gt;Software Apprenticeship Podcast&lt;/a&gt; but had to pull it back for re-editing because of some problems with how developers talk to each other.&amp;nbsp; Developers are not kind to ANY code.&amp;nbsp; Even our own.&amp;nbsp; Especially our own.&amp;nbsp; Sitting next to a dev while he or she discusses the code they are working on can be a shocking experience.&amp;nbsp; Words like “Crap,” “Junk”, “Garbage” and many worse are used often.&amp;nbsp; A lot of this type of talk was on episode 3 and when someone at Backstop (who’s job it is to protect us from ourselves and comments taken out of context) heard it they asked us to edit the podcast to take out some of the more offensive comments. This is why episode 3 sometimes fades into music and then comes back mid-conversation.&amp;nbsp; Sorry about that.&lt;br /&gt;&lt;br /&gt;I don’t know where I first heard the definition of developer as “Whiny Optimist” but it is uncannily accurate.&amp;nbsp; We developers are forever complaining about previously written code.&amp;nbsp; Code is awful. Code is crap.&amp;nbsp; Code is the worst spaghetti wrapped around horse manure we’ve ever seen.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;And yet…&lt;br /&gt;&lt;br /&gt;We couldn’t go on if we thought we’d have to live out our lives fighting the very thing we create.&amp;nbsp; There is this optimism about future code.&amp;nbsp; It&amp;nbsp; will be bright and shiny.&amp;nbsp; The next project to re-write the &lt;whatever&gt; is going to make everything better.&amp;nbsp; So much better…&amp;nbsp; The code will be pristine and new features slide in like rum into coke.&amp;nbsp; Ponies and rainbows are coming.&lt;br /&gt;&lt;br /&gt;Also…&lt;br /&gt;&lt;br /&gt;Every year I get better at what I do, so even code I thought wonderful 3 years ago can be “crap” to me today.&amp;nbsp; I look back and see a developer who didn’t keep orthogonal concepts separate who coupled code that should not be coupled and I am sad.&amp;nbsp; I regret my past inefficiencies and curse them.&lt;br /&gt;&lt;br /&gt;But…&lt;br /&gt;&lt;br /&gt;How bad is this code really?&amp;nbsp; Backstop’s code is rigorously tested many times automatically before being poured over by humans.&amp;nbsp; Any code change in my product gets tested first on my machine (by automated tests) then on another “Build Server” (which runs the tests I was supposed to run and a bunch more), then another series of “Regression Servers” will run some even longer regression tests that literally use the app as our customers do.&amp;nbsp; If it passes all that then we’ll have our Quality Assurance people go over it again to make sure the machines haven’t missed anything.&amp;nbsp; The last thing the Q.A. people do is write a new automated regression test to make sure this functionality doesn’t break in the future.&lt;br /&gt;&lt;br /&gt;What the heck are we complaining about then?&amp;nbsp; The software works!&amp;nbsp; It helps many people make a lot of money, it makes the company money, and is a leader in the industry.&amp;nbsp; We developers are, in some ways, a bunch of ungrateful jerks. &lt;br /&gt;&lt;br /&gt;Let me see if I can explain why.&amp;nbsp; Writing software that solves hard problems is hard.&amp;nbsp; Duh. There are only so many people who can do it and we struggle through.&amp;nbsp; Writing software that solves hard problems and can continue to accept new features easily is the HOLY GRAIL of software development.&amp;nbsp; Rarely has it been done even though every company claims their code is the “best in the industry.”&amp;nbsp; If you were to get your hands on the unedited version of episode 3 you would hear a lot of developers complain how we wish we had written code in the past that could be easily changed today.&amp;nbsp; We might even call such code “garbage” but what does “garbage” really mean?&amp;nbsp; In our app it has come to mean code that works, is well tested, but resists change more than we would like.&amp;nbsp; We are whining about having to do more work.&amp;nbsp; If only our past selves had properly separated the concerns more, if only there was more time for refactoring.&amp;nbsp; But some day we will reach that shining castle on the hill.&amp;nbsp; And there will be ponies and rainbows for all.&lt;/whatever&gt;</content><link rel='replies' type='application/atom+xml' href='http://jakescruggs.blogspot.com/feeds/1244655054000776185/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1042801964488488185/1244655054000776185' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1042801964488488185/posts/default/1244655054000776185'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1042801964488488185/posts/default/1244655054000776185'/><link rel='alternate' type='text/html' href='http://jakescruggs.blogspot.com/2014/06/the-definition-of-garbage.html' title='The Definition of Garbage'/><author><name>Jake Scruggs</name><uri>http://www.blogger.com/profile/16274380203959781950</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://farm1.static.flickr.com/200/441258345_b0379aaf00_m.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1042801964488488185.post-7949928666491611737</id><published>2014-05-14T22:54:00.000-05:00</published><updated>2014-05-14T22:54:57.128-05:00</updated><title type='text'>Software Apprenticeship Podcast Episode 3 is Out</title><content type='html'>This week we start off by throwing Jonathan into the deep end of pool where he pairs with an experienced developer on a 10 year old Java project that is the core of our signature product: Backstop.&amp;nbsp; Of course the company is called &lt;a href=&quot;https://www.backstopsolutions.com/&quot; target=&quot;_blank&quot;&gt;Backstop Solutions&lt;/a&gt; and so, in order to avoid confusion, we gave the project a different name for internal use:&amp;nbsp; Fund Butter.&amp;nbsp; The mystery of how such a terrible thing came to pass is revealed in this very episode.&lt;br /&gt;&lt;br /&gt;There’s no way we couldn’t discuss DHH’s &lt;a href=&quot;http://david.heinemeierhansson.com/2014/tdd-is-dead-long-live-testing.html&quot; target=&quot;_blank&quot;&gt;Rails Conf declaration and blog post: “TDD is dead. Long live testing.”&lt;/a&gt; This, of course, leads to a discussion of our team’s test philosophy.&lt;br /&gt;
&lt;br /&gt;
You can find it on iTunes (search for Software Apprenticeship Podcast), any podcast app’s search function, Google, this temp page: &lt;a href=&quot;https://itunes.apple.com/us/podcast/software-apprenticeship-podcast/id868371146&quot;&gt;https://itunes.apple.com/us/podcast/software-apprenticeship-podcast/id868371146&lt;/a&gt; or use the RSS feed directly if your into that sort of thing: &lt;a href=&quot;http://softwareapprenticeship.libsyn.com/rss&quot;&gt;http://softwareapprenticeship.libsyn.com/rss&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;Our panel (composed of &lt;a href=&quot;https://github.com/tobytripp&quot; target=&quot;_blank&quot;&gt;Toby Tripp&lt;/a&gt;, Matt Pyra, Eric Johnson, &lt;a href=&quot;https://twitter.com/jonathanhowden&quot; target=&quot;_blank&quot;&gt;Jonathan Howden,&lt;/a&gt; and I) meander through quite a few topics.&amp;nbsp; Here’s a breakdown by time of the various topics:&lt;br /&gt;&lt;br /&gt;01:27 Backstop’s 2 day bug bash&lt;br /&gt;02:00 The apprentice has to tackle a 10 year old Java program&lt;br /&gt;06:22 “Everything needs to have an ID if you’re going to make it Hibernate-y” - Jake “super technical” Scruggs&lt;br /&gt;08:21 Why we call Backstop “Fund Butter” within the company&lt;br /&gt;10:50 The apprentice encounters &lt;a href=&quot;http://en.wikipedia.org/wiki/Selenium_%28software%29&quot; target=&quot;_blank&quot;&gt;Selenium &lt;/a&gt;&lt;br /&gt;12:42 Troubles with regression/integration testing through the web browser.&lt;br /&gt;13:43 “Unit Testing is Dead” - DHH&amp;nbsp; &lt;br /&gt;20:00 Pairing all the time vs code review&lt;br /&gt;21:51 Toby talks about the Hill Air Force Base pair programming study mentioned here: &lt;a href=&quot;http://www.informit.com/articles/article.aspx?p=29410&quot; target=&quot;_blank&quot;&gt;http://www.informit.com/articles/article.aspx?p=29410 &lt;/a&gt;&lt;br /&gt;26:40 The Wall of Awesome - Backstop’s way for employee’s to recognize and thank other employees&lt;br /&gt;47:21 The anti-college movement &lt;br /&gt;49:36 The &lt;a href=&quot;http://redsquirrel.com/dave/work/a2j/patterns/ExposeYourIgnorance.html&quot; target=&quot;_blank&quot;&gt;“Expose your ignorance” apprenticeship pattern&lt;/a&gt; with examples/confessions from Jonathan, Jake, and Toby&lt;br /&gt;51:14 The &lt;a href=&quot;http://en.wikipedia.org/wiki/Chrysler_Comprehensive_Compensation_System&quot; target=&quot;_blank&quot;&gt;C3&lt;/a&gt; project comes up with near 100% frequency when &amp;gt;= 2 die hard XP&#39;ers are in the same room. </content><link rel='replies' type='application/atom+xml' href='http://jakescruggs.blogspot.com/feeds/7949928666491611737/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1042801964488488185/7949928666491611737' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1042801964488488185/posts/default/7949928666491611737'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1042801964488488185/posts/default/7949928666491611737'/><link rel='alternate' type='text/html' href='http://jakescruggs.blogspot.com/2014/05/software-apprenticeship-podcast-episode.html' title='Software Apprenticeship Podcast Episode 3 is Out'/><author><name>Jake Scruggs</name><uri>http://www.blogger.com/profile/16274380203959781950</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://farm1.static.flickr.com/200/441258345_b0379aaf00_m.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1042801964488488185.post-1469270652908528212</id><published>2014-04-28T20:52:00.000-05:00</published><updated>2014-04-28T20:52:18.999-05:00</updated><title type='text'>Announcing the Software Apprenticeship Podcast</title><content type='html'>In the summer of 2004 I did an apprenticeship of sorts at a place called Object Mentor.&amp;nbsp; At the time “Uncle” Bob Martin and his son Micah Martin were in leadership positions at the company and I somehow convinced them to let me work for free over the summer in exchange for teaching me software development. It wasn’t a very structured program, nothing like what Micah would later put together for &lt;a href=&quot;http://www.8thlight.com/apprenticeship&quot; target=&quot;_blank&quot;&gt;8th Light&lt;/a&gt;, but I was a pretty motivated learner.&amp;nbsp; I also had the advantage of coming from a teaching background so I knew how to learn.&lt;br /&gt;
&lt;br /&gt;
All this has been covered in daily detail, if you&#39;d like to read &lt;a href=&quot;http://jakescruggs.blogspot.com/search/label/Apprenticeship&quot; target=&quot;_blank&quot;&gt;more.&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
After ten years of software experience I’m becoming a mentor to an apprentice and documenting the experience via podcast.&amp;nbsp; &lt;a href=&quot;https://backstopsolutions.com/&quot; target=&quot;_blank&quot;&gt;Backstop Solutions&lt;/a&gt; has graciously allowed me to pay our apprentice (the same rate we pay interns) as he is doing real work on a daily basis in addition to outside learning experiences.&amp;nbsp; From 9-5 he will be working on production code with 100% supervision as he will always be pairing with an experienced developer.&amp;nbsp; It’s a six month program with 2 month check-ins.&amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
The apprentice, &lt;a href=&quot;https://twitter.com/jonathanhowden&quot; target=&quot;_blank&quot;&gt;Jonathan Howden&lt;/a&gt;, knows that should he fail to meet expectations we may end our relationship at 2, 4, or 6 months.&amp;nbsp; This is a bit scary, but if &lt;a href=&quot;https://backstopsolutions.com/&quot; target=&quot;_blank&quot;&gt;Backstop&lt;/a&gt; is going to be taking a chance on an un-credentialed employee we, as a company, need to be able mitigate the risk of such a person polluting our codebase.&amp;nbsp; It is therefore our responsibility to provide constant feedback to the apprentice so that he will know exactly what is needed to succeed.&amp;nbsp; So far he’s been doing great: He just finished his 3rd week of apprenticeship so we just recorded our third podcast and will be on a weekly schedule. Assuming he survives the six month apprenticeship, Jonathan will be offered a full time job at a damn good starting salary.&amp;nbsp; Interested in such a job right now? Check out &lt;a href=&quot;https://careers.backstopsolutions.com/&quot;&gt;https://careers.backstopsolutions.com/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
In the first episode, Jonathan talks quite a bit about &lt;a href=&quot;http://devbootcamp.com/&quot; target=&quot;_blank&quot;&gt;Dev Bootcamp&lt;/a&gt; (DBC).&amp;nbsp; I’ve known, worked with, and read the &lt;a href=&quot;http://www.amazon.com/Apprenticeship-Patterns-Guidance-Aspiring-Craftsman/dp/0596518382/&quot; target=&quot;_blank&quot;&gt;book&lt;/a&gt; of one of the founders so it seemed natural to reach out to Dave Hoover and DBC to help Backstop find its first apprentice.&amp;nbsp; We asked their “fairy job mother” to spread the word that we were looking for apprentices and ten applied.&amp;nbsp; They were all given coding homework challenges which were evaluated code review style with the whole &lt;a href=&quot;https://www.backstopsolutions.com/investorbridge&quot; target=&quot;_blank&quot;&gt;InvestorBridge&lt;/a&gt; team allowed to attend.&amp;nbsp; We judged three submissions good enough to warrant an in-person interview.&amp;nbsp; Jonathan made it through this gauntlet and was rewarded with a brand new, much longer, gauntlet.&amp;nbsp; Of learning.&amp;nbsp; Look, there&#39;s no way not to make this sound hokey as we&#39;re trying to do a good thing here.&lt;br /&gt;
&lt;br /&gt;
On a weekly basis I hope to capture what an apprenticeship is from the inside and perhaps provide some value to proto-developers and prospective mentor companies who may be wondering what this “apprenticeship” business is all about.&amp;nbsp; Changing careers is, like it or not, the future.&amp;nbsp; I did it in 2004 and I hope Jonathan will too in 2014.&lt;br /&gt;
&lt;br /&gt;
Software Apprenticeship Podcast:&lt;br /&gt;
iTunes Page: &lt;a href=&quot;https://itunes.apple.com/us/podcast/software-apprenticeship-podcast/id868371146?mt=2&quot;&gt;https://itunes.apple.com/us/podcast/software-apprenticeship-podcast/id868371146?mt=2&lt;/a&gt;&lt;br /&gt;
RSS feed: &lt;a href=&quot;http://softwareapprenticeship.libsyn.com/rss&quot;&gt;http://softwareapprenticeship.libsyn.com/rss&lt;/a&gt;&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://static.libsyn.com/p/assets/b/d/2/d/bd2d90219333eac7/software_apprenticeship.jpg&quot; height=&quot;320&quot; title=&quot;&quot; width=&quot;320&quot; /&gt;&lt;/div&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://jakescruggs.blogspot.com/feeds/1469270652908528212/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1042801964488488185/1469270652908528212' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1042801964488488185/posts/default/1469270652908528212'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1042801964488488185/posts/default/1469270652908528212'/><link rel='alternate' type='text/html' href='http://jakescruggs.blogspot.com/2014/04/announcing-software-apprenticeship.html' title='Announcing the Software Apprenticeship Podcast'/><author><name>Jake Scruggs</name><uri>http://www.blogger.com/profile/16274380203959781950</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://farm1.static.flickr.com/200/441258345_b0379aaf00_m.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1042801964488488185.post-6308692382946239188</id><published>2014-02-27T21:38:00.001-06:00</published><updated>2014-02-27T21:38:48.514-06:00</updated><title type='text'>SICP Wasn’t Written for You</title><content type='html'>The number of software luminaries who sing the praises of “&lt;a href=&quot;http://en.wikipedia.org/wiki/Structure_and_Interpretation_of_Computer_Programs&quot; target=&quot;_blank&quot;&gt;Structure and Interpretation of Computer Programs&lt;/a&gt;” (referred to as SICP) is such a long list that you might think only a crazy person would take issue with it. However, to ignore SICP’s problems and continue to blindly recommend it seems just as crazy.&lt;br /&gt;&lt;br /&gt;SICP was the textbook for MIT’s introductory programming class and was a bit of a departure from other into to computer science textbooks at the time.&amp;nbsp; Wikipedia sums it up nicely:&amp;nbsp; “Before SICP, the introductory courses were almost always filled with learning the details of some programming language, while SICP focuses on finding general patterns from specific problems and building software tools that embody each pattern.”&amp;nbsp; Which sounds awesome, but does essentially say that abstract principles will be introduced before the nuts and bolts of a language.&amp;nbsp; If you think about that for a minute, you may see where the problems will be.&lt;br /&gt;&lt;br /&gt;When I was training to be a teacher I took a bunch of education courses.&amp;nbsp; I got good grades but when I got into the classroom to actually teach I flailed around just trying to keep the class under control and mostly forgot to apply the principles I had learned.&amp;nbsp; The knowledge was in my head, but it floated, disconnected, from anything in particular.&amp;nbsp; When I learned these ideas I had no teaching experience, and so, nowhere to place these abstract principles.&lt;br /&gt;&lt;br /&gt;SICP’s first chapter explains the basic form of Scheme (a Lisp), some basic operators (+, -, *, /, etc), defining/calling a function, different ways a compiler might evaluate code, and conditionals over the course of a few short pages.&amp;nbsp; That’s a bit much to swallow all at once, especially the comparative evaluation stuff but that should be easily sorted out with some examples. Right?&amp;nbsp; Well, that’s not really SICP’s thing. SICP will give you a few trivial examples and then toss you right into the deep end. Then first 2 problems for the reader are pretty easy, but it’s the 3rd that will let you know what yer in for: “Define a procedure that takes three numbers as arguments and returns the sum of the squares of the two larger numbers.” Which seems pretty easy until you realize there are no variables.&amp;nbsp; You’ll need to figure out an algorithm that can take 3 numbers and, without any intermediate state storage, return the 2 biggest numbers in such a way that you can sum their squares.&amp;nbsp; I’ll be real honest here, after about 30 min of trying to do this (I have zero functional background so I’m a complete novice here) I gave up and tracked down the answer online.&amp;nbsp; Of course the answer was simple and concise and made me feel like a chump.&amp;nbsp; Which is fine, but not really what I was expecting in the first chapter, let alone the 3rd problem of the entire book.&lt;br /&gt;&lt;br /&gt;But that’s what SICP is all about -- challenging problems. The rest of the chapter introduces Newton’s method for square/cube roots and lexical scoping just for fun. Chapter 2 is recursion vs iteration in terms of execution speed, resource usage, and transforming from one to the other.&amp;nbsp; Logarithmic, linear, and exponential growth are dealt with in a few paragraphs and then we’re off to Exponentiation, Greatest Common Divisors, Primality, and implementing Fermat&#39;s Little Theorem for probabilistic prime determination. My favorite question from chapter 2 asks the reader to formulate an inductive proof that Fib(n) is the closet integer to ((golden ratio)^n)/5.&lt;br /&gt;&lt;br /&gt;Which brings me to another criticism of SICP:&amp;nbsp; It assumes a familiarity with math that most people just don’t have. A first year MIT student would probably be swimming in math classes so the book assumes that knowledge on the readers part.&amp;nbsp; Abstract programming principles can be very difficult to find examples for so I’m sympathetic to the plight of the authors, but when you just go straight at math you’re explaining an abstract thing with another abstract thing.&lt;br /&gt;&lt;br /&gt;There’s a certain sort of person who gets excited by complicated abstract but internally consistent logic with no real connection to the concrete.&amp;nbsp; In my experience as a physics teacher, these students do exist but are very rare. Most people need a bit of connection to something tangible in order to have the ideas connect in their brain.&lt;br /&gt;&lt;br /&gt;What then is my point about SICP?&amp;nbsp; Simply that its explanations are overly terse and its problems are large steps past what little is explained.&amp;nbsp; In light of those things I have recommendations for those who attempt to work through it.&lt;br /&gt;&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;If you intend to do every problem, realize that this will take a LONG time and involve a bunch of research.&lt;/li&gt;
&lt;li&gt;Set a time-box for how long you’re going to spend on a problem before you go look up the answer.&amp;nbsp; If you’ve spent enough time trying to solve a problem you will still value the answer enough to remember it. 30 min is a good number.&amp;nbsp; Increase or decrease as your sanity allows. &lt;/li&gt;
&lt;li&gt;If you feel like something hasn’t been explained:&amp;nbsp; You’re probably right.&amp;nbsp; After you find the answer, a close re-reading will reveal a cryptic sentence that you now realize was trying to tell you something. This will infuriate you and is perfectly normal.&lt;/li&gt;
&lt;li&gt;Work through the book with a group.&amp;nbsp; This will hopefully allow you to commiserate about how lost you are and get some help.&amp;nbsp; If there’s someone in there that loves this book and thinks everything is explained perfectly, ignore them.&amp;nbsp; If they subtly imply that you’re stupid for not getting it:&amp;nbsp; Leave the group.&amp;nbsp; You don’t need that static in your life.&lt;/li&gt;
&lt;li&gt;Do not feel bad about not knowing all this math stuff:&amp;nbsp; Remember that this book was written for students who would be surrounded by math at the time they read it.&lt;/li&gt;
&lt;li&gt;Consider learning Lisp before starting this book.&amp;nbsp; The really important concepts in the book come easier if you’re not also learning Lisp at the same time&lt;/li&gt;
&lt;/ul&gt;
</content><link rel='replies' type='application/atom+xml' href='http://jakescruggs.blogspot.com/feeds/6308692382946239188/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1042801964488488185/6308692382946239188' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1042801964488488185/posts/default/6308692382946239188'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1042801964488488185/posts/default/6308692382946239188'/><link rel='alternate' type='text/html' href='http://jakescruggs.blogspot.com/2014/02/sicp-wasnt-written-for-you.html' title='SICP Wasn’t Written for You'/><author><name>Jake Scruggs</name><uri>http://www.blogger.com/profile/16274380203959781950</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://farm1.static.flickr.com/200/441258345_b0379aaf00_m.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1042801964488488185.post-2850506625953831384</id><published>2012-08-08T20:16:00.001-05:00</published><updated>2012-08-08T20:17:31.893-05:00</updated><title type='text'>Why I abandoned MetricFu</title><content type='html'>My last commit to &lt;a href=&quot;http://metric-fu.rubyforge.org/&quot; target=&quot;_blank&quot;&gt;MetricFu&lt;/a&gt; was March 2...&amp;nbsp; of 2011.&amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
So. &lt;br /&gt;
much.&lt;br /&gt;
shame.&lt;br /&gt;
&lt;br /&gt;
Since I am throwing in the towel and handing over leadership (perhaps to you), I thought I should explain why I&#39;ve been such a terrible maintainer and why I&#39;m walking away. &lt;br /&gt;
&lt;br /&gt;
Reasons:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;1). MetricFu is a mess.&amp;nbsp; At some point, with all the submissions coming in, the architecture and testing got away from me.&amp;nbsp; Now it&#39;s pretty depressing to see crap code quality in an app that is supposed to be about good code quality.&amp;nbsp; I can not overstate how embarrassing and frustrating this is – mostly because it&#39;s my fault (I let in things I shouldn&#39;t have. Stupid feature blindness).&lt;/li&gt;
&lt;li&gt;2). In 2008, when I created MetricFu, I was fascinated by metrics and now I&#39;m not because I don&#39;t need the tools to see the problems anymore.&amp;nbsp; Metrics made me better but now I&#39;m leaving them behind:&amp;nbsp; Selfish.&lt;/li&gt;
&lt;li&gt;3). I&#39;m not a consultant at the moment so the exploratory nature of MetricFu isn&#39;t very useful to me.&amp;nbsp; I know where the bad parts of town are in my app.&lt;/li&gt;
&lt;li&gt;4). I think metrics can be a great teaching tool, but you can learn all the wrong things if you&#39;re not careful. You can reduce Flog scores without making the app better (Simple: arbitrarily divide up every large method) . Same with code coverage. Even code duplication detection can lead to bad code.&amp;nbsp; DRY-ing things up in a bad way can often be much more harmful then leaving them moist (perhaps you removed some duplication by creating a crazy amount of indirection – a common problem).&lt;/li&gt;
&lt;li&gt;5). Ultimately, creating software is a craft.&amp;nbsp; It&#39;s not pure science and it&#39;s not pure art, it&#39;s a combination of both.&amp;nbsp; MetricFu leans a too little hard toward numbers and that implies a precision we just don&#39;t have. How to get from bad code to good is a very delicate dance between content, form, and business requirements.&lt;/li&gt;
&lt;li&gt;6). Integrating over a dozen meta-code gems is a god damn pain.&amp;nbsp; The gems that make up metric_fu use code to analyze code (intense meta Ruby) and so they sometimes conflict.&amp;nbsp; Also since MetricFu mostly uses regexes to parse the (command line or html) output, every change in one of MetricFu&#39;s underlying gems means that MetricFu needs a version bump.&amp;nbsp; &lt;/li&gt;
&lt;li&gt;7). The last year has been, personally, very busy and difficult for me.&lt;/li&gt;
&lt;/ul&gt;
For these reasons I&#39;m going to be stepping aside as metric_fu maintainer – I&#39;ll still be around to answer questions and such but I probably won&#39;t be contributing much code.&amp;nbsp; If I&#39;ve somehow disappointed or frustrated you because of last year&#39;s neglect then I apologize. Seriously.&amp;nbsp; I&#39;m sorry.&lt;br /&gt;
&lt;br /&gt;
Want to lead MetricFu? Make your case in the metric_fu google group:&lt;br /&gt;
&lt;a href=&quot;https://groups.google.com/forum/?fromgroups#%21forum/metric_fu&quot; target=&quot;_blank&quot;&gt;https://groups.google.com/forum/?fromgroups#!forum/metric_fu&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://jakescruggs.blogspot.com/feeds/2850506625953831384/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1042801964488488185/2850506625953831384' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1042801964488488185/posts/default/2850506625953831384'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1042801964488488185/posts/default/2850506625953831384'/><link rel='alternate' type='text/html' href='http://jakescruggs.blogspot.com/2012/08/why-i-abandoned-metricfu.html' title='Why I abandoned MetricFu'/><author><name>Jake Scruggs</name><uri>http://www.blogger.com/profile/16274380203959781950</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://farm1.static.flickr.com/200/441258345_b0379aaf00_m.jpg'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1042801964488488185.post-5740749811748733602</id><published>2010-12-07T09:50:00.004-06:00</published><updated>2010-12-07T10:33:50.734-06:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="oracle"/><category scheme="http://www.blogger.com/atom/ns#" term="Rails"/><category scheme="http://www.blogger.com/atom/ns#" term="testing"/><title type='text'>Oracle Foreign Key without Index Test</title><content type='html'>We&#39;ve been having some Oracle deadlock issues that have been hard to reproduce locally. After a lot of investigation and solving of important problems that happened not to be THE problem we figured out that while we&#39;ve been pretty good creating integrity constraints in the database we have not been very good about making sure that every foreign key has a corresponding index.  And that can lead to problems.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So we had a situation were our documents table had a foreign key on the accounts table that was not indexed.  So updating an account row lead to a whole table lock on documents (instead of just a row lock which would have happened if there was an index) and that was very bad when we had two separate processes where one was doing a bunch of accounts stuff and the other was doing a lot of documents stuff.  Deadlocks for everyone! &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The sad thing is that if we had just drank the Rails cool-aid about having no integrity constraints in the db we would have been fine but we got into trouble by only implementing constraints and not the indexes they work much better with. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So we found this cool bit of SQL that helped us find all the foreign keys missing an index here: &lt;a href=&quot;http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:4530093713805#26568859366976&quot;&gt;http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:4530093713805#26568859366976&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And that help us solve the deadlock problem.  But what about the future?  If only there was a way to run this check periodically and automatically...  Time for a test!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;script src=&quot;https://gist.github.com/731989.js?file=indexes_on_foreign_keys_test.rb&quot;&gt;&lt;/script&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;As an additional bonus, the failing output of the test tells you how to write the index you need. Big thanks to &lt;a href=&quot;http://twitter.com/#!/davebortz&quot;&gt;Dave Bortz&lt;/a&gt; for tracking down this problem -- I just swooped in and wrote the test.  And took credit in this here blog.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jakescruggs.blogspot.com/feeds/5740749811748733602/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1042801964488488185/5740749811748733602' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1042801964488488185/posts/default/5740749811748733602'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1042801964488488185/posts/default/5740749811748733602'/><link rel='alternate' type='text/html' href='http://jakescruggs.blogspot.com/2010/12/oracle-foreign-key-without-index-test.html' title='Oracle Foreign Key without Index Test'/><author><name>Jake Scruggs</name><uri>http://www.blogger.com/profile/16274380203959781950</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://farm1.static.flickr.com/200/441258345_b0379aaf00_m.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1042801964488488185.post-9058791524994487093</id><published>2010-08-28T23:09:00.010-05:00</published><updated>2010-08-29T06:59:22.833-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="RubyKaigi2010"/><title type='text'>Ruby Kaigi 2010 Day 3</title><content type='html'>&lt;div&gt;Last day of Ruby Kaigi! Sad to see it go, it&#39;s been a great conference. As per usual Tweets are in bulleted italics and the rest is after the fact commentary.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;First I&#39;ve got to show you the commemorative fans they were handing out:&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://www.flickr.com/photos/jakescruggs/4934685088/&quot; title=&quot;It&#39;s the creators of Ruby and PHP by jake_scruggs, on Flickr&quot;&gt;&lt;img src=&quot;http://farm5.static.flickr.com/4095/4934685088_0308fb60c3.jpg&quot; width=&quot;375&quot; height=&quot;500&quot; alt=&quot;It&#39;s the creators of Ruby and PHP&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It&#39;s Matz and... Someone else (sorry if it&#39;s obvious - I don&#39;t know).  And of course they are programing in the bath.&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;BigDecimal: You can handle numbers as large as can fit into memory as opposed to the IEEE double #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;BigMath is the Math module for BigDecimal #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;Lots of different rounding modes in BigDecimal #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;BigDecimal.mode is global per process - not thread safe #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;So BigDecimal is Fiber unsafe #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;Bummer.&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;.@mrkn implemented a solution storing mode in thread local #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;Oh good.  Wait, is that in 1.9.2 or trunk. I&#39;d have to be in 1.9.2 right? To the Google! ... Yep, seems like it made it in: &lt;a href=&quot;http://redmine.ruby-lang.org/issues/show/3285&quot;&gt;http://redmine.ruby-lang.org/issues/show/3285&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;You can now change modes in a block (added to trunk yesterday) #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;Effective digits/ Significant digits determines which digits to keep and which to round off #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;BigDecimals don&#39;t know their own effective digits #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;But I think the point of talking about sig figs was that it&#39;s coming soonish in Ruby. 1.9.3?&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;It is dangerous to mix floats and BigDecimals #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;BigDecimals can&#39;t convert from rational, integer, or float. just strings #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;And you can&#39;t do BigDecimal(BigDecimal) !! #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;That is one crappy interface. Taking in only strings is frustrating and weird. How did this happen?&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;Now a preview of the future of BigDecimal #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;No library for irrational numbers in Ruby #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;Perhaps we can represent irrational numbers as algorithms and on convert when needed. #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;BigDecimals don&#39;t have real significant digits implemented right now. #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;The issue of BigDecimal not being able to handle anything other than a string as input will be fixed as it is a bug #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;The irrational numbers thing sounds pretty cool.  Since I mostly sling around strings for my day job I don&#39;t know that I&#39;ll ever use it.  But purely for Ruby pride I like to see ruby challenge Python&#39;s rising dominance in the sciences and maths.&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;I really don&#39;t like the lack of travel time between session. You should have at least 5 minutes to change sessions. #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;Look, this has been a great conference and any slights I&#39;ve tended to overlook because they&#39;ve really done a heroic job of keeping the admission price down but that lack of a passing period is just...  Well I don&#39;t see why they did it.  Just having the time as a buffer in case talks run over is reason alone.  Moreover, no passing period traps people in sessions that they&#39;d rather not be in and restricts choice.&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;Apparently there is a lot of chatter in IRC by ruby commiters that NArray should be added to strd lib. #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;NArray is 28x faster and uses 8x less characters in 1.9.2 #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;NArray is faster than what? Array, I assume, but I may not be following the translation correctly. #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;Translation is volunteer and best-effort so it adds some challenge to attending sessions in a foreign language. So if I make any mistakes in this here blog, that&#39;s what I&#39;m blaming it on.&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;Pwrake is parallel distributed Rake - being developed here in Tsukuba. #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;Just a little tidbit dropped at the end of the NArray presentation -- sounds pretty cool.  Masahiro Tanaka is using it drive his workflow in his scientific research.&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;yarv2llvm tries to speed up Ruby by implementing type inference (yarv is the vm for 1.9x) #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;There are times in Ruby when type can not be inferred and in those cases yarv2llvm is often slower than Ruby 1.9x #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;Fixnum overflow to BigNum is one of the hardest problems to solve #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;Btw, I think the title of this talk: &quot;How Did Yarv2llvm Fail&quot; is wonderful. Way to keep everything above board. #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Great talk and very honest. The type inference thing looks promising but there are a couple of tough hurdles to clear.  Maybe some day.  Until then there&#39;s always &lt;a href=&quot;http://github.com/headius/mirah&quot;&gt;Mirah&lt;/a&gt;.&lt;/div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;Ruby AOT complier is &quot;mostly compatible&quot; with Ruby 1.9 #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;AOT == &quot;Ahead of time&quot;&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;Ruby AOT compiler is passing 7847 of 7850 Ruby Spec tests as of now. #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;On average Ruby AOT compiler is 3.5x faster than 1.9 for common benchmarks #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;Cool, let&#39;s all move to Ruby AOT!&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;It doesn&#39;t fair quite so well in the real world Ex: Rails. Slightly slower than 1.9 #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;Something about cache misses makes it slower #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;The Ruby AOT compiler team wants to reduce the generated code size to increase speed. #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;Rails can be compiled in 77 min and size of compiled code is 92MB with Ruby AOT #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;Oh.  Never mind. Plus, compiling.  Boo. Hiss.&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;This memory profiler&#39;s gui looks amazing! #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;Seriously, this is the sexiest profiler ever #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;Can attach to running Ruby programs from another machine #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;Designed to have as small as possible impact and be easy to use #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;I gotta tell ya the audience was chomping at the bit to get a hold of this profiler.  You can run it in production for christ&#39;s sake!  And the GUI is to die for.&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;Not available yet!?! #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;Needs to get patch accepted into ruby core - maybe in 1.9.3. RATS! #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;Very cruel of Tetsu Soh not to mention this up front.  I&#39;m sure it was an oversight but everyone was crazy disappointed.  Still this was one of the best talks of the conf.  Tetsu Soh is one to watch.&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;Dear Ruby Core please, please, please, please, please, please, please, please accept Tetsu Soh memory profiler patch #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;Indeed. I&#39;m famous (on the internet (in one corner)) so you should listen to me.&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;Lots of requests to publish Tetsu Soh&#39;s memory profiler on Github. I agree! #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;Automatic sliding doors in Japan trigger much latter than Americans would expect leading to a lot of stopping and hand waving&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;I&#39;m not the only one who noticed this so I&#39;m not crazy.&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;More awesome techno in the #rubykaigi main hall. I want, nay, need the playlist.&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;Please post it on the &#39;Goodies&#39; section of the Ruby Kaigi site.  Or tweet about it.  Something.&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;Shay Friedman has spent the first five minutes of his talk apologizing for being associated with Microsoft. Stop. #rubykaigi&lt;/i&gt;  &lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;There was this weird hostile vibe coming from Shay.  I felt like he hated us for liking Apple products.  The weird thing is that there are a lot fewer Apple computers here than at a normal Ruby Conf.  Maybe he thought we were all Microsoft haters and so he might as well fire first.  Seemed like a mistake.&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;Just saw a nice hello world creating windows and dialog boxes in IronRuby #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;IronRuby currently passes 85% of Ruby Spec. #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;IronRuby 1.0 is 1.8.6 compatible. 1.1 (coming soon) will be 1.9.2 compatible. #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;Windows Presentation Foundation&#39;s view templates are written in xaml which is like html. #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;Another markup language because we needed more. I feel like the IronRuby team really needs a win. They&#39;ve been the slowest progressing Ruby VM for a long time now.&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;&amp;lt;script language=&quot;ruby&quot;&amp;gt; Whaa? Gestalt hides a hidden bit of Silverlight in the page so you can replace Javascript with Ruby. #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Pretty neat trick that. Of course it means making your site dependent on silverlight. No worse than depending on Flash I guess.&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;IronRuby.Rack is Rack implementation on ASP. Currently in beta. #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;It&#39;s all coming along, I&#39;d just like to see something working at this point in its life.&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;If key is symbol then only one instance - less object creation. Which is why everyone uses symbols. Or because everyone else does #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;So did you know why everyone uses symbols?  Or did you just do it because that&#39;s the convention. Yeah, me too but then I learned. I&#39;m not going to say how long ago that was.&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;Presenter&#39;s computer went down and it&#39;s taking forever to reboot. Stupid Mac. #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;That&#39;s one of those rough moments where you really feel bad for the presentor. But he handled it like a champ -- continuing the presentation while he waited for his machine to boot back up. Well done. I wish I got more out of the talk but it was one of those inspirational talks that are hard to translate.  The Japanese speaking audience seemed to love it.&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;Please use the overburdened network to download the english version of the slides. Umm... What? #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;Huh.  Why did that seem like a good idea. Since when does asking a room full of people to download something all at once ever work. And yet, it seems it happens once a conference. Repeat after me: Never ever depend on the network at a conference.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Funny story time.  All through the conference I spent a lot of time staring at the IRC screens on either side of the stage where the translations happen.  But since it&#39;s just IRC, anyone can join the room.  There was this one guy who posted A LOT and everyone of the posts seemed to be either:&lt;/div&gt;&lt;div&gt;888888888888&lt;/div&gt;&lt;div&gt;or&lt;/div&gt;&lt;div&gt;wwwwwwwwww&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I later found out that 888888 means clapping and wwwww means laughter. OK but stop cluttering  up the screen that I&#39;m trying to read translations off of.  Then I found out who sora_h was: He&#39;s 14 and his name is Shota Fukumori.  He got up and gave an entertaining lightning talk.  Turns out he&#39;s a Ruby commiter so he&#39;s got that on me.&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://www.flickr.com/photos/jakescruggs/4934686542/&quot; title=&quot;Young programmer by jake_scruggs, on Flickr&quot;&gt;&lt;img src=&quot;http://farm5.static.flickr.com/4080/4934686542_10cf9b178b.jpg&quot; width=&quot;500&quot; height=&quot;375&quot; alt=&quot;Young programmer&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And, all of a sudden, it was time for the final keynote by Chad Fowler.  He gave a talk about how to live a remarkable life and it was good stuff.&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;The two things that are necessary to live a remarkable life are: To have intention and a system of realizing that intention #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;Living intentionally means being mindful of your actions. It&#39;s easy to coast through life. #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;&quot;My co-workers laughed at me when I learned Ruby&quot; - Chad Fowler #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;&quot;You don&#39;t want to be in a situation where you are competing on price&quot; - Chad Fowler #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;Programming Cobol is like working in a hospice. There&#39;s a market for that. - Chad Fowler #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;&quot;Always be the worst musician in whatever band you&#39;re in&quot; Pat Matheney #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;&quot;If you&#39;re playing things that sound good then you&#39;re not practicing&quot; lesson from music that applies to programming #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;&quot;I needed a project that was useless&quot; - Chad Fowler #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;&quot;Was today better than yesterday?&quot; All you have to do is get a little better every day #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;&quot;Passion is a resource that you have to conserve&quot; - Chad Fowler #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;Lots of gems in there.&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;RubyKaigi 2011 will be in July and in Tokyo. #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;There was something about the theme being &quot;The Last Ruby Kaigi&quot; but I think it was sort of a joke making fun of some guy who posted a rant about how the Ruby Kaigis need to end.  I didn&#39;t have enough background to get it.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Oh, I forgot to talk about the guy hawking &quot;The Last Google Wave Book Ever Published.&quot;  It seems he had been working on a Google Wave book and it was printed on the same day Google announced the end of wave.  His response?  To shamelessly promote the book at Ruby Kaigi in a lightning talk, at some sort of hallway session (with 30 people gathered around), and pretty much everywhere else.  And I actually saw some people carrying the book around.  Did they buy it?  Who knows -- his positive personality was so powerful I wouldn&#39;t be surprised if they did.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;a href=&quot;http://www.flickr.com/photos/jakescruggs/4937081377/&quot; title=&quot;The Last Google Wave book ever published by jake_scruggs, on Flickr&quot;&gt;&lt;img src=&quot;http://farm5.static.flickr.com/4116/4937081377_5fc3029114.jpg&quot; width=&quot;500&quot; height=&quot;375&quot; alt=&quot;The Last Google Wave book ever published&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Ruby Kaigi was an excellent time.  I thought it might be crazy intimidating but everyone was super nice and there were enough english speakers so that I could always get my ideas across.  Go if you have the chance.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Also, check out my every growing set of Ruby Kaigi photos at Flickr:&lt;/div&gt;&lt;div&gt;&lt;a href=&quot;http://www.flickr.com/photos/jakescruggs/sets/72157624815648014/&quot;&gt;http://www.flickr.com/photos/jakescruggs/sets/72157624815648014/&lt;/a&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jakescruggs.blogspot.com/feeds/9058791524994487093/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1042801964488488185/9058791524994487093' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1042801964488488185/posts/default/9058791524994487093'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1042801964488488185/posts/default/9058791524994487093'/><link rel='alternate' type='text/html' href='http://jakescruggs.blogspot.com/2010/08/ruby-kaigi-2010-day-3.html' title='Ruby Kaigi 2010 Day 3'/><author><name>Jake Scruggs</name><uri>http://www.blogger.com/profile/16274380203959781950</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://farm1.static.flickr.com/200/441258345_b0379aaf00_m.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://farm5.static.flickr.com/4095/4934685088_0308fb60c3_t.jpg" height="72" width="72"/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1042801964488488185.post-4706721565901105774</id><published>2010-08-28T07:27:00.008-05:00</published><updated>2010-08-28T08:38:17.137-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="RubyKaigi2010"/><title type='text'>Ruby Kaigi 2010 Day 2</title><content type='html'>Holy crap am I tired.  It&#39;s been a long awesome day. It started out with some excitement:&lt;div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;Just found out I have an hour time slot when all I prepared was 30 minutes. Ok, time to write some more. #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;Panic! Maybe I&#39;ll talk about metric_fu a bit. #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;I must have looked at that schedule 20 times and never realized that I had an hour slot.  Everyone else had 30 minutes so I thought I did too.&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;Attendees of &quot;The Importance and Implementation of Speedy Tests&quot; will also get &quot;Metrics Based Refactoring&quot; at no additional cost! #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;I did something I almost never do:  Look at crisis as an opportunity (crisi-tunity).  I had to write &quot;Metrics Based Refactoring&quot; anyway for Windy City Rails so why not write it now.  In less than 4 hours.  While watching my friends present at a conference.  Looking over those sentences now I can&#39;t believe I didn&#39;t freak out.&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;Ted Han used publicly available data to settle reviewing bais accusations against &quot;The Edge&quot; of hating the PS3 #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;Turns out there was no bais. Math to the rescue! #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;bais? bias? baise? no idea.&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;You are probably not surprised to find out that I can&#39;t spell.  Even Eito Katagiri, who did a wonderful job translating my slides, found a bunch of spelling errors and English is not his first language.&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;I just pulled out a table in the main hall and the table police where all over me. My mistake. Sorry. #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;There were announcements everywhere about not doing this and yet I did.  In my defense: I&#39;m an idiot.&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;They&#39;re giving out an award to the person who committed most to Ruby 1.9.2: Yusuke Endoh #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;A very nice gesture.  Lots of class here at Ruby Kaigi.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Time for Matz&#39;s keynote!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;Matz is talking about Ruby 2.0... again. #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;This topic is a staple of Matz&#39;s speaking career.  I think the first time I saw him talk, years ago, he was talking about Ruby 2.0. Someday...&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;&quot;Right now ruby is just good enough&quot; - Matz #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;Matz hates local variable propagation (the lack thereof) but no one else seems to care so he&#39;s abandoning it. #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;Ruby&#39;s private is not private: it can be accessed from subclasses and overridden by accident #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;Monkey patching modifies the class globally. #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;Classbox is the solution to global monkey patching #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;Lots of talk about the mysterious &#39;classbox.&#39;  What is it?  Well here&#39;s a paper on the subject:&lt;/div&gt;&lt;div&gt;&lt;a href=&quot;http://www.iam.unibe.ch/~scg/Archive/Papers/Berg05aclassboxes.pdf&quot;&gt;http://www.iam.unibe.ch/~scg/Archive/Papers/Berg05aclassboxes.pdf&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And some pertinent lines from the abstract:&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;...Unfortunately existing approaches suffer from various limitations. Either class extensions have a global impact, with possibly negative effects for unexpected clients, or they have a purely local impact, with neg- ative results for collaborating clients. Furthermore, conflicting class extensions are either disallowed, or resolved by linearization, with consequent negative effects. To solve these problems we present classboxes, a module system for object-oriented lan- guages that provides for method addition and replacement. Moreover, the changes made by a classbox are only visible to that classbox (or classboxes that import it), a feature we call local rebinding. To validate the model we have implemented it in the Squeak Smalltalk environment, and performed benchmarks.&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;Now for more Ruby 2.0 preview:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;5/2 =&gt; 2 should be 2.5 or 5/2 (rational) #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;Inheritance in ruby is more for connivence than for other merits #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;Matz is thinking about moving mix-ins to a traits like solution which would have conflict detection (unintentional overrides) #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;You could declare the &#39;mix&#39; and specify how to deal with conflicting methods. #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;mix Foo, [:*] would copy all constants from the mix, or you can specify which ones you want and rename them #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;mix raises error on method/constant name conflict or removing #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;From Matz&#39;s slides &quot;Ruby 2.0, just started, small step from 1.9, should be done soon&quot; #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;Ruby 2.0: Traits, Classbox, Keyword arguments, a few other nifty features #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;There some fierce discussion going on in IRC about the proposed changes in Ruby 2.0 #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;The debate on &#39;mixes&#39; got pretty hot and heavy.  Keep in mind that all this IRC chatter is displayed behind Matz while he was giving his keynote because the translations are done in IRC.  So you&#39;d be reading a translation of what he said right along with people discussing it.&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;My presentation on &quot;Speedy Tests&quot; and &quot;Metrics Based Refactoring&quot; starts at 13:30 (10 min) in room 200 #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;The &#39;slides&#39; from my presentation on &quot;Speedy Tests&quot; http://is.gd/eHNTN #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;I think the talk went very well.  Especially considering that I wrote the second half fairly fast.&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;I just disparaged integration tests in favor of unit tests. Next up is @p_elliott talking about how he only does integration #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;.@p_elliott does a lot of things to make his integration test fly. I would like to see one of their suites. I could learn a lot. #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;So I asked Paul how long their suites take and he said that they develop on 8 core machines and use Specjour to utilize 4 more cores so they tend to run between 5-8 minutes.  Pretty damn fast for full stack integration testing.&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;Hey, someone else made the 30 minutes vs. 60 minutes mistake. I feel better now. #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;Except he found out at the end of his presentation when he asked: &quot;How much time do I have left?&quot; and go the response: &quot;25 minutes.&quot;  Yipes.  Luckily there were a lot of questions.&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;.@nusco did a really good job explaining the basics of Ruby metaprograming&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;RT @sudhindraRao Whatever works in #java does not work in #ruby. Even huge classes are maintainable. @rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;.@nusco&#39;s favorite metaprogramming trick is method_missing. I thought he was kidding but he was not. #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;When he said method_missing I grabbed the microphone back and responded: &quot;Really?&quot;  I couldn&#39;t help myself.  I tend to avoid method_missing.  There&#39;s usually a way to do what you want with other programming tricks.&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;Modules are extremely decoupled and can be tested in isolation so they are very flexible @nusco #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;Good point.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;Lightning Talks! I&#39;m excited! #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;Talking very fast does not lend itself to translation.  But still they were very cool.  Even better there was a lady in a kimono who would &#39;gong&#39; you if you ran out of time.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://www.flickr.com/photos/jakescruggs/4934093277/&quot; title=&quot;The gong lady stikes by jake_scruggs, on Flickr&quot;&gt;&lt;img src=&quot;http://farm5.static.flickr.com/4081/4934093277_b0442a1fed.jpg&quot; width=&quot;500&quot; height=&quot;375&quot; alt=&quot;The gong lady stikes&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;That is awesome.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;After the lightning talks a few of us went back to the hotel to drop our things of before the party and we ran smack into this huge festival that happens once a year in Tsukuba. Here are some pics:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;a href=&quot;http://www.flickr.com/photos/jakescruggs/4934688370/&quot; title=&quot;Festival 11 by jake_scruggs, on Flickr&quot;&gt;&lt;img src=&quot;http://farm5.static.flickr.com/4074/4934688370_68bc9aa127.jpg&quot; width=&quot;500&quot; height=&quot;375&quot; alt=&quot;Festival 11&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;a href=&quot;http://www.flickr.com/photos/jakescruggs/4934691494/&quot; title=&quot;Festival 4 by jake_scruggs, on Flickr&quot;&gt;&lt;img src=&quot;http://farm5.static.flickr.com/4120/4934691494_1e17f48008.jpg&quot; width=&quot;500&quot; height=&quot;375&quot; alt=&quot;Festival 4&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;a href=&quot;http://www.flickr.com/photos/jakescruggs/4934097053/&quot; title=&quot;Festival 6 by jake_scruggs, on Flickr&quot;&gt;&lt;img src=&quot;http://farm5.static.flickr.com/4098/4934097053_78ae5d8471.jpg&quot; width=&quot;500&quot; height=&quot;375&quot; alt=&quot;Festival 6&quot; /&gt;&lt;/a&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The party was super nice.  And they had a fantastic spread of wonderful foods and drinks.  &lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jakescruggs.blogspot.com/feeds/4706721565901105774/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1042801964488488185/4706721565901105774' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1042801964488488185/posts/default/4706721565901105774'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1042801964488488185/posts/default/4706721565901105774'/><link rel='alternate' type='text/html' href='http://jakescruggs.blogspot.com/2010/08/ruby-kaigi-2010-day-2.html' title='Ruby Kaigi 2010 Day 2'/><author><name>Jake Scruggs</name><uri>http://www.blogger.com/profile/16274380203959781950</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://farm1.static.flickr.com/200/441258345_b0379aaf00_m.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://farm5.static.flickr.com/4081/4934093277_b0442a1fed_t.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1042801964488488185.post-7493601368196407080</id><published>2010-08-27T18:19:00.004-05:00</published><updated>2010-08-27T19:39:48.937-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="RubyKaigi2010"/><title type='text'>Ruby Kaigi 2010 Day 1</title><content type='html'>&lt;div&gt;Here I am in Japan at RubyKaigi 2010.   Wow.  Generally I tweet a lot about the conf live and then publish those tweets here (in italics) and provide slightly more commentary.  So lets get it on.&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;So my flight leaves at noon for #rubykaigi, takes 13 hours, and arrives at 3pm tomorrow... Wait -- that can&#39;t be right. #looksitupagain&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;Before today&#39;s trip to Japan the furthest from the U.S.A. I&#39;ve ever been is: Canada. #howisthatpossible&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;In cab. It has begun.&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;Someone once said &quot;If you&#39;ve never missed a flight you&#39;re spending too much time in airports&quot; #atgate2hoursearly&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;Yep - can you feel the panic in those first couple of tweets? I was totally freaked out.  The actual trip turned out to be easy.  I met up with Chad Fowler, Yehuda, and Woody at the airport and we took a bus straight to Tsukuba.  I went to an exotic foreign land and the first thing I did was take a bus through 100 minutes of strip malls.  But I was in Japan.  And Yehuda held forth on &#39;snowmen&#39; and encodings for most of the way so that was interesting.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;a href=&quot;http://www.flickr.com/photos/jakescruggs/4930480551/&quot; title=&quot;Yehuda Katz Holds Forth on the Bus by jake_scruggs, on Flickr&quot;&gt;&lt;img src=&quot;http://farm5.static.flickr.com/4123/4930480551_514009ca51.jpg&quot; width=&quot;500&quot; height=&quot;375&quot; alt=&quot;Yehuda Katz Holds Forth on the Bus&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;So it&#39;s 7:15 am in Chicago, meaning I&#39;ve been up for over 24 hours. So that&#39;s like 36 old man hours.&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;My first meal in Japan was near 60 bucks. And I&#39;m not even in Tokyo yet. I&#39;m gonna need a bigger wallet.&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;Also, I almost got run over by not one, but two bicyclists using cell phones to text.&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;And 7-11&#39;s are everywhere.&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;So I survived the first day and even had an excellent dinner.  It was a bit pricey but worth it.  Many thanks to Makoto Inoue for helping organize this get together - it was exactly what I needed.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;Donuts are cute in Japan: http://is.gd/eFXCR&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://www.flickr.com/photos/jakescruggs/4931073850/&quot; title=&quot;Donuts are cute at Mr. Donut by jake_scruggs, on Flickr&quot;&gt;&lt;img src=&quot;http://farm5.static.flickr.com/4122/4931073850_1d642418e1.jpg&quot; width=&quot;500&quot; height=&quot;375&quot; alt=&quot;Donuts are cute at Mr. Donut&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;Ate second breakfast/lunch at &quot;Mr. Donut&quot; which is really nice here in Japan.  Of course you can get noodles.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;Good news: #rubykaigi has a non-freezing temperature. I was worried it would be 91 outside and 50 inside. Which tends to make me sick&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;Some nice low-key techno playing in the #rubykaigi main convention hall.&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;RT @headius Ruby 1.8.8 will release this year and be the last 1.8 release. Some debate still about whether to backport 1.9.2 features. #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;Ah, Charles got to got to the secret Ruby Core meeting so he&#39;s in the know.  Actually I could have probably gone too but I wasn&#39;t sure if just anyone was allowed.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;Btw, the advice I received to stay up as long as possible after my flight to Japan was good. Feeling no jet-lag.&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;I adjusted my Japanese rent-a-phone to display am/pm and now it reads &quot;0:32pm&quot; I guess they really like military time here&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;It&#39;s the little things that are the most endearing. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;Getting an introduction to #rubykaigi in japanese with translations coming in IRC which is displayed on side screens. #lag&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;br /&gt;&lt;a href=&quot;http://www.flickr.com/photos/jakescruggs/4932819961/&quot; title=&quot;We get a lecture on proper use of wifi by jake_scruggs, on Flickr&quot;&gt;&lt;img src=&quot;http://farm5.static.flickr.com/4114/4932819961_d550f03286.jpg&quot; width=&quot;500&quot; height=&quot;375&quot; alt=&quot;We get a lecture on proper use of wifi&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;Next up at #rubykaigi is a panel on Rails 3/ Ruby 1.9.2 (replacing canceled keynote)&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;br /&gt;&lt;a href=&quot;http://www.flickr.com/photos/jakescruggs/4933414302/&quot; title=&quot;First panel by jake_scruggs, on Flickr&quot;&gt;&lt;img src=&quot;http://farm5.static.flickr.com/4093/4933414302_1f84cf753d.jpg&quot; width=&quot;500&quot; height=&quot;375&quot; alt=&quot;First panel&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;Ah, the translations are back. Mostly. #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;RT @headius I can&#39;t decide if it will be more or less exhausting to attend three days of conference sessions I can&#39;t understand :) #RubyKaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;.@wycats is fearless - he&#39;s critiquing Ruby 1.9.2 while sitting 5 feet from matz on stage&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;So Leonard was doing the translation from Japanese to English and Matz was doing the translation from English to Japanese which lead the a moment where Matz had to translate Yehuda&#39;s (nice) criticism of Ruby 1.9.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;One of things @tenderlove really likes about 1.9 is using encodings is painless. You have to think about it but it&#39;s easy. #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;Secret to getting commit rights on Ruby or Rails? Submit patches with tests over a consistent period. #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;.@tenderlove doesn&#39;t think that ActiveRecord got the same amount of love that ActiveSupport did in Rails 3. #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;Specifically @tenderlove doesn&#39;t like ActiveRelation&#39;s integration in ActiveRecord in Rails 3. &quot;It needs help&quot; #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;.@wycats&#39; response: &quot;There&#39;s always 3.1&quot; #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;.@tenderlove feels less able to bounce around the whole project when developing on Ruby as compared to Rails. #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;.@wycats brought up something for Ruby core, saw a lot of discussion referencing his name but he could not participate. #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;Ah the perils of trying to develop across (real) languages. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;Wait, Sarah&#39;s talk is going to be in Japanese? #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;Oh, just the first part -- well done. #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;She learned a lot of Japanese just for this presentation.  Good for her. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;Rails wrapping of Javascript is kind of a disaster - mostly because javascript is changing fast. #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;Good point - I hadn&#39;t really thought about why wrapping SQL works so well while wrapping Javascript works out so poorly.&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;Step one to writing testable Javascript: Get it out of the view. #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;Pivotal uses Jasmine to test their Javascript: Bdd/RSpec like syntax and no dom is required. Can run in browser or headless. #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;There&#39;s no time between sessions to escape one and go to another. Good thing I don&#39;t mind appearing rude. #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;Picture a lot of me saying &quot;Excuse me&quot; to people who don&#39;t understand english.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;OH &quot;Social games are just CMS with bad UI&#39;s&quot; #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;That&#39;s really funny.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;MySql 5 only supports 3 bytes for UTF8. huh. #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;A &#39;u&#39; with an umlaut is two code points that represent one character. #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;UTF8 and UTF16 are both encodings of unicode. #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;In Ruby 1.8 and C a string is just an array of bytes. #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;&quot;Corruption is normal&quot; - @wycats #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;force_encoding is not the way. If you have to use it you probably have a deeper problem. #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;Dear internet: Take all sweeping statements with a grain of salt.&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;Two sessions in a row on encodings.  We all feel like we need to know more about encodings.  And then we ignore that feeling until it bites us in the ass.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;jugyo has a lot of Growl-themed ideas. #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;Had an outbreak of super-sleepiness. Purchased a strange energy drink from an even stranger vending machine and I&#39;m good. #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;TermColor can do blink! Now that&#39;s progress. #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;Cinatra is Sinatra for command line apps. #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;&quot;write code like writing blog entries&quot; - jugyo #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;Watching Jugyo talk is always entertaining - I loved his lightning talk at last years Ruby Conf.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;.@tenderlove has changed into a crappy suit -- It&#39;s business time! #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;And headgear? #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;br /&gt;&lt;a href=&quot;http://www.flickr.com/photos/jakescruggs/4932823869/&quot; title=&quot;@tenderlove 1 by jake_scruggs, on Flickr&quot;&gt;&lt;img src=&quot;http://farm5.static.flickr.com/4123/4932823869_cd2d2ed3c0.jpg&quot; width=&quot;500&quot; height=&quot;375&quot; alt=&quot;@tenderlove 1&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;That, my friends, is awesome.  I can&#39;t compete in shear crazy and acknowledge my superior.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;The number of languages (code) vs. the number of languages (speak) is completely off. #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;&quot;People are interpreters with forgiving parsers.&quot; - @tenderlove #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;.@tenderlove enjoys programming the most at hack nights. Challenging and fun. #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;PHP and Ruby living together: Webrick serving up WordPress. You are one weird dude @tenderlove #rubykaigi&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;Webrick serving up PHP WordPress.  Think about that for a moment.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;Making some last minute changes to my #rubykaigi presentation: &quot;Speedy Tests&quot; Come see it tomorrow at 13:30 in room 200&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;Hey, I just found out I have an hour time slot when I had thought I was going to present for 30 minutes.  I guess the crowd is going to get some bonus metric_fu coverage.  As I&#39;m going to present in 4 hours I better go write some more content.  Panic!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Oh yeah, go check out my Ruby Kaigi photo set on Flickr: &lt;a href=&quot;http://www.flickr.com/photos/jakescruggs/sets/72157624815648014/&quot;&gt;http://www.flickr.com/photos/jakescruggs/sets/72157624815648014/&lt;/a&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jakescruggs.blogspot.com/feeds/7493601368196407080/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1042801964488488185/7493601368196407080' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1042801964488488185/posts/default/7493601368196407080'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1042801964488488185/posts/default/7493601368196407080'/><link rel='alternate' type='text/html' href='http://jakescruggs.blogspot.com/2010/08/ruby-kaigi-2010-day-1.html' title='Ruby Kaigi 2010 Day 1'/><author><name>Jake Scruggs</name><uri>http://www.blogger.com/profile/16274380203959781950</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://farm1.static.flickr.com/200/441258345_b0379aaf00_m.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://farm5.static.flickr.com/4123/4930480551_514009ca51_t.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1042801964488488185.post-7166009996374413798</id><published>2010-07-20T15:15:00.002-05:00</published><updated>2010-07-20T15:30:04.957-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="git"/><title type='text'>Using Git Inside a Git Hook</title><content type='html'>Using Git Inside a Git Hook  can cause problems.  In my previous post: &quot;&lt;a href=&quot;http://jakescruggs.blogspot.com/2010/07/signal-13-problems-with-git-hooks.html&quot;&gt;Signal 13 Problems with Git Hooks&lt;/a&gt;&quot; I describe how we are trying to automatically merge certain types of branches into a branch that is designed to hold them all.  Anyway, that means we want to run some git commands inside of the git hook.  We change dirs into another directory where we have a clone of the repo and start telling git to merge some stuff and we get a bunch of&lt;pre&gt;&lt;br /&gt;remote: fatal: Not a git repository: &#39;.&#39;&lt;br /&gt;&lt;/pre&gt;But if we run the exact same commands as the git user everything works fine.  Huh.  Eventually we got our linux guru over and he noticed that the environment under which the git user runs is totally different when inside a hook.  &lt;a href=&quot;http://github.com/sitaramc/gitolite&quot;&gt;Gitolite&lt;/a&gt; does a bunch of things to the env, but the one that was screwing us up was the setting of the GIT_DIR.  After we figured that out, the solution was as easy as:&lt;pre&gt;&lt;br /&gt;ENV.delete &#39;GIT_DIR&#39;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;in our ruby script that is triggered by the &#39;post-receive&#39; hook.  And now I must get back to the fun.</content><link rel='replies' type='application/atom+xml' href='http://jakescruggs.blogspot.com/feeds/7166009996374413798/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1042801964488488185/7166009996374413798' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1042801964488488185/posts/default/7166009996374413798'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1042801964488488185/posts/default/7166009996374413798'/><link rel='alternate' type='text/html' href='http://jakescruggs.blogspot.com/2010/07/using-git-inside-git-hook.html' title='Using Git Inside a Git Hook'/><author><name>Jake Scruggs</name><uri>http://www.blogger.com/profile/16274380203959781950</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://farm1.static.flickr.com/200/441258345_b0379aaf00_m.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1042801964488488185.post-4497882811048392923</id><published>2010-07-20T12:16:00.005-05:00</published><updated>2010-07-20T15:11:28.965-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="git"/><title type='text'>Signal 13 Problems with Git Hooks</title><content type='html'>Ran into a gotcha in Git today when trying to write a post push hook.  We want our designer to have a fast turn around time with clients so we&#39;re writing some hooks to merge all of the &#39;theme&#39; branches he works with to get merged into a special preview branch which is then deployed to the preview site.  And all this should happen after he does a &#39;git push.&#39;  Seems like a &#39;post-receive&#39; hook is just what we want.  &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Except that every time we tried to create one we got these errors on a push:&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;error: git-shell died of signal 13&lt;br /&gt;fatal: The remote end hung up unexpectedly&lt;br /&gt;error: error in sideband demultiplexer&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;If the &#39;post-receive&#39; file even existed in git_dir/hooks/ on the git repo box, we got this error.  We checked permissions, gitolite docs, git docs, google, etc and no help.  We finally realized that Git was piping in some information to our &#39;post-receive&#39; file and since we were not consuming it, that was causing the explosion.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So, I present to you, a stub of &#39;post-receive&#39; file written in Ruby:&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#!/usr/bin/env ruby&lt;br /&gt;STDIN.readlines.each do |line|&lt;br /&gt;rev_old, rev_new, ref = line.split(&quot; &quot;)&lt;br /&gt;# You will get in here as many times as branches were pushed&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;rev_old is the old commit hash, rev_new is the new commit hash, and ref will be something like: &quot;refs/heads/test_branch&quot;  Useful information.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Git often passes things into it&#39;s hooks, check the &lt;a href=&quot;http://book.git-scm.com/5_git_hooks.html&quot;&gt;git book docs&lt;/a&gt; to find out what.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt; &lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jakescruggs.blogspot.com/feeds/4497882811048392923/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1042801964488488185/4497882811048392923' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1042801964488488185/posts/default/4497882811048392923'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1042801964488488185/posts/default/4497882811048392923'/><link rel='alternate' type='text/html' href='http://jakescruggs.blogspot.com/2010/07/signal-13-problems-with-git-hooks.html' title='Signal 13 Problems with Git Hooks'/><author><name>Jake Scruggs</name><uri>http://www.blogger.com/profile/16274380203959781950</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://farm1.static.flickr.com/200/441258345_b0379aaf00_m.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1042801964488488185.post-6158904919972886157</id><published>2010-07-15T22:47:00.004-05:00</published><updated>2010-07-15T23:09:01.530-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="RubyMidwest2010"/><title type='text'>The Road to Ruby Midwest</title><content type='html'>Crazy day:&lt;br /&gt;It was the day before &lt;a href=&quot;http://www.rubymidwest.com/&quot;&gt;Ruby Midwest&lt;/a&gt; so I gave my &#39;Speedy Tests&#39; talk to my workmates at &lt;a href=&quot;http://backstopsolutions.com/&quot;&gt;Backstop Solutions&lt;/a&gt; during lunch today and they had the nerve to find some things wrong with it -- so I&#39;ll be doing some re-tooling before Saturday.  Then I was all set to leave 2 hours early for the airport when my manager wants to talk about me helping QA understand our process, new features, and maybe get some automated tests running.  Hell to the yeah.  So I&#39;m all over this opportunity but our conversation makes me leave the office a bit late to catch my flight.  No problem, I build in a lot of buffer.  Then the Blue line (Chicago&#39;s subway) was down.  Uh oh.  Some surly dude said there was a free shuttle to somewhere else but I couldn&#39;t find it so I took a cab.  Crazy traffic puts me at the airport with 30 min until my flight.  Panic!  But the security lines are longish so I panic while inching forward in a zig-zag line.  Then I sprint to terminal C (which is the farthest away and involves going underground) and find my seat minutes before they close the doors.&lt;br /&gt; &lt;br /&gt;The lady next to me wanted to make small talk about how I was out of breath.   I did not.&lt;br /&gt;&lt;br /&gt;Then when I landed I noticed that all the signs say &quot;KCI&quot; when I&#39;m pretty sure I booked a flight to &quot;MCI&quot; so I had a minor heart attack moment where I thought I flew into the wrong city.  But no, it turns out that KCI and MCI are the same.  That&#39;s not confusing at all.&lt;br /&gt;&lt;br /&gt;But all was well when I made it too the speakers dinner.  Very nice of the Ruby Midwest guys to organize such a dinner and pick up the tab.  Good conversations with some locals (Shashank, Luke, and Josh), a 37 signals-er (John), and an Edge Case-r (Adam).  Looks like the conference is off to a swimming start.</content><link rel='replies' type='application/atom+xml' href='http://jakescruggs.blogspot.com/feeds/6158904919972886157/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1042801964488488185/6158904919972886157' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1042801964488488185/posts/default/6158904919972886157'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1042801964488488185/posts/default/6158904919972886157'/><link rel='alternate' type='text/html' href='http://jakescruggs.blogspot.com/2010/07/road-to-ruby-midwest.html' title='The Road to Ruby Midwest'/><author><name>Jake Scruggs</name><uri>http://www.blogger.com/profile/16274380203959781950</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://farm1.static.flickr.com/200/441258345_b0379aaf00_m.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1042801964488488185.post-4984857037247312966</id><published>2010-06-13T13:30:00.002-05:00</published><updated>2010-06-13T13:48:53.965-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Rails"/><category scheme="http://www.blogger.com/atom/ns#" term="RailsConf2010"/><category scheme="http://www.blogger.com/atom/ns#" term="Ruby"/><title type='text'>Rails Conf 2010 Day 3</title><content type='html'>A few days late on this because I&#39;ve been sick all weekend.  There just has to be a way to do climate control in conference centers in such a way as to not destroy the planet and, more importantly, Jake&#39;s health.  I seriously wore black jeans and 2 shirts on hot summer days and yet I was shivering and caught a cold. &lt;br /&gt;&lt;br /&gt;But let&#39;s get to last day of Rails Conf 2010 and my exciting adventures therein. (tweets are in &lt;span style=&quot;font-style: italic;&quot;&gt;italics&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Woke to &quot;Relax&quot; by Frankie Goes to Hollywood. Which is good &#39;cause my heart was pounding. Settled it with some bacon. #railsconf&lt;/span&gt;&lt;br /&gt;Yep, I could feel cold coming but I was in denial.  I ran into Neal Ford at breakfast and we chit chatted about this and that and then he mentioned that he had read my blog post from yesterday.  First thought:  I published that sucker at 1am this morning and he&#39;s read it already?  Second thought:  Oh shit, what did I say about his keynote -- I think I called him a jerk at some point.  But my brain was foggy and so I wasn&#39;t quite sure what I had said.  Later I looked and, yes, I had called him a jerk.  I was kidding!  If only that was the most embarrassing thing I did that day...&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Pro tip: Have the hotel watch your bag for the day while your at the last day of the con #railsconf&lt;/span&gt;&lt;br /&gt;It&#39;s true.  This year Rails Conf was nice enough to have a section for people&#39;s bags at the conference but they don&#39;t always.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Twenty-Five Zeros - Robert Martin &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;So, as many of you know, I started out at Object Mentor (as an unpaid apprentice/intern) and I&#39;m a bit of an Uncle Bob fanboy.  As these next tweets can attest:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Bring it Uncle Bob! #railsconf&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Good to see Uncle Bob still starts all his talks with some hard core physics. #railsconf&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;HOLY SHIT!!! Uncle Bob opens by showcasing some impressive drum chops. #railsconf&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;RT @duncan: Photo of @unclebobmartin on drums at #RailsConf (ISO 12800 in the dark)&lt;a href=&quot;http://www.flickr.com/photos/oreillyconf/4688547550/&quot;&gt; http://www.flickr.com/photos/oreillyconf/4688547550/ &lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;@spiceee call him (@unclebobmartin) butter cause he&#39;s on a roll #railsconf&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;#railsconf haiku Uncle Bob holds us | We are enraptured by him | Rambling? I think not!&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Great speaker, although I had to de-follow him on twitter as I&#39;m not into right wing politics.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;If we have computers 10^25 times more powerful than 1960 then why no AI? Always seems 10 years out. #railsconf  &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Our software has not improved anywhere near 25 orders of magnitude unlike the processors @unclebobmartin #railsconf&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;Funny how social sciences never really advance as fast as the hard ones.  I think of programming as a &#39;soft&#39; science because the hard part is NOT getting a computer to understand the code it&#39;s describing intent to humans.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;.@unclebobmartin &quot;What language do you know that still has goto?&quot; guy in crowd: &quot;PHP&quot; #railsconf  &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;A brief tour of programming languages with @unclebobmartin #railsconf&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;RT &quot;vi? what the hell?&quot; - @unclebobmartin #railsconf&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Vi, Emacs, TextMate, etc. all seem like some weird time warp compared to the awesomeness of the language.  It always seems like a really good Ruby IDE is just around the corner.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;RT the point emerges. multicore processors pass the buck to us. future == parallelism #railsconf&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Real innovation in software may be driven by the move to parallel processors @unclebobmartin #railsconf&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;.@unclebobmartin is hawking #sicp Yeah, yeah, yeah. I&#39;m getting to it. #railsconf    &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;#sicp is a page turner? Really? @unclebobmartin #railsconf&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Structure and Interpretation of Computer Programs is so often praised that people in the know just refer to it as sicp. It&#39;s available for free here: &lt;a href=&quot;http://mitpress.mit.edu/sicp/&quot;&gt;http://mitpress.mit.edu/sicp/&lt;/a&gt;  I&#39;m thinking of working through it in clojure.  And who doesn&#39;t like LISP?  Uh...&lt;br /&gt;&lt;br /&gt;But his point about multi-core is important (although it has been made before).  A lot of people took his talk to mean that Ruby will lead the way into the future of programming.  I think his point was that the people at Rails Conf will lead the way -- but probably not in Ruby.  I&#39;ve seen a few frameworks for handling concurrency in Ruby and they all suck.  Why?  Because you have to remember to use them all the time.  All it takes is one programmer mutating a state somewhere in your code and now you have an intermittent race condition bug.  If you&#39;re really going to do concurrency you need a language that treats all mutation like a disease that must be contained in explicitly declared blocks.  And that language is not Ruby.&lt;br /&gt;&lt;br /&gt;But I think we still have a few years left before we all have to get functional, so that&#39;s nice.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;There&#39;s 2 prominent black dudes in the Ruby community. I just gave a hardy hello to one and referred to him by the other&#39;s name. #railsconf    &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Sorry. Sorry. Sorry. Sorry. Sorry. Sorry. Sorry. Sorry. Sorry. Sorry. Sorry. Sorry. Sorry. Sorry. Sorry. Sorry. Sorry. Sorry. #railsconf&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;In my defense:  I&#39;m an idiot.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;You May Also Be Interested in: Implementing User Recommendations in Rails - Matthew Deiters&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;So Amazon makes 25% of its sales based on recommendations.  I was talking with a friend from Groupon the night before and he was telling me that just guessing the sex from a person&#39;s name (and targeting what they get offered) has led to a significant sales boost.  If you&#39;re not thinking about how to intelligently recommend to your customers, it&#39;s a sure bet your competitors are.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Aaahh the Hoff&#39;s crotch is coming at me! #railsconf    &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Oh it was just an animated gif. #railsconf   &lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;I urge you not to click this link: &lt;a href=&quot;http://www.post-literate.com/gerpunx/archives/2005/01/prepare_to_lose_your_mind.php&quot;&gt;http://www.post-literate.com/gerpunx/archives/2005/01/prepare_to_lose_your_mind.php&lt;/a&gt;&lt;br /&gt;I think Deiters was trying to make a point about recursion in SQL being bad, but the image made my brain stop working.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Gem Neo4jr-social is a graph db that uses JRuby but isolates it in a Jetty server so you don&#39;t need to use JRuby throughout #railsconf    &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;You can use Neo4jr-social to get friend recommendations and degrees of separation pretty easily. @mdeiters #railsconf&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;To which Charles Nutter (@headius) responded @jakescruggs Jeez, why not just use JRuby? So much pain could be avoided.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;I really want @mdeiters slides for the explanation of all these crazy graph relationship terms #railsconf   &lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Graph db&#39;s are amazing for relationship stuff.  You can do &quot;what&#39;s my degree of separation from X&quot; stuff in milliseconds.  And Neo4jr-social looks like a pretty cool way to do that stuff in a readable way.&lt;br /&gt;&lt;br /&gt;&lt;ul style=&quot;font-style: italic;&quot;&gt;&lt;li&gt;You have a lot of money lying around in your data - pick it up! @mdeiters #railsconf    &lt;/li&gt;&lt;li&gt;RT &quot;This conference is the NoSQL conference. But remember: It&#39;s not No SQL. It&#39;s Not Only SQL&quot; -- @mdeiters #railsconf&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Really good talk.  Lots of info in the slides:&lt;br /&gt;&lt;a href=&quot;http://assets.en.oreilly.com/1/event/40/You%20May%20Also%20Be%20Interested%20in_%20Implementing%20User%20Recommendations%20in%20Rails%20Presentation.pdf&quot;&gt;http://assets.en.oreilly.com/1/event/40/You%20May%20Also%20Be%20Interested%20in_%20Implementing%20User%20Recommendations%20in%20Rails%20Presentation.pdf&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Lapidary: the Art of Gemcutting - Nick Quaranto&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;RubyGems.org has a nice versioned API @qrush #railsconf&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;&#39;gem yank&#39; to remove a gem. Didn&#39;t know you could do that. There&#39;s an undo too. Nice. @qrush #railsconf&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;Versioned API and an &#39;undo&#39; -- cool.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;gem webhook projects suggestion - gem tarballer @qrush #railsconf    &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;gem webhook projects suggestion - distributed testing service @qrush #railsconf    &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;gem webhook projects suggestion - change log service @qrush #railsconf    &lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;All these ideas are great.  I command the readers of this blog to go implement them now...  Please?&lt;br /&gt;&lt;br /&gt;&lt;ul style=&quot;font-style: italic;&quot;&gt;&lt;li&gt;Gemcutter moved from postgres to redis @qrush #railsconf mostly    &lt;/li&gt;&lt;li&gt;Lots of Gemcutter clones out there @qrush #railsconf    &lt;/li&gt;&lt;li&gt;.@qrush wants to add better indexes, dependency resolution, and support bundler in RubyGems.org #railsconf    &lt;/li&gt;&lt;li&gt;.@qrush also wants historical data for every gem with download graphs. @qrush #railsconf    &lt;/li&gt;&lt;li&gt;github.com/rubygems/rubygems No longer on svn. @qrush #railsconf&lt;/li&gt;&lt;/ul&gt;All very cool.  Nick is clearly firing on all cylinders -- he deserves a raise.&lt;br /&gt;&lt;br /&gt;Yehuda Katz - showed up and thanked Nick for his contributions to the Ruby community.  I was in quite a few talks where he made it a point to thank the speaker for things he really liked.  Stand up guy that Yehuda.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;RT: OH: &quot;Firefox is the new IE.&quot; #railsconf (via @glv)&lt;/span&gt;&lt;br /&gt;Ouch.  But kinda true.&lt;br /&gt;   &lt;br /&gt;&lt;ul style=&quot;font-style: italic;&quot;&gt;&lt;li&gt;The Cold/Hot/Cold/Hot/Cold/Hot/Cold/Hot of this week has made me weak. Picked up some knockoff airborne at the CVS #railsconf  &lt;/li&gt;&lt;li&gt;Getting sicker... Must consume more vitamins and wear more clothes. Covering up crazy shirt now. :( #railsconf  &lt;/li&gt;&lt;li&gt;Must. Fight. Sickness. At. The. Airport.&lt;/li&gt;&lt;/ul&gt;At that point the sickness overtook me so I found a quiet place and laid down.  So I missed the last keynote -- which I&#39;m about to watch now.&lt;br /&gt;&lt;br /&gt;And I&#39;m back.  Good Keynote.  Actually, all the keynotes were pretty darn good this year.  And so were the sessions.  Shortly before I got sick on Thursday I remember thinking &quot;This is probably my favorite Rails Conf.&quot;&lt;br /&gt;&lt;br /&gt;Gary Vaynerchuk&#39;s talk is probably summed up best with this (made up) title:&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Relationships, relationships, relationships, (and swearing) - Gary Vaynerchuk&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Here&#39;s some memorable quotes and thoughts:&lt;br /&gt;&lt;br /&gt;&quot;Giving a Fuck is coming on strong&quot;&lt;br /&gt;&lt;br /&gt;&quot;Stop using the space (twitter, facebook, etc) just to put out fires&quot;&lt;br /&gt;&lt;br /&gt;&quot;If I get a hundred more followers I&#39;ll donate $100 to Haiti - Hey Fuck-face just donate $100 to Haiti&quot;&lt;br /&gt;&lt;br /&gt;&quot;Everything you&#39;re doing is being documented&quot;&lt;br /&gt;&lt;br /&gt;&quot;It&#39;s just getting real hard to hide&quot;&lt;br /&gt;&lt;br /&gt;In 2005-6 everything was free 24/7/365.  Now people are being trained to pay for things.&lt;br /&gt;&lt;br /&gt;On consulting for huge companies: Its stunning how little most big companies give a crap.  Most CEO&#39;s want to keep the stock price up for 3-5 years and get out with a huge payday.&lt;br /&gt;&lt;br /&gt;Getting people to your site is awesome but &quot;Content is always king&quot;&lt;br /&gt;&lt;br /&gt;&quot;What&#39;s the ROI (Return On Investment) in social media?  Well I don&#39;t know fuck-face what&#39;s the ROI in having a real relationship?  Meanwhile you&#39;re paying for billboards...&quot;&lt;br /&gt;&lt;br /&gt;Old businesses: &quot;They lived under small town rules&quot; - if you screw someone you&#39;re going out of business.  Those days are coming back.&lt;br /&gt;&lt;br /&gt;Corporations: &quot;We don&#39;t want to open this up because people could say our product&#39;s bad&quot;&lt;br /&gt;&lt;br /&gt;Gary on the future:  &quot;I&#39;m all in -- I&#39;m bullish on human beings.&quot;&lt;br /&gt;&lt;br /&gt;You can find Gary&#39;s Keynote along with all the others at: &lt;a href=&quot;http://www.youtube.com/view_play_list?p=393ECE649BB3813D&quot;&gt;http://www.youtube.com/view_play_list?p=393ECE649BB3813D&lt;/a&gt; or on iTunes.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Well that&#39;s the end of my Rails Conf 2010 coverage.  Thanks for reading.</content><link rel='replies' type='application/atom+xml' href='http://jakescruggs.blogspot.com/feeds/4984857037247312966/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1042801964488488185/4984857037247312966' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1042801964488488185/posts/default/4984857037247312966'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1042801964488488185/posts/default/4984857037247312966'/><link rel='alternate' type='text/html' href='http://jakescruggs.blogspot.com/2010/06/rails-conf-2010-day-3.html' title='Rails Conf 2010 Day 3'/><author><name>Jake Scruggs</name><uri>http://www.blogger.com/profile/16274380203959781950</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://farm1.static.flickr.com/200/441258345_b0379aaf00_m.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1042801964488488185.post-1730086529597400230</id><published>2010-06-09T23:35:00.004-05:00</published><updated>2010-06-13T14:45:37.256-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Rails"/><category scheme="http://www.blogger.com/atom/ns#" term="RailsConf2010"/><category scheme="http://www.blogger.com/atom/ns#" term="Ruby"/><title type='text'>Rails Conf 2010 Day 2</title><content type='html'>Only 40 tweets today (re and otherwise).  I must be slowing down in my old age. Tweets are in &lt;span style=&quot;font-style: italic;&quot;&gt;italics&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Today&#39;s morning music was &quot;Bulletproof&quot; by Pop Will Eat Itself. Cram that in your head @ryanbriones&lt;/span&gt;&lt;br /&gt;Ryan was complaining yesterday that he had the theme from flash stuck in his head all day because of me.  That sounds awesome!  I had a Daft Punk song stuck in my head all day today and I was a better person for it.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Trying to work on my Lightning Talk. Lightning talks are usually the best part of any conf so it better be good. 4:25 today #railsconf&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Lightning talk is finished. Title: &quot;ActiveMQ and ActiveMessaging: I&#39;ve Experienced the Pain So You Don&#39;t Have To&quot; #railsconf&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Yeah, I got up, worked out, ate eggs wrapped in cheese and bacon, showered and then realized I had gotten up an hour early by mistake.  Opportunity!  So I worked on the lightning talk.  To be honest, I was kinda pissed at myself for the boneheaded alarm mishandling but if it doesn&#39;t make you money or happy, you need to let it go.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Don&#39;t forget to read my sham of a blog post about #RailsConf Day 1: http://is.gd/cIdLZ&lt;/span&gt;&lt;br /&gt;So very meta.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;iPod at #RailsConf Keynote has been set to &quot;BadPopCountryMusic&quot; wtf mate?&lt;/span&gt;&lt;br /&gt;Seriously.  Is there anything worse than top 40 wanna be country music?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Creativity &amp;amp; Constraint - Neal Ford&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;&quot;Some of the &#39;facts&#39; in this talk may in fact be harmless lies&quot; - disclaimer of @neal4d #railsconf&lt;/span&gt;&lt;br /&gt;This disclaimer needs to be in front of all keynotes.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;I&#39;m Not Old, I&#39;m seasoned. @neal4d #railsconf&lt;/span&gt;&lt;br /&gt;Me too buddy, me too.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;&quot;The right community to suggest something really weird to&quot; @neal4d #railsconf&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;RT I so wanna go to Neal Ford&#39;s halloween party! #railsconf&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Constraints are liberating: @neal4d excuse for showing cool Halloween photos at #railsconf&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;His Halloween party pics were off the hook.  Did I ever tell you I took Neal to his first day lunch at ThoughtWorks?  You&#39;d think that would get me a Halloween party invite but memories are short.  Jerk.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;What constraints help? Maybe not static typing... @neal4d #railsconf&lt;/span&gt;&lt;br /&gt;Double true.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Hemingway and the Ex Pats in Paris wore stupid hats #railsconf&lt;/span&gt;&lt;br /&gt;Well they do.  Americans in berets look stupid.  There -- I said it.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;An empty canvas is a daunting task @neal4d #railsconf&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;The invention of the camera made painters do something different besides making it look real. @neal4d #railsconf&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;The Camera gave painters freedom from the responsibility of representation. @neal4d #railsconf&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Our camera is Java Enterprise Development - they can crank out vanilla apps so we can move on to interpretation @neal4d #railsconf&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Interesting.  I think he meant no offense to Java devs in specific but much offense to the mindless and complacent.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;.@neal4d has a crazy terse 3 line Quicksort implementation #railsconf&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Yeah, I had no idea what it did.  You&#39;d need a team powerful enough to turn goat piss into moonshine if you&#39;re going to check that in.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Non-obfuscating density is a characteristic of art in code @neal4d #railsconf&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;But how much density is too much?  It&#39;s a thin line between art and crap.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;RT #railsconf @_why : when u dont create things, u become defined by ur tastes rather than ability. ur tastes narrow &amp;amp; exclude ppl. so create&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Neal ended up his talk with poignant quote from _why.  Pour one out for the homies who couldn&#39;t be here.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Sponsored Keynote: Engine Yard&#39;s Open Source Love Affair - Evan Phoenix&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Dr. Who Theme! Played live by  #railsconf ers&lt;/span&gt;&lt;br /&gt;Huh?&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Did Evan come on as a rock star or a parody of a rock star? you decide. #railsconf&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Rim shots at a keynote? #railsconf&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Talk show format is... interesting Will it pay off? @evanphx #railsconf&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;A &#39;Late Night with X&#39; theme backed up by a live band.  And a game of password.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;.@evanphx &quot;Perl is the word you were looking for&quot; Dr. Nic: &quot;Never heard of it.&quot; #railsconf&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Well played Doc.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Enjoyed a pleasant 10 minutes of nothing with @evanphx #railsconf&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I really did enjoy it.  Better than somebody coming out and saying &quot;hey we bought this slot with our sponsorship and we&#39;re awesome.&quot;&lt;br /&gt;&lt;br /&gt;And then Twitter went down.  Again.  So I had to type into a document instead of live to the world.  It felt weird and dirty.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Ruby on Rails: Tasty Burgers -- Aaron Patterson &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;First, you &lt;span style=&quot;font-weight: bold;&quot;&gt;have&lt;/span&gt; to download his slides just for the introduction: http://tenderlovemaking.com/railsconf2010.pdf&lt;br /&gt;&lt;br /&gt;Two samples to entice you:&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://www.flickr.com/photos/jakescruggs/4687409786/&quot; title=&quot;Hello this is @tenderlove by jake_scruggs, on Flickr&quot;&gt;&lt;img src=&quot;http://farm5.static.flickr.com/4006/4687409786_31e150afa4.jpg&quot; alt=&quot;Hello this is @tenderlove&quot; height=&quot;415&quot; width=&quot;500&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://www.flickr.com/photos/jakescruggs/4687410170/&quot; title=&quot;Nom by jake_scruggs, on Flickr&quot;&gt;&lt;img src=&quot;http://farm5.static.flickr.com/4025/4687410170_d27bba969a.jpg&quot; alt=&quot;Nom&quot; height=&quot;339&quot; width=&quot;500&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Btw his outfits put mine to shame.  Today&#39;s was a deep magenta velvet jacket with a 70&#39;s tie and an ironic mustache.  Or a sincere but poorly chosen mustache.  There&#39;s a point when intense silliness becomes serious and upon that point Mr. Tender Love Making is doing an interpretive dance.&lt;br /&gt;&lt;br /&gt;Topics he talked about:&lt;br /&gt;&lt;br /&gt;sqlite3-ruby and Sqlite&lt;br /&gt;&lt;br /&gt;Did you know you can have a virtual file system in Sqlite?  Me neither.&lt;br /&gt;&lt;br /&gt;The new version of sqlite3-ruby is x1000 faster than before (1.3.0 vs 1.2.5)&lt;br /&gt;&lt;br /&gt;Mmap&lt;br /&gt;&lt;br /&gt;Mmap is a gem that lets you treat a file like a string.  So if you need to pass in a string to something but don&#39;t want to read the whole file into memory use Mmap.  Pretty useful tool to have in your back pocket.&lt;br /&gt;&lt;br /&gt;Rack&lt;br /&gt;&lt;br /&gt;Unknown but useful rack trick:  Rack will call &#39;each&#39; and &#39;close&#39; on the return object.  So you can pass it an array or file and things will work out just fine.  Handy.&lt;br /&gt;&lt;br /&gt;He speculated that Rails could take advantage of this and return html in pieces (as it&#39;s rendered) to make things faster.  Would be hard to do but awesome.&lt;br /&gt;&lt;br /&gt;JSON is a subset of YAML -- I did not know that.  Did everyone else?  Really? I knew you all were talking behind my back.&lt;br /&gt;&lt;br /&gt;He left the stage with a plea for the audience to dig into rails and investigate the &#39;Tasty Burgers.&#39;&lt;br /&gt;&lt;br /&gt;But wait, there was some advanced shenanigans when he called Evan Phoenix to ask him a question.  During Evan&#39;s talk!  Those guys are the kings of wacky.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Redis, Rails, and Resque - Background Job Bliss by Chris Wanstrath&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;No Slides at all!  But still good.&lt;br /&gt;&lt;br /&gt;&quot;Redis is all we really wanted it for a long time but we didn&#39;t know we wanted it&quot;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Redis is a key value store for data structures @defunkt #railsconf&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This doesn&#39;t have anything to do with Chris Wanstrath&#39;s appearance but comical mustaches are the new black.  Except that he has a mustache now.  And it looks silly.  Not that I can complain about peoples fashions sense.&lt;br /&gt;&lt;br /&gt;Chris is totally in love with Redis and Unicorn because their maintainers are awesome, active, and their software is pretty bullet proof (it stays up).  Which is kinda important to Github.&lt;br /&gt;&lt;br /&gt;He advises you to background everything you can and I agree.&lt;br /&gt;&lt;br /&gt;Resque is the queuing system they built on top of Redis.  I&#39;ve used it at Groupon and seen it used on Mad Mimi and it works well.  Plus the built in Sinatra web UI provides an amazingly informative look into the live queues.&lt;br /&gt;&lt;br /&gt;Github is on Ruby Enterprise Edition now.  So is Backstop (my company).  And everyone else at Ruby Conf.  It just surpassed ironic mustaches as the new black.&lt;br /&gt;&lt;br /&gt;Chris is determined to not add any queuing features to Resque.  He wants to let the plugins do that and there are more than a few you should check out.  I&#39;d Google that for you but I&#39;m tired.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Rocket Fueled Cucumbers - Joseph Wilk&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;So Joseph&#39;s cuke build was getting out of control as it grew.  Taking more than 4 hours.  He solved this by using EC2 and Testjour (or Hydra) to parallelize the suite across 20 machines and got it down to 11 minutes.  But it cost $3K a month.  Yipes.&lt;br /&gt;&lt;br /&gt;He recommends stubbing out slow services and maybe even caching the db (but didn&#39;t specify how).&lt;br /&gt;&lt;br /&gt;He&#39;s excited about using the cucover gem to do &quot;Lazy coverage-aware running of Cucumber acceptance tests&quot;  Kinda like a super smart autotest.&lt;br /&gt;&lt;br /&gt;He mentioned this post as required reading that he doesn&#39;t necessarily agree with: &lt;a href=&quot;http://jamesshore.com/Blog/Alternatives-to-Acceptance-Testing.html&quot;&gt;http://jamesshore.com/Blog/Alternatives-to-Acceptance-Testing.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Capybara can use envjs gem to run javascript tests in cuke.  Which is very cool.  Capybara-envjs on github&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Dear Lazyweb, how do you get a showoff presentation up on Heroku? I&#39;d like to put my lightning talk up. #railsconf&lt;/span&gt;&lt;br /&gt;Posted this before my talk.  Still have no answer but if all the cool kids can do it I&#39;m sure I can figure it out.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Lightning Talks&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Lightning Talks start now and I&#39;m giving one. Come to Ballroom 1 now! #railsconf&lt;/span&gt;&lt;br /&gt;Yep.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;RT client_side_validations http://bit.ly/9gEfuL #railsconf&lt;/span&gt;&lt;br /&gt;Interesting gem.  Way too much live coding for a lightning talk - dude was brave.  He barely made it to the end and almost missed giving out the gem name.  Live coding seems like a good idea but is to be avoided in presentations.  Ignore my advice at your own peril.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Don&#39;t hide costs from the client -- it leads to bad relationships #lightningtalks #railsconf&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Custom filters based on metadata looks cool in RSpec 2 #lightningtalks #railsconf&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;gem install surveyor for easy surveys in your rails app #lightningtalks #railsconf&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;surveyor gem can ask some complicated questions with easy. #lightningtalks #railsconf&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;RT Mind. Blown. http://bit.ly/90D1ur Now that was a lightning talk by @igrigorik. #railsconf&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Yeah the schema free sql database thing was a nice antidote to all this NoSql hype.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;http://bit.ly/RwandaOnRails looks like an interesting way to track charity money&#39;s effectiveness #lightningtalks #railsconf&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;&quot;Yes and...&quot; is an important part of improv and pairing. I totally agree. #lightningtalks #railsconf&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;My lightning talk went well and as soon as I figure out how to get it up on Heroku I&#39;ll give you (dear reader) the url.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Update:&lt;/span&gt; Here they are: &lt;a href=&quot;http://active-messaging-pain.heroku.com/&quot;&gt;http://active-messaging-pain.heroku.com/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Keynote - Derek Sivers&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In 2007 Derek took a lot of heat for his article entitled: &quot;7 reasons I switched back to PHP after 2 years on Rails&quot;&lt;br /&gt;Which can be found here: &lt;a href=&quot;http://www.oreillynet.com/ruby/blog/2007/09/7_reasons_i_switched_back_to_p_1.htm&quot;&gt;http://www.oreillynet.com/ruby/blog/2007/09/7_reasons_i_switched_back_to_p_1.htm&lt;/a&gt;l&lt;br /&gt;&lt;br /&gt;I remember reading it and thinking he was a moron.  He gives a pretty good keynote for a moron so perhaps I should reevaluate.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;RT The first follower turns a lone nut into a leader. - @sivers #railsconf&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;RT derek sivers shows this vid http://bit.ly/guHuz to talk about being a leader and starting a movement #railsconf&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The talk was all about how he preferred his own PHP frameworky thing but how that couldn&#39;t scale and so he&#39;s coming back to Rails.  And is excited about Rails 3.  Also there was a lot about building community.  We use our emotional brain to justify our rational experiences.  But sometimes our emotional brain has access to things we don&#39;t consciously know (detailed in the book &#39;Blink&#39;).  There was more but it&#39;s late and I&#39;m pretty tired so I&#39;m wrapping this blog post up with a few more tweets:&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Fogo de Chao ftw #railsconf&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Drunk. Drunk on steak. Drunk on chocolate. In fact, I&#39;m like a chocoholic except for alcohol.&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://jakescruggs.blogspot.com/feeds/1730086529597400230/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1042801964488488185/1730086529597400230' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1042801964488488185/posts/default/1730086529597400230'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1042801964488488185/posts/default/1730086529597400230'/><link rel='alternate' type='text/html' href='http://jakescruggs.blogspot.com/2010/06/rails-conf-2010-day-2.html' title='Rails Conf 2010 Day 2'/><author><name>Jake Scruggs</name><uri>http://www.blogger.com/profile/16274380203959781950</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://farm1.static.flickr.com/200/441258345_b0379aaf00_m.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://farm5.static.flickr.com/4006/4687409786_31e150afa4_t.jpg" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1042801964488488185.post-482694815251915790</id><published>2010-05-18T18:06:00.000-05:00</published><updated>2010-05-18T18:09:14.816-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="interview"/><title type='text'>Interview Coding Problems</title><content type='html'>One of the awesome things about the business we&#39;re in is that you can ask people to actually do the thing you&#39;re hiring them to do IN THE INTERVIEW!  You can&#39;t really ask a banker to do some banking during an interview, but it&#39;s relatively easy to set up a computer with a coding problem and ask a potential hire to work through it.  Having recently gone through a job search, I though I&#39;d discuss my thoughts on coding problems as part of the interview process.&lt;br /&gt;&lt;br /&gt;The first time I ever wrote code for an interview was at &lt;a href=&quot;http://www.thoughtworks.com/&quot;&gt;ThoughtWorks&lt;/a&gt;.  It was a 3 day at home coding problem.  There were always 3 different questions and each could be knocked out in a few hours.  The candidate could choose which one they wanted to solve and upon submission, the solution was looked at by at least 2 different developers.  The great part about this is that we could filter out a lot of candidates before bringing them in to the intensive day long interview.  The downside of a take home test is that you never really know if they got some help.  Which is why in this type of interview it&#39;s important to go over their solution in person.&lt;br /&gt;&lt;br /&gt;One coding interview I did was 2 developers and I working on a Rails plugin.  It seemed like a good idea, but I don&#39;t create Rails sites from scratch every day so there was a fair bit of fumbling around hooking up the database and trying to remember what generators to use and so on.  When we finally got to the writing a plugin part I was a bit flustered and short on time.  We made some progress but I don&#39;t think either of us were satisfied with the outcome.  This brings me to an important point:  You will accomplish a lot less in an hour than you think you might.  This is because the interviewee is using an unfamiliar machine, text editor, doesn&#39;t have his or her custom bash aliases available, and is being watched.  And questioned.  All this will slow anyone down by 50%.  So if it would take you 30 minutes to solve a given problem from scratch then it&#39;s about right for an hour long pairing interview.&lt;br /&gt;&lt;br /&gt;At &lt;a href=&quot;http://obtiva.com/&quot;&gt;Obtiva&lt;/a&gt;, &lt;a href=&quot;http://twitter.com/aberant&quot;&gt;Colin&lt;/a&gt; and I paired on some truly horrible code that he had inherited.  Oh the stories we could tell you about that code base...  But I&#39;m not sure how I feel about these &quot;work with me&quot; interviews if they are going to last less than 3-4 hours.  Actually, a day would be a better time allotment for this type of interview.  The reason is that solving a problem in an existing code base requires a lot of backstory.  If you only have an hour or two it&#39;s hard to grok the domain and you may just be testing the candidate for familiarity with the subject matter instead of pure programming talent.  It would be easy to miss a good candidate or hire someone who just happens to know the domain.&lt;br /&gt;&lt;br /&gt;Speaking of domain, you should try as hard as possibly to eliminate it from your coding problem.  I once did an interview with a firm where the challenge was to build a highly simplified version of something from their domain.  The problem was that it really wasn&#39;t simplified enough.  After reading a page and a half describing the system my head was spinning with new terms and concepts (I wasn&#39;t familiar at all with their field).  They had helpfully started me out with some stub classes and some failing cucumber specs but when piled onto a shaky foundational understanding it actually hurt more than it helped.  I had to figure out the domain, understand the class stubs (and any hints they may have been providing), describe what I was doing to the interviewer, understand what the cucumber tests were asking for, and navigate an unfamiliar workstation.  It turned into a bit of a train wreck.  Basically I did what I do when I don&#39;t understand something:  I went slow and tested everything.  But I ran out of time before I could even get one of the cucumber scenarios passing.&lt;br /&gt;&lt;br /&gt;You should try to structure the problem so that it has an easily achievable first step.  This enables the interviewee to get his or her confidence up to try the trickier parts and also provides an easy hint you can give them if the are struggling.  You might say:  &quot;Hey, why don&#39;t you just try and get X working.&quot;  X being the easy part.  You&#39;ll get better results when people are relaxed.&lt;br /&gt;&lt;br /&gt;At &lt;a href=&quot;http://backstopsolutions.com/&quot;&gt;Backstop&lt;/a&gt; we have a couple of coding questions, but the central theme is that the domain is either something everyone is totally familiar with or we can teach them in a few minutes before the coding starts.  We also make sure that the candidate pairs with different programmers to see how they interact with different people.  Now pairing while interviewing is not like regular pairing, of course.  When I run the interview, I approach pairing with an interviewee like I&#39;m a novice developer who is a domain expert.  I&#39;ll answer any questions they have about the domain but I don&#39;t help much with the coding part.  I always allow access to any documentation they want to look up and of course I have irb open and ready for experimentation.&lt;br /&gt;&lt;br /&gt;For me the pairing interview is just a way to have an engaging conversation about code.  If someone doesn&#39;t solve the problem but does so in an interesting and thoughtful way then I consider it a success.  This also means that an unreadable working solution is considered a failure.&lt;br /&gt;&lt;br /&gt;Having actual programing be a part of your interview process will take a some thought, but all that time is well worth the effort.  I can&#39;t tell you how many times someone has sailed through the talking parts of the process only to crash and burn in the coding section.  Hiring someone who is great at talking about code but terrible at actually coding is one of the worst things you can do.</content><link rel='replies' type='application/atom+xml' href='http://jakescruggs.blogspot.com/feeds/482694815251915790/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1042801964488488185/482694815251915790' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1042801964488488185/posts/default/482694815251915790'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1042801964488488185/posts/default/482694815251915790'/><link rel='alternate' type='text/html' href='http://jakescruggs.blogspot.com/2010/05/interview-coding-problems.html' title='Interview Coding Problems'/><author><name>Jake Scruggs</name><uri>http://www.blogger.com/profile/16274380203959781950</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://farm1.static.flickr.com/200/441258345_b0379aaf00_m.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1042801964488488185.post-1380155276900785539</id><published>2010-05-17T20:45:00.000-05:00</published><updated>2010-05-17T20:45:00.065-05:00</updated><title type='text'>Upcoming Speaking Dates</title><content type='html'>I&#39;ll be giving an all new talk entitled &quot;The Necessity and Implementation of Speedy Tests&quot; at &lt;a href=&quot;http://rubykaigi.org/2010/en&quot;&gt;Ruby Kaigi&lt;/a&gt; in Japan!  Ruby Kaigi is being held August 27-29th, 2010 in Tsukuba, Ibaraki, Japan.  Very exciting!&lt;br /&gt;&lt;br /&gt;Want to see the above talk but can&#39;t make it to Japan?  I&#39;ll be giving the same (ish) talk at &lt;a href=&quot;http://www.rubymidwest.com/&quot;&gt;Ruby Midwest&lt;/a&gt; in Kansas City, MO.  Ruby Midwest will be held July 16-17, 2010.&lt;br /&gt;&lt;br /&gt;Stop on by and say hello -- I&#39;ll be the guy in the crazy shirt.</content><link rel='replies' type='application/atom+xml' href='http://jakescruggs.blogspot.com/feeds/1380155276900785539/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1042801964488488185/1380155276900785539' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1042801964488488185/posts/default/1380155276900785539'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1042801964488488185/posts/default/1380155276900785539'/><link rel='alternate' type='text/html' href='http://jakescruggs.blogspot.com/2010/05/upcoming-speaking-dates.html' title='Upcoming Speaking Dates'/><author><name>Jake Scruggs</name><uri>http://www.blogger.com/profile/16274380203959781950</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://farm1.static.flickr.com/200/441258345_b0379aaf00_m.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1042801964488488185.post-4092176406052456118</id><published>2010-05-16T20:20:00.000-05:00</published><updated>2010-05-16T20:23:44.978-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Backstop"/><category scheme="http://www.blogger.com/atom/ns#" term="consulting"/><category scheme="http://www.blogger.com/atom/ns#" term="Obtiva"/><title type='text'>Why I Left Obtiva</title><content type='html'>Recently I ended my nearly 2 year relationship with &lt;a href=&quot;http://obtiva.com/&quot;&gt;Obtiva&lt;/a&gt; and why I left deserves a few words.&lt;br /&gt;&lt;br /&gt;The issues I had with Obtiva were mostly just issues I have with consulting: &lt;br /&gt;&lt;ul&gt;&lt;li&gt;You only work at places messed up enough that they need to hire consultants &lt;/li&gt;&lt;li&gt;You leave before you get to spend time with code you wrote so it&#39;s hard to learn long term lessons &lt;/li&gt;&lt;li&gt;The most stable gigs that pay the bills for a consultancy tend to be the worst programming experiences (Large corporations with way more money than sense)&lt;/li&gt;&lt;li&gt;You have to track every hour of your time&lt;/li&gt;&lt;li&gt;Time off has to be negotiated with two companies instead of one&lt;/li&gt;&lt;li&gt;Learning a whole new bunch of names. personalities, and organizational structures every 6 months&lt;/li&gt;&lt;/ul&gt;Now don&#39;t get me wrong, consulting with ThoughtWorks and then Obtiva made me a much better programmer and was an amazing learning experience but I felt that, in order to grow as a programmer, I needed to work for a product company and learn the lessons that only living with a code base long term can teach you.  Consulting is a great drinking-from-a-fire-hose experience that every developer should consider, but it has its limitations.  So I joined &lt;a href=&quot;http://backstopsolutions.com/&quot;&gt;Backstop Solutions &lt;/a&gt;and I write Ruby on Rails sites for hedge funds and the people who use them (note: we sell products to hedge funds, I don&#39;t actually work for a hedge fund).&lt;br /&gt;   &lt;br /&gt;Why Backstop?  Well, it&#39;s big enough (60ish people) that they&#39;ve worked out most of the kinks of being a business (direct deposit, 401k, health insurance, etc.) but small enough that you can get to know everyone and (hopefully) help steer the company.  Their product is strong and growing, but there&#39;s some new products in the works too.  They do Agile but would like to do it better (I&#39;ve been brought on to help with that in addition to my coding responsibilities).  But the best part was that while everyone is smart and nice, it&#39;s oddly unknown in the Ruby community -- and I can help with that.&lt;br /&gt;&lt;br /&gt;Obtiva was a great experience.  During my time there I moved from being just a coder to being more of a leader, started speaking at conferences, got to participate in many wonderful geekfests, helped mentor software apprentices (which I once was), and learned a ton from all the programmers I interacted with. &lt;br /&gt;&lt;br /&gt;To sum up I&#39;ll quote from my company-wide resignation email:  &quot;Mommy and daddy still love each other.  Except we&#39;re going to see other people.  And not live together.&quot;</content><link rel='replies' type='application/atom+xml' href='http://jakescruggs.blogspot.com/feeds/4092176406052456118/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1042801964488488185/4092176406052456118' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1042801964488488185/posts/default/4092176406052456118'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1042801964488488185/posts/default/4092176406052456118'/><link rel='alternate' type='text/html' href='http://jakescruggs.blogspot.com/2010/05/why-i-left-obtiva.html' title='Why I Left Obtiva'/><author><name>Jake Scruggs</name><uri>http://www.blogger.com/profile/16274380203959781950</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://farm1.static.flickr.com/200/441258345_b0379aaf00_m.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1042801964488488185.post-4934757985106449905</id><published>2010-05-14T11:15:00.001-05:00</published><updated>2010-05-14T11:21:15.564-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="XP"/><title type='text'>Are you Really Doing Agile Development?</title><content type='html'>So recently at work I was asked help to make the company more &quot;Agile.&quot;  Well I&#39;m a developer first and process wonk second so I responded with my usual &quot;How many of the 12 practices are you really following?&quot;  Which was met with a lot blank stares.  Turns out the classic XP practices are not so easy to find on the internet anymore.  It also turns out that the word &quot;Agile&quot; has been so successful that lots of people don&#39;t know that XP stands for Extreme Programming.  Now I&#39;ll be the first to admit that &quot;Extreme Programming&quot; is a colossally stupid name, but what I like about XP and the original 12 practices is that they were controversial and easy to evaluate:  Either you were doing them or you weren&#39;t.  What I don&#39;t like about &quot;Agile&quot; is that it&#39;s so broad and defined in such a &quot;hand wavy&quot; way that pretty much everyone can fool themselves into thinking that they already are fully Agile.&lt;br /&gt;&lt;br /&gt;So to fix this and help my company start measuring their &quot;Agility&quot; better, I&#39;ve decided to list out classic (They&#39;ve changed over time -- but not for me.  And get off my lawn!) 12 XP processes.  And my highly opinionated view of each of them.  After that I&#39;ll tell you how to score your &quot;Agility.&quot;&lt;br /&gt;&lt;br /&gt;* Planning Game&lt;br /&gt;  Get requirements from customer, form them into (short) stories, estimate the time it will take, do them, measure velocity, examine failed estimates for clues as to how to estimate better, and repeat.  A story should be a placeholder for a conversation -- This only works if the customer (or surrogate) is highly available to the developers and the developers take advantage of that availability by checking in frequently during the development process.  Note:  Stories that take longer than a day significantly undermine many of the other parts of XP.&lt;br /&gt; &lt;br /&gt;* Small Releases&lt;br /&gt;  Iterations should be 1-2 weeks (depending on how painful/expensive it is to organize an iteration).  Releases should happen after every iteration if the application is easy to deploy (web apps).&lt;br /&gt;&lt;br /&gt;* Metaphor&lt;br /&gt;  Nobody does this.  Extra points if you do.&lt;br /&gt;&lt;br /&gt;* Simple Design&lt;br /&gt;  This means different things at different levels.  When kicking off a green field project a week of requirements gathering and design is good.  For an individual story, a few minutes to an hour is good.  Then you start writing code.  Important:  Design as you go.  Stopping to spend a few hours with a whiteboard is allowed and encouraged.  Do the simplest thing that could possible work until it becomes apparent that it will not.  Then redesign.  The idea is that at the beginning of the project you know the least about it -- spread the design across the life of the project so you can make design decisions with more knowledge.&lt;br /&gt;&lt;br /&gt;* Testing&lt;br /&gt;  Test first.  Coverage above 80% for Java, 90% for Ruby (less exception checking in Ruby means easier to cover).  Non-brittle, atomic, fast tests (unit tests should run under 5 min. Actually under 1 minute is best, but most think that&#39;s impossible (spoiler: Its possible)).&lt;br /&gt;&lt;br /&gt;* Refactoring&lt;br /&gt;  Short:  Red, Green, Refactor!  Long:  Write a failing test, make it pass, refactor the code.  This also means when you wander into a messy place you leave it a little better than you found it.   &lt;br /&gt;&lt;br /&gt;* Pair Programming&lt;br /&gt;  Above 80% of the time.  Seriously.  Tasks that seem like you can&#39;t pair on them often mean that you aren&#39;t using the right pairing techniques.  Pairing is a skill:  Get good at it.&lt;br /&gt;&lt;br /&gt;* Collective Code Ownership&lt;br /&gt;  Anyone can change any code.  Yes, they should consult whoever is knowledgeable about said code, but there are no parts of the code that only developer X is allowed to touch.&lt;br /&gt;&lt;br /&gt;* Continuous Integration&lt;br /&gt;  Every check-in to the remote repository triggers a comprehensive suite of unit tests.  The developers have to care if the build fails.  For example:  When the build fails, no one checks in until it is fixed.  Also there should be some social ridicule for the build breaker (have to wear a stupid hat for the rest of the day, an obnoxious build breaker trophy placed on their desk, they have to buy donuts for the team, etc.).  This all assumes that the build is reliable and that a failure means there is a real problem. &lt;br /&gt;&lt;br /&gt;* 40-hour Week&lt;br /&gt;  Now called &quot;Sustainable Pace&quot; because &quot;40-hour Week&quot; tends to scare managers and end of project pushes are sometimes necessary even in XP.  This should be no more than 2 weeks, have a clearly defined point at which the long hours will stop, and happen no more than twice a year.  Actually, if it happens twice a year it means your estimation skills need to get better.&lt;br /&gt; &lt;br /&gt;* On-site Customer&lt;br /&gt;  Doesn&#39;t happen often for non-internal projects.  Usually customer surrogates are used.  These surrogates need to take pains to talk to real users often (not just the managers of the users) and be highly available to developers to answer questions. &lt;br /&gt; &lt;br /&gt;* Coding Standards&lt;br /&gt;  Doesn&#39;t matter what they are but the developers need to come to a consensus and stick to it.  Consensus does not mean everyone nods yes in the meeting but ignores the standards when they feel like it.&lt;br /&gt; &lt;br /&gt;So how do I score my Agility?  Take the number of practices that you actually do, divide by 12, and then multiple by 100 -- that&#39;s your percent Agile.  Do not give yourself a point if you don&#39;t fully implement a practice.  Have Continuous Integration but some of the tests fail randomly?  No point.  You pair &quot;when necessary&quot; which ends up being 40% of the time.  No point!  Run iterations but don&#39;t estimate your stories?  No Point!!&lt;br /&gt;&lt;br /&gt;This is take a hard look at yourself in the mirror time, not some hippie love fest.</content><link rel='replies' type='application/atom+xml' href='http://jakescruggs.blogspot.com/feeds/4934757985106449905/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1042801964488488185/4934757985106449905' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1042801964488488185/posts/default/4934757985106449905'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1042801964488488185/posts/default/4934757985106449905'/><link rel='alternate' type='text/html' href='http://jakescruggs.blogspot.com/2010/05/are-you-really-doing-agile-development.html' title='Are you Really Doing Agile Development?'/><author><name>Jake Scruggs</name><uri>http://www.blogger.com/profile/16274380203959781950</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://farm1.static.flickr.com/200/441258345_b0379aaf00_m.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1042801964488488185.post-3095689412863072053</id><published>2009-08-30T18:51:00.004-05:00</published><updated>2009-08-30T19:18:31.977-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="LoneStarRubyConf2009"/><category scheme="http://www.blogger.com/atom/ns#" term="Ruby"/><title type='text'>Lone Star Ruby Conf 2009 Day Two Afternoon Sessions</title><content type='html'>&lt;span style=&quot;font-weight: bold;&quot;&gt;More Lighting Talks!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;A lot of people skip the lighting talks, but I find that some of the best stuff at any given conference comes out of the these intense 7 minutes sessions.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Jared Ning: &quot;Ruby Without Borders&quot; &lt;/span&gt;&lt;br /&gt;Matthew Todd gave a talk last year asking for people to came to Tanzania and help him code in Ruby.  Jared did and he loved the experience.&lt;br /&gt;He mentioned a very useful TextMate short-cut:&lt;br /&gt;If you have a bunch of files and folders open in the project drawer and you click the chevron (the triangle thingy) to close a top level folder then when you open it back up TextMate remembers the state of what folders were open and closed underneath.  But sometimes you want to close down all the folders underneath.  Option clicking on the chevron will do that.  Also, option clicking on a closed chevron will open up all sub folders.  I&#39;ve been looking for this.&lt;br /&gt;&lt;br /&gt;Check out &lt;a href=&quot;http://matthewtodd.org/2009/01/26/ruby-without-borders.html&quot;&gt;Ruby Without Borders&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Jeffrey Taylor: &quot;Fast Multi-protocol XML Parsing&quot;&lt;/span&gt;&lt;br /&gt;Jeffrey&#39;s project had to read a lot of RSS feeds and it was super slow even with the fast ruby xml parsers.  So he rolled his own, which can be found here:&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://abluz.dyndns.org/fast_xml_parsing.rb&quot;&gt;http://abluz.dyndns.org/fast_xml_parsing.rb&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Jeffrey used the &lt;a href=&quot;http://en.wikipedia.org/wiki/Simple_API_for_XML&quot;&gt;sax model&lt;/a&gt; to do super fast xml parsing (10 times faster than nokogiri - he claims).  He does admit that the code has a Flog score of over 500 for one method.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Hal Fulton: &quot;Reia: The Next Big Thing&quot; &lt;/span&gt;&lt;br /&gt;&lt;a href=&quot;http://wiki.reia-lang.org/wiki/Reia_Programming_Language&quot;&gt;Reia&lt;/a&gt; is an attempt to combine Erlang and Ruby.  If you want the cool concurrency of Erlang with Rubyish syntax, take a look.&lt;br /&gt;&lt;br /&gt;Yehuda Katz: &lt;a href=&quot;http://github.com/wycats/bundler&quot;&gt;http://github.com/wycats/bundler&lt;/a&gt;&lt;br /&gt;A true dependency resolver&lt;br /&gt;From the README:&lt;br /&gt;&lt;blockquote&gt;Bundler is a tool that manages gem dependencies for your ruby application. It takes a gem manifest file and is able to fetch, download, and install the gems and all child dependencies specified in this manifest. It can manage any update to the gem manifest file and update the bundled gems accordingly. It also lets you run any ruby code in context of the bundled gem environment.&lt;/blockquote&gt;So basically it&#39;s a better way to vendor your gems with your project.  Check it out if you&#39;ve had trouble using other systems.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Before Matz&#39;s Q and A, Jim Freeze got up and talked about Lone Star Ruby Conf&#39;s attendance over it&#39;s three year span:&lt;br /&gt;2007 - 200&lt;br /&gt;2008 - 282&lt;br /&gt;2009 - 230ish&lt;br /&gt;&lt;br /&gt;Which is right around where they want it.  Small enough to be intimate, large enough to be interesting.  And that size group fits nicely in the Norris Conference Center.&lt;br /&gt;&lt;br /&gt;Btw, the network was outstanding this year.  They bought something like 6 wireless routers and although sometimes it was sluggish, it remains some of the best wireless I&#39;ve had at a conference.  Usually the high tech load crashes the network within minutes.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Matz Q and A&lt;/span&gt;&lt;br /&gt;The two answers that stood out to me were when he said that the Perl $ variables were the thing he regrets the most about designing Ruby.  Also, when I asked him about how often he gets to write in Ruby he said that the largest Ruby program he ever wrote is 2-3000 lines of ruby code.  It was a mail client with Emacs front end.  Generally he uses it for scripts and such.  I find it amazing and a little heartbreaking that Matz doesn&#39;t get to program in the language he created and clearly loves.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Encoding Domains - Rich Kilmer&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;First, there was a lot of buzz about &lt;a href=&quot;http://prezi.com/&quot;&gt;Prezi&lt;/a&gt; at the conference.  Prezi is a canvas presentation tool that so impressed Rich Kilmer that he learned it the night before and wrote his keynote in it.  In Prezi you put all your text, videos, images, sound files, and whatever in one huge canvas and then tell give it a bunch of waypoints and zoom levels to follow.  It&#39;s pretty bad-ass.&lt;br /&gt;&lt;br /&gt;This was Rich&#39;s first keynote ever.  Which is kinda hard the believe as he&#39;s been doing amazing things with Ruby since the dawn of time (which is 2000, btw).  In it he discussed how software libraries don&#39;t have value, they have potential.  What has real value is encoding domains.  He told an interesting story about how he encoded the domain of a massive military project mostly by sitting down with some experts in the field and figuring out how they would like the DSL to read.  Once he had captured all the information they could enter in to their logistics system in syntactically correct Ruby, he went about making it work.  He called it syntax driven development and it worked so well that 5 years later he still gets calls about the prototype he wrote in two months.  Apparently they are still trying to create the real product in some other language.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Well, the perfect storm of conferences (Agile 2009, Software Craftsmanship North America, and Lone Star Ruby Conf) is now over and I&#39;m looking forward to actually writing some Ruby tomorrow.  I need the rest.</content><link rel='replies' type='application/atom+xml' href='http://jakescruggs.blogspot.com/feeds/3095689412863072053/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1042801964488488185/3095689412863072053' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1042801964488488185/posts/default/3095689412863072053'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1042801964488488185/posts/default/3095689412863072053'/><link rel='alternate' type='text/html' href='http://jakescruggs.blogspot.com/2009/08/lone-star-ruby-conf-2009-day-two.html' title='Lone Star Ruby Conf 2009 Day Two Afternoon Sessions'/><author><name>Jake Scruggs</name><uri>http://www.blogger.com/profile/16274380203959781950</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://farm1.static.flickr.com/200/441258345_b0379aaf00_m.jpg'/></author><thr:total>0</thr:total></entry></feed>