<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1069467794206617140</id><updated>2012-01-19T11:48:04.944-08:00</updated><category term='ruby'/><category term='setup'/><category term='formatting'/><category term='tiger'/><category term='code'/><category term='biomimicry'/><category term='gems'/><category term='rails'/><category term='rcov osx install'/><title type='text'>Biomime: Coding and Biology</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://biomime.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://biomime.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Jeremy Rice</name><uri>http://www.blogger.com/profile/12256074521855601742</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-wV3OV11Fp0k/TxhzaIa4zSI/AAAAAAAAPXQ/GY4PplLad-I/s220/AllSpiritualLike.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>38</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1069467794206617140.post-2420567710837315881</id><published>2009-10-19T18:37:00.000-07:00</published><updated>2009-10-19T18:37:43.999-07:00</updated><title type='text'>Questions for an Interview</title><content type='html'>&lt;div&gt;&lt;b&gt;QUESTION:&lt;/b&gt; Based on your resume, you have [seen lots of different management styles OR had extended experience with a single employer]. With that experience, I'm sure you've seen your share of good and bad management practices. What are some of the worst things you have seen management do? What style of management works best for you?&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Of course, this is a trap! This is a good indication of whether or not the person will fit into the management style you use. Typically, the applicant will answer "micro-management" (as the worst style), and that they prefer someone a little more hands-off. ...I find this to be a cop-out. A good answer here would use a specific example of something that management did poorly and how the applicant attempted to resolve it. The best answers to "best for you" would involve managers that give the applicant the tools they need to succeed. Such answers demonstrate that the person knows how a team actually works, that they are driven, and that they can overcome obstacles.&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;QUESTION&lt;/b&gt;: What do you think are the most important qualities of [good code]?&lt;br /&gt;&lt;br /&gt;...Note that this could be applied to pretty much any trade, just be sure you're asking about the &lt;i&gt;resulting product&lt;/i&gt;, not the position--that's a different question.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Any answers that demonstrate they have thought about this (hopefully, a LOT), and they've formulated their own opinions about what makes the product good. of course, you can choose to add your own interpretation to their answers to see if they are a good fit with your company, too: do they share values with the other workers?&lt;/blockquote&gt;&lt;br /&gt;&lt;b&gt;QUESTION:&lt;/b&gt; What do you think are the most important traits for a [developer]?&lt;br /&gt;&lt;br /&gt;...Note that, of course, you can change "developer" for anything you want.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;You want them--WITHOUT PROMPTING--to list off their own best traits, and to explain how they posses them. If you have to prompt them with a question like "...and how do you think you measure up to these?", then you've found an applicant that isn't very applied and is probably low-confidence. It comes out naturally with good applicants. And, again, you want to compare their answer with the values of your current employes to see if it's a good match.&lt;/blockquote&gt;&lt;br /&gt;&lt;b&gt;QUESTION:&lt;/b&gt; What makes you a remarkable candidate? What do you think makes you stand out from the other applicants?&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Well, you may or may not want to see some humility here ("I don't know if this makes me *remarkable*, but..."); that's up to you. But this answer yields a good idea about their level of confidence and what they like to do most. ...Not necessarily what they're best at, since their answer is so biased. : )&lt;/blockquote&gt;&lt;br /&gt;&lt;b&gt;QUESTION:&lt;/b&gt; Out of all the people you've worked with, who would you say you respected most, and why?&lt;br /&gt;&lt;br /&gt;[after they answer]&lt;br /&gt;&lt;br /&gt;...If I were to ask that person to describe you, what would they say?&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Well, I'm not sure, but the point of this question is to get the applicant to think about two things and how they relate: what they like most in a co-worker, and what co-workers probably think of them.&lt;/blockquote&gt;&lt;br /&gt;&lt;b&gt;QUESTION:&lt;/b&gt; Assuming you get this job, what would be your biggest fear? What do you feel could go horribly wrong?&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;If nothing else, I think this question gives you a chance to see how the applicant handles a stressful, difficult question. Ideally, they would answer honestly, and tell you what the biggest potential incompatibility would be. However, I find that most applicants shrug this question off and use it to make a joke. I've also seen applicants really choke on it, which (to me) was a good indication that they weren't likely to work well under stress, and that they aren't comfortable being honest with authority figures.&lt;/blockquote&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1069467794206617140-2420567710837315881?l=biomime.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biomime.blogspot.com/feeds/2420567710837315881/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1069467794206617140&amp;postID=2420567710837315881' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/2420567710837315881'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/2420567710837315881'/><link rel='alternate' type='text/html' href='http://biomime.blogspot.com/2009/10/questions-for-interview.html' title='Questions for an Interview'/><author><name>Jeremy Rice</name><uri>http://www.blogger.com/profile/12256074521855601742</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-wV3OV11Fp0k/TxhzaIa4zSI/AAAAAAAAPXQ/GY4PplLad-I/s220/AllSpiritualLike.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1069467794206617140.post-4636611327971678867</id><published>2009-10-15T06:01:00.001-07:00</published><updated>2009-10-15T06:01:37.621-07:00</updated><title type='text'>Kids' contest: art and nature</title><content type='html'>&lt;a href="http://www.gettoknow.ca/us/contest/"&gt;http://www.gettoknow.ca/us/contest/&lt;/a&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif; font-size: 13px; color: rgb(56, 56, 56); line-height: 23px; "&gt;The contest, recently launch in California for the first time and currently accepting entries, is an invitation for youth (age 18 and younger) to go outside (or to a zoo, aquarium, or museum), to &amp;quot;get to know&amp;quot; their wild neighbors, and then to share their experience with the world by creating an original work of art, photography, or writing and then entering their creation in the contest.&lt;/span&gt;&lt;/div&gt;  &lt;div&gt;&lt;font class="Apple-style-span" color="#383838" face="Arial, Helvetica, sans-serif"&gt;&lt;span class="Apple-style-span" style="line-height: 23px;"&gt;&lt;br&gt;&lt;/span&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font class="Apple-style-span" color="#383838" face="Arial, Helvetica, sans-serif"&gt;&lt;span class="Apple-style-span" style="line-height: 23px;"&gt;&lt;br&gt;  &lt;/span&gt;&lt;/font&gt;&lt;/div&gt;...Perhaps something EOL could get involved with?  Sounds like it&amp;#39;s CA-only at the moment, but I could be mistaken. &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1069467794206617140-4636611327971678867?l=biomime.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biomime.blogspot.com/feeds/4636611327971678867/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1069467794206617140&amp;postID=4636611327971678867' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/4636611327971678867'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/4636611327971678867'/><link rel='alternate' type='text/html' href='http://biomime.blogspot.com/2009/10/kids-contest-art-and-nature.html' title='Kids&apos; contest: art and nature'/><author><name>Jeremy Rice</name><uri>http://www.blogger.com/profile/12256074521855601742</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-wV3OV11Fp0k/TxhzaIa4zSI/AAAAAAAAPXQ/GY4PplLad-I/s220/AllSpiritualLike.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1069467794206617140.post-649903999390770223</id><published>2009-07-16T14:51:00.000-07:00</published><updated>2009-07-16T14:51:04.595-07:00</updated><title type='text'>Legacy Doesn't Always Mean "Old"</title><content type='html'>I've decided the EOL website development project is a "Legacy Code" project.&lt;br /&gt;&lt;br /&gt;That may seem a bit naive, since it's really a start-up project that's two years old, give or take.&amp;nbsp; However, there are three reasons for my decision.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Because it was a &lt;i&gt;rapid&lt;/i&gt; start-up project that was done without "real" Agile development.&amp;nbsp; It accrued a surprising amount of &lt;a href="http://www.brainfuel.tv/code-debt"&gt;code debt&lt;/a&gt; in its early days.&lt;/li&gt;&lt;li&gt;Because the database is non-Rails in some serious ways. Particularly in its use of compound keys and the fact that it's spread over three databases instead of one.&amp;nbsp; There are good business reasons for these decisions, but they affect our use of Rails.&lt;/li&gt;&lt;li&gt;Because of the lack of robust testing.&lt;/li&gt;&lt;/ol&gt;It's the latter case that I am most interested in addressing first and with highest priority.&amp;nbsp; Our team agrees, but also points out that there is a lot of work needed in the area.&amp;nbsp; We have &lt;i&gt;lots&lt;/i&gt; of tests!&amp;nbsp; But they are difficult to use, fragile in some cases, slow, and so on.&amp;nbsp; Given these problems, we had a 90 minute meeting today, where we asked four questions:&lt;br /&gt;&lt;div style="margin-left: 40px;"&gt;&lt;ul&gt;&lt;li&gt;What are our overall testing goals, really?&lt;/li&gt;&lt;li&gt;How well are we achieving them, currently?&lt;/li&gt;&lt;li&gt;What are the most pressing needs?&lt;/li&gt;&lt;li&gt;How can we best apply our time to improve tests?&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;I found these to be very effective!&amp;nbsp; To answer the first one, we developed the following three answers:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Facilitate careful development (TDD).&lt;/li&gt;&lt;li&gt;Prevent regressions from being deployed.&lt;/li&gt;&lt;li&gt;Create enough trust to allow refactoring.&lt;/li&gt;&lt;/ol&gt;To the next three questions, we had a lively and effective discussion, with lots of excellent ideas and approaches discussed.&amp;nbsp; The end result was a list of concerns, another list of "action items" to address the most important among them, and, interestingly, a list of "philosophies" about how to approach tests.&amp;nbsp; They are somewhat specific to EOL, but they were cool enough that I feel compelled to share them:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;View and controller tests are really much like "unit" tests&lt;/b&gt;, since they are testing a method on a class... it's just a different "kind" of class.&lt;/li&gt;&lt;li&gt;&lt;b&gt;It's okay to throw away unit tests&lt;/b&gt; (including controller/view), as long as the features they are supporting are all tested with higher-level tests, and those tests are passing.&amp;nbsp; Implementation methods change, some of the requirements of the past are likely to change, too.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Try to write tests that are not fragile&lt;/b&gt; (meaning: refactoring doesn't fail tests).&amp;nbsp; The underlying idea is that when a &lt;em&gt;feature&lt;/em&gt; is complete, all tests should pass and when the feature is incomplete, some tests should fail.&amp;nbsp; Period.&amp;nbsp; The interals are less important, though someone may have a need to test them (at the Unit level) to help with developement.&lt;/li&gt;&lt;li&gt;&lt;b&gt;The blackbox, factory approach is more appropriate than mocks and specs in EOL's environment.&lt;/b&gt; But we need to make the domain logic approachable to developers (new ones in particular).&amp;nbsp; Copy/pasting solutions from other tests /works/, but is not ideal.&amp;nbsp; We need to make this easier to use, more convenient.&amp;nbsp; Developers should /want/ to write tests, becaise it's easy to do.&amp;nbsp; Newcomers have varying levels of domain knowledge.&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1069467794206617140-649903999390770223?l=biomime.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biomime.blogspot.com/feeds/649903999390770223/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1069467794206617140&amp;postID=649903999390770223' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/649903999390770223'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/649903999390770223'/><link rel='alternate' type='text/html' href='http://biomime.blogspot.com/2009/07/legacy-doesnt-always-mean-old.html' title='Legacy Doesn&apos;t Always Mean &quot;Old&quot;'/><author><name>Jeremy Rice</name><uri>http://www.blogger.com/profile/12256074521855601742</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-wV3OV11Fp0k/TxhzaIa4zSI/AAAAAAAAPXQ/GY4PplLad-I/s220/AllSpiritualLike.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1069467794206617140.post-98690933447551444</id><published>2009-07-10T17:03:00.000-07:00</published><updated>2009-07-10T17:03:57.630-07:00</updated><title type='text'>On Creating Effective Web Interfaces</title><content type='html'>At EOL, we've been asked to implement some new features that we (the developers) didn't like. They didn't seem to adhere to web-standards, didn't look particularly good, and didn't really seem to capture the problem (caveat: as &lt;i&gt;we&lt;/i&gt; see it) elegantly.&lt;br /&gt;&lt;br /&gt;This sparked a discussion (healthy, not heated) about how we could best approach design and web usability as we add features. Another developer wrote a blog-post about it.&amp;nbsp; (...internal-only; sorry, no link for you!)&amp;nbsp; I felt compelled to talk about the same subject myself and field some ideas.&amp;nbsp; His post was all well-formatted, edited, and technical.&amp;nbsp; Mine is casual and sloppy.&amp;nbsp; So it goes.&amp;nbsp; ; )&lt;br /&gt;&lt;br /&gt;So what's the problem? &lt;br /&gt;&lt;br /&gt;We're using Agile methods, so the proximal problem--which we are already trying to address--is that the temptation is strong to just "get something out there".&amp;nbsp; Users can respond to it, and we can quickly adjust our approach to build something they will like better.&lt;br /&gt;&lt;br /&gt;This has a few negative consequences:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The code gets ugly and risks leaving remnants of old styles when it changes.&amp;nbsp; Have a look at our CSS, for example.&amp;nbsp; :(&lt;br /&gt;&lt;/li&gt;&lt;li&gt;I think users can get scared away.&amp;nbsp; At least for &lt;i&gt;me,&lt;/i&gt; I know I've tried to use some feature of, say, Yahoo! Mail, hated it, and never looked at it again.&amp;nbsp; ...They may very well have cleaned things up later, but I don't care to look.&lt;/li&gt;&lt;li&gt;User feedback tends to... well... &lt;i&gt;suck&lt;/i&gt;.&amp;nbsp; In my experience, they'll ask for things that actually result in clutter.&amp;nbsp; Also, it's only the squeaky wheels that get heard, and their needs may be vastly different from the majority.&lt;/li&gt;&lt;li&gt;There is a &lt;i&gt;big&lt;/i&gt; but poorly-understood difference between a feature that's easy to use and one that is "intuitive".&amp;nbsp; The latter implies that a newcomer can step in and use the tool... well... intuitively.&amp;nbsp; This is great!&amp;nbsp; But it often creates an interface that wears on your quickly, or ends up something you hate over time.&amp;nbsp; Photoshop's clone tool is a good example of a tool that's easy to use, but not at all intuitive.&amp;nbsp; It's important to know which is better for your problem. I think that user-generated feedback generally comes from users who have tinkered with an interface for something on the order of minutes.&amp;nbsp; They're talking about intuitive use, not easy use.&lt;/li&gt;&lt;/ol&gt;...There are probably others, but I'm getting bored.&amp;nbsp; ; )&lt;br /&gt;&lt;br /&gt;The &lt;i&gt;core&lt;/i&gt; problem, I think, is that we really need someone skilled at web interfaces.&amp;nbsp; But we don't have the money to add someone to the team to do this, and everyone currently &lt;i&gt;on&lt;/i&gt; the team is too busy to pick up the skill and/or apply it at the expense of their current duties.&lt;br /&gt;&lt;br /&gt;In short, we are left with only one option: establish some guidelines by which we can do the best we can, on our own.&lt;br /&gt;&lt;br /&gt;To that end, I like the idea that my associate mentioned (interestingly enough, by quoting yet &lt;i&gt;another&lt;/i&gt; associate of mine): a list of usability questions that can be asked to gauge whether an interface works or not.&lt;br /&gt;&lt;br /&gt;...I think this is a reasonable start.&amp;nbsp; That said:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;I don't know who we should ask these questions.&lt;/li&gt;&lt;li&gt;I worry that we'll end up with design-by-committee interfaces, which usually suck.&amp;nbsp; Ideally, I hope that design can be limited to two people on any given feature.&amp;nbsp; ...Ideally-ideally, the same two people on &lt;i&gt;every&lt;/i&gt; feature, to maintain consistency.&lt;/li&gt;&lt;li&gt;Nothing in the questions mentions web standards/best-practices.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;I worry that this is going to take up more time than we have, and breed frustration at the slow implementation of new features.&lt;/li&gt;&lt;li&gt;I think the questions are good for measuring usability, but there are other concerns, such as intuitive-vs-easy, elegance, and the "message" conveyed by each feature.&amp;nbsp; I hope we can add questions into the mix so that these things are considered.&lt;/li&gt;&lt;li&gt;I think it's worth investing two or three people's time over a day or two (each) to research usability, and contribute to the "checklist" that we're building.&amp;nbsp; This could include best-practices, design methodology, questions to ask, and the like.&lt;/li&gt;&lt;/ul&gt;I could go on.&amp;nbsp; This is a fascinating subject with many different possible solutions.&amp;nbsp; ...Sadly, I don't think &lt;i&gt;any&lt;/i&gt; of them are even remotely as good as "hire an expert".&amp;nbsp; : (&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1069467794206617140-98690933447551444?l=biomime.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biomime.blogspot.com/feeds/98690933447551444/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1069467794206617140&amp;postID=98690933447551444' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/98690933447551444'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/98690933447551444'/><link rel='alternate' type='text/html' href='http://biomime.blogspot.com/2009/07/on-creating-effective-web-interfaces.html' title='On Creating Effective Web Interfaces'/><author><name>Jeremy Rice</name><uri>http://www.blogger.com/profile/12256074521855601742</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-wV3OV11Fp0k/TxhzaIa4zSI/AAAAAAAAPXQ/GY4PplLad-I/s220/AllSpiritualLike.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1069467794206617140.post-870449376142985742</id><published>2009-06-02T19:01:00.000-07:00</published><updated>2009-06-02T19:24:52.079-07:00</updated><title type='text'>"rake stats" should count all my stuff!</title><content type='html'>We have some custom directories for Specs, which aren't counted when you run "rake stats".&amp;nbsp; I thought we deserved more credit!&amp;nbsp; : )&lt;br /&gt;&lt;br /&gt;I put at the bottom of our Rakefile.&amp;nbsp; It's a little... brute-force, as it trumps RSpec's own task of the same name, but it does the trick:&lt;br /&gt;&lt;br /&gt;&lt;pre class="textmate-source"&gt;&lt;span class="source source_ruby"&gt;&lt;span class="comment comment_line comment_line_number-sign comment_line_number-sign_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_ruby"&gt;#&lt;/span&gt; We have some pretty customized stat directories, so:&lt;br /&gt;&lt;/span&gt;&lt;span class="meta meta_require meta_require_ruby"&gt;&lt;span class="keyword keyword_other keyword_other_special-method keyword_other_special-method_ruby"&gt;require&lt;/span&gt; &lt;span class="string string_quoted string_quoted_single string_quoted_single_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;'&lt;/span&gt;spec/rake/spectask&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;namespace &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;spec&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_start-block keyword_control_start-block_ruby"&gt;do&lt;br /&gt;&lt;/span&gt;&lt;span class="comment comment_line comment_line_number-sign comment_line_number-sign_ruby"&gt;  &lt;span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_ruby"&gt;#&lt;/span&gt; Setup specs for stats&lt;br /&gt;&lt;/span&gt;  task &lt;span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby"&gt;:&lt;/span&gt;statsetup&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_start-block keyword_control_start-block_ruby"&gt;do&lt;br /&gt;&lt;/span&gt;    &lt;span class="meta meta_require meta_require_ruby"&gt;&lt;span class="keyword keyword_other keyword_other_special-method keyword_other_special-method_ruby"&gt;require&lt;/span&gt; &lt;span class="string string_quoted string_quoted_single string_quoted_single_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;'&lt;/span&gt;code_statistics&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="punctuation punctuation_separator punctuation_separator_other punctuation_separator_other_ruby"&gt;::&lt;/span&gt;&lt;span class="variable variable_other variable_other_constant variable_other_constant_ruby"&gt;STATS_DIRECTORIES&lt;/span&gt; &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_augmented keyword_operator_assignment_augmented_ruby"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="string string_quoted string_quoted_other string_quoted_other_literal string_quoted_other_literal_lower string_quoted_other_literal_lower_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;%w(&lt;/span&gt;Blackbox\ specs spec/blackbox&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;if&lt;/span&gt; &lt;span class="support support_class support_class_ruby"&gt;File&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;exist?&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;(&lt;/span&gt;&lt;span class="string string_quoted string_quoted_single string_quoted_single_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;'&lt;/span&gt;spec/blackbox&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="punctuation punctuation_separator punctuation_separator_other punctuation_separator_other_ruby"&gt;::&lt;/span&gt;&lt;span class="variable variable_other variable_other_constant variable_other_constant_ruby"&gt;STATS_DIRECTORIES&lt;/span&gt; &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_augmented keyword_operator_assignment_augmented_ruby"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="string string_quoted string_quoted_other string_quoted_other_literal string_quoted_other_literal_lower string_quoted_other_literal_lower_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;%w(&lt;/span&gt;Model\ specs spec/models&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;if&lt;/span&gt; &lt;span class="support support_class support_class_ruby"&gt;File&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;exist?&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;(&lt;/span&gt;&lt;span class="string string_quoted string_quoted_single string_quoted_single_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;'&lt;/span&gt;spec/models&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="punctuation punctuation_separator punctuation_separator_other punctuation_separator_other_ruby"&gt;::&lt;/span&gt;&lt;span class="variable variable_other variable_other_constant variable_other_constant_ruby"&gt;STATS_DIRECTORIES&lt;/span&gt; &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_augmented keyword_operator_assignment_augmented_ruby"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="string string_quoted string_quoted_other string_quoted_other_literal string_quoted_other_literal_lower string_quoted_other_literal_lower_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;%w(&lt;/span&gt;View\ specs spec/views&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;if&lt;/span&gt; &lt;span class="support support_class support_class_ruby"&gt;File&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;exist?&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;(&lt;/span&gt;&lt;span class="string string_quoted string_quoted_single string_quoted_single_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;'&lt;/span&gt;spec/views&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="punctuation punctuation_separator punctuation_separator_other punctuation_separator_other_ruby"&gt;::&lt;/span&gt;&lt;span class="variable variable_other variable_other_constant variable_other_constant_ruby"&gt;STATS_DIRECTORIES&lt;/span&gt; &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_augmented keyword_operator_assignment_augmented_ruby"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="string string_quoted string_quoted_other string_quoted_other_literal string_quoted_other_literal_lower string_quoted_other_literal_lower_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;%w(&lt;/span&gt;Controller\ specs spec/controllers&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;if&lt;/span&gt; &lt;span class="support support_class support_class_ruby"&gt;File&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;exist?&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;(&lt;/span&gt;&lt;span class="string string_quoted string_quoted_single string_quoted_single_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;'&lt;/span&gt;spec/controllers&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="punctuation punctuation_separator punctuation_separator_other punctuation_separator_other_ruby"&gt;::&lt;/span&gt;&lt;span class="variable variable_other variable_other_constant variable_other_constant_ruby"&gt;STATS_DIRECTORIES&lt;/span&gt; &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_augmented keyword_operator_assignment_augmented_ruby"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="string string_quoted string_quoted_other string_quoted_other_literal string_quoted_other_literal_lower string_quoted_other_literal_lower_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;%w(&lt;/span&gt;Selenium\ specs spec/selenium&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;if&lt;/span&gt; &lt;span class="support support_class support_class_ruby"&gt;File&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;exist?&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;(&lt;/span&gt;&lt;span class="string string_quoted string_quoted_single string_quoted_single_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;'&lt;/span&gt;spec/selenium&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="punctuation punctuation_separator punctuation_separator_other punctuation_separator_other_ruby"&gt;::&lt;/span&gt;&lt;span class="variable variable_other variable_other_constant variable_other_constant_ruby"&gt;STATS_DIRECTORIES&lt;/span&gt; &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_augmented keyword_operator_assignment_augmented_ruby"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="string string_quoted string_quoted_other string_quoted_other_literal string_quoted_other_literal_lower string_quoted_other_literal_lower_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;%w(&lt;/span&gt;Helper\ specs spec/helpers&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;if&lt;/span&gt; &lt;span class="support support_class support_class_ruby"&gt;File&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;exist?&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;(&lt;/span&gt;&lt;span class="string string_quoted string_quoted_single string_quoted_single_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;'&lt;/span&gt;spec/helpers&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="punctuation punctuation_separator punctuation_separator_other punctuation_separator_other_ruby"&gt;::&lt;/span&gt;&lt;span class="variable variable_other variable_other_constant variable_other_constant_ruby"&gt;STATS_DIRECTORIES&lt;/span&gt; &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_augmented keyword_operator_assignment_augmented_ruby"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="string string_quoted string_quoted_other string_quoted_other_literal string_quoted_other_literal_lower string_quoted_other_literal_lower_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;%w(&lt;/span&gt;Library\ specs spec/lib&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;if&lt;/span&gt; &lt;span class="support support_class support_class_ruby"&gt;File&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;exist?&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;(&lt;/span&gt;&lt;span class="string string_quoted string_quoted_single string_quoted_single_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;'&lt;/span&gt;spec/lib&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="punctuation punctuation_separator punctuation_separator_other punctuation_separator_other_ruby"&gt;::&lt;/span&gt;&lt;span class="variable variable_other variable_other_constant variable_other_constant_ruby"&gt;STATS_DIRECTORIES&lt;/span&gt; &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_augmented keyword_operator_assignment_augmented_ruby"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="string string_quoted string_quoted_other string_quoted_other_literal string_quoted_other_literal_lower string_quoted_other_literal_lower_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;%w(&lt;/span&gt;Cucumber\ features features&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;if&lt;/span&gt; &lt;span class="support support_class support_class_ruby"&gt;File&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;exist?&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;(&lt;/span&gt;&lt;span class="string string_quoted string_quoted_single string_quoted_single_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;'&lt;/span&gt;features&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="punctuation punctuation_separator punctuation_separator_other punctuation_separator_other_ruby"&gt;::&lt;/span&gt;&lt;span class="support support_class support_class_ruby"&gt;CodeStatistics&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_other punctuation_separator_other_ruby"&gt;::&lt;/span&gt;&lt;span class="variable variable_other variable_other_constant variable_other_constant_ruby"&gt;TEST_TYPES&lt;/span&gt; &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_augmented keyword_operator_assignment_augmented_ruby"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="string string_quoted string_quoted_double string_quoted_double_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;"&lt;/span&gt;Model specs&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;"&lt;/span&gt;&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;if&lt;/span&gt; &lt;span class="support support_class support_class_ruby"&gt;File&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;exist?&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;(&lt;/span&gt;&lt;span class="string string_quoted string_quoted_single string_quoted_single_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;'&lt;/span&gt;spec/models&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="punctuation punctuation_separator punctuation_separator_other punctuation_separator_other_ruby"&gt;::&lt;/span&gt;&lt;span class="support support_class support_class_ruby"&gt;CodeStatistics&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_other punctuation_separator_other_ruby"&gt;::&lt;/span&gt;&lt;span class="variable variable_other variable_other_constant variable_other_constant_ruby"&gt;TEST_TYPES&lt;/span&gt; &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_augmented keyword_operator_assignment_augmented_ruby"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="string string_quoted string_quoted_double string_quoted_double_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;"&lt;/span&gt;View specs&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;"&lt;/span&gt;&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;if&lt;/span&gt; &lt;span class="support support_class support_class_ruby"&gt;File&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;exist?&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;(&lt;/span&gt;&lt;span class="string string_quoted string_quoted_single string_quoted_single_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;'&lt;/span&gt;spec/views&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="punctuation punctuation_separator punctuation_separator_other punctuation_separator_other_ruby"&gt;::&lt;/span&gt;&lt;span class="support support_class support_class_ruby"&gt;CodeStatistics&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_other punctuation_separator_other_ruby"&gt;::&lt;/span&gt;&lt;span class="variable variable_other variable_other_constant variable_other_constant_ruby"&gt;TEST_TYPES&lt;/span&gt; &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_augmented keyword_operator_assignment_augmented_ruby"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="string string_quoted string_quoted_double string_quoted_double_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;"&lt;/span&gt;Blackbox specs&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;"&lt;/span&gt;&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;if&lt;/span&gt; &lt;span class="support support_class support_class_ruby"&gt;File&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;exist?&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;(&lt;/span&gt;&lt;span class="string string_quoted string_quoted_single string_quoted_single_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;'&lt;/span&gt;spec/blackbox&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="punctuation punctuation_separator punctuation_separator_other punctuation_separator_other_ruby"&gt;::&lt;/span&gt;&lt;span class="support support_class support_class_ruby"&gt;CodeStatistics&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_other punctuation_separator_other_ruby"&gt;::&lt;/span&gt;&lt;span class="variable variable_other variable_other_constant variable_other_constant_ruby"&gt;TEST_TYPES&lt;/span&gt; &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_augmented keyword_operator_assignment_augmented_ruby"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="string string_quoted string_quoted_double string_quoted_double_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;"&lt;/span&gt;Selenium specs&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;"&lt;/span&gt;&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;if&lt;/span&gt; &lt;span class="support support_class support_class_ruby"&gt;File&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;exist?&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;(&lt;/span&gt;&lt;span class="string string_quoted string_quoted_single string_quoted_single_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;'&lt;/span&gt;spec/selenium&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="punctuation punctuation_separator punctuation_separator_other punctuation_separator_other_ruby"&gt;::&lt;/span&gt;&lt;span class="support support_class support_class_ruby"&gt;CodeStatistics&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_other punctuation_separator_other_ruby"&gt;::&lt;/span&gt;&lt;span class="variable variable_other variable_other_constant variable_other_constant_ruby"&gt;TEST_TYPES&lt;/span&gt; &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_augmented keyword_operator_assignment_augmented_ruby"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="string string_quoted string_quoted_double string_quoted_double_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;"&lt;/span&gt;Controller specs&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;"&lt;/span&gt;&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;if&lt;/span&gt; &lt;span class="support support_class support_class_ruby"&gt;File&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;exist?&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;(&lt;/span&gt;&lt;span class="string string_quoted string_quoted_single string_quoted_single_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;'&lt;/span&gt;spec/controllers&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="punctuation punctuation_separator punctuation_separator_other punctuation_separator_other_ruby"&gt;::&lt;/span&gt;&lt;span class="support support_class support_class_ruby"&gt;CodeStatistics&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_other punctuation_separator_other_ruby"&gt;::&lt;/span&gt;&lt;span class="variable variable_other variable_other_constant variable_other_constant_ruby"&gt;TEST_TYPES&lt;/span&gt; &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_augmented keyword_operator_assignment_augmented_ruby"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="string string_quoted string_quoted_double string_quoted_double_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;"&lt;/span&gt;Helper specs&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;"&lt;/span&gt;&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;if&lt;/span&gt; &lt;span class="support support_class support_class_ruby"&gt;File&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;exist?&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;(&lt;/span&gt;&lt;span class="string string_quoted string_quoted_single string_quoted_single_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;'&lt;/span&gt;spec/helpers&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="punctuation punctuation_separator punctuation_separator_other punctuation_separator_other_ruby"&gt;::&lt;/span&gt;&lt;span class="support support_class support_class_ruby"&gt;CodeStatistics&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_other punctuation_separator_other_ruby"&gt;::&lt;/span&gt;&lt;span class="variable variable_other variable_other_constant variable_other_constant_ruby"&gt;TEST_TYPES&lt;/span&gt; &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_augmented keyword_operator_assignment_augmented_ruby"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="string string_quoted string_quoted_double string_quoted_double_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;"&lt;/span&gt;Library specs&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;"&lt;/span&gt;&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;if&lt;/span&gt; &lt;span class="support support_class support_class_ruby"&gt;File&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;exist?&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;(&lt;/span&gt;&lt;span class="string string_quoted string_quoted_single string_quoted_single_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;'&lt;/span&gt;spec/lib&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="punctuation punctuation_separator punctuation_separator_other punctuation_separator_other_ruby"&gt;::&lt;/span&gt;&lt;span class="support support_class support_class_ruby"&gt;CodeStatistics&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_other punctuation_separator_other_ruby"&gt;::&lt;/span&gt;&lt;span class="variable variable_other variable_other_constant variable_other_constant_ruby"&gt;TEST_TYPES&lt;/span&gt; &lt;span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_augmented keyword_operator_assignment_augmented_ruby"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="string string_quoted string_quoted_double string_quoted_double_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;"&lt;/span&gt;Cucumber features&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;"&lt;/span&gt;&lt;/span&gt; &lt;span class="keyword keyword_control keyword_control_ruby"&gt;if&lt;/span&gt; &lt;span class="support support_class support_class_ruby"&gt;File&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;exist?&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;(&lt;/span&gt;&lt;span class="string string_quoted string_quoted_single string_quoted_single_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby"&gt;'&lt;/span&gt;features&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="punctuation punctuation_separator punctuation_separator_other punctuation_separator_other_ruby"&gt;::&lt;/span&gt;&lt;span class="support support_class support_class_ruby"&gt;STATS_DIRECTORIES&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby"&gt;.&lt;/span&gt;delete_if &lt;span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_ruby"&gt;{&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_variable punctuation_separator_variable_ruby"&gt;|&lt;/span&gt;&lt;span class="variable variable_other variable_other_block variable_other_block_ruby"&gt;a&lt;/span&gt;&lt;span class="punctuation punctuation_separator punctuation_separator_variable punctuation_separator_variable_ruby"&gt;|&lt;/span&gt; a&lt;span class="punctuation punctuation_section punctuation_section_array punctuation_section_array_ruby"&gt;[&lt;/span&gt;&lt;span class="constant constant_numeric constant_numeric_ruby"&gt;0&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_array punctuation_section_array_ruby"&gt;]&lt;/span&gt; &lt;span class="keyword keyword_operator keyword_operator_comparison keyword_operator_comparison_ruby"&gt;=~&lt;/span&gt; &lt;span class="string string_regexp string_regexp_classic string_regexp_classic_ruby"&gt;&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_ruby"&gt;/&lt;/span&gt;test&lt;span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_ruby"&gt;/&lt;/span&gt;&lt;/span&gt;&lt;span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_ruby"&gt;}&lt;/span&gt;&lt;br /&gt;  &lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword keyword_control keyword_control_ruby"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1069467794206617140-870449376142985742?l=biomime.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biomime.blogspot.com/feeds/870449376142985742/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1069467794206617140&amp;postID=870449376142985742' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/870449376142985742'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/870449376142985742'/><link rel='alternate' type='text/html' href='http://biomime.blogspot.com/2009/06/rake-stats-should-count-all-my-stuff.html' title='&quot;rake stats&quot; should count all my stuff!'/><author><name>Jeremy Rice</name><uri>http://www.blogger.com/profile/12256074521855601742</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-wV3OV11Fp0k/TxhzaIa4zSI/AAAAAAAAPXQ/GY4PplLad-I/s220/AllSpiritualLike.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1069467794206617140.post-4074310792202240388</id><published>2009-05-15T07:44:00.000-07:00</published><updated>2009-05-15T07:44:32.002-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rcov osx install'/><title type='text'>RCov Gem Installation problem</title><content type='html'>I couldn't get RCov installed this week:&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-size: x-small;"&gt;&lt;b&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$ sudo gem install rcov --trace&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ERROR:&amp;nbsp; While executing gem ... (OptionParser::InvalidOption)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; invalid option: --trace&lt;/span&gt;&lt;/b&gt;&lt;/span&gt; &lt;/blockquote&gt;Poking around a wee bit, I discovered that this was just rubyforge being obnoxious.&amp;nbsp; Go download the tarball form of the file and then just "&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;&lt;b&gt;sudo gem install [name of the tarball]&lt;/b&gt;&lt;/span&gt;".&amp;nbsp; All good.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1069467794206617140-4074310792202240388?l=biomime.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biomime.blogspot.com/feeds/4074310792202240388/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1069467794206617140&amp;postID=4074310792202240388' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/4074310792202240388'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/4074310792202240388'/><link rel='alternate' type='text/html' href='http://biomime.blogspot.com/2009/05/rcov-gem-installation-problem.html' title='RCov Gem Installation problem'/><author><name>Jeremy Rice</name><uri>http://www.blogger.com/profile/12256074521855601742</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-wV3OV11Fp0k/TxhzaIa4zSI/AAAAAAAAPXQ/GY4PplLad-I/s220/AllSpiritualLike.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1069467794206617140.post-3784253429262567765</id><published>2009-03-20T16:45:00.001-07:00</published><updated>2009-03-20T16:45:14.226-07:00</updated><title type='text'>Testing Your WebApp</title><content type='html'>&lt;div class="gmail_quote"&gt;I&amp;#39;ve been looking into the various ways to test web applications, including performance, acceptance tests, and cross-browser compatibility.  In my travels over the past week-and-a-half, I have decided there are three levels to this:&lt;br&gt; &lt;ol&gt;&lt;li&gt;Testing the design of your site.  Does it look similar enough in all supported browsers?&lt;/li&gt;&lt;li&gt;Testing the function of your site.  Does all the Javascript work?  Is everything that needs to render rendering?&lt;/li&gt; &lt;li&gt;Testing the reliability of your site.  How fast is it?  How many users can it handle?  For how long?&lt;br&gt;&lt;/li&gt;&lt;/ol&gt;&lt;font size="4"&gt;&lt;b&gt;Design Testing&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;A good first step is to validate with the W3C tools and try to stay 100% standards compliant. But you&amp;#39;re doing that already, I&amp;#39;m sure. : )&lt;br&gt; &lt;br&gt;Adobe has a neat &amp;quot;&lt;a href="http://ajaxian.com/archives/meer-meer" target="_blank"&gt;Meer Meer&lt;/a&gt;&amp;quot; application that&amp;#39;s coming... sometime. There is also &lt;a href="http://www.istartedsomething.com/20090318/expression-web-superpreview-cross-browser-testing/" target="_blank"&gt;SuperPreview&lt;/a&gt;.  Both of these allow cross-browser design using nothing more than whatever web-browser you have installed: they call the real browsers on the server-side, take snapshots, and serve you the images.  The coolest feature here is that you can overlay two browser&amp;#39;s snapshots and have the differences jump out at you.  ...Both of these are unreleased, but just around the corner.  Very cool.&lt;br&gt;  &lt;br&gt;If snapshots are enough, you can get these cheap: $50 a month for &lt;a href="http://litmusapp.com/pricing" target="_blank"&gt;Litmus&lt;/a&gt;.  You can hook these tests into your testing suite. CrossBrowserTesting has a &lt;a href="http://www.lgr.ca/blog/2008/04/cross-browser-testing.html" target="_blank"&gt;demo video here&lt;/a&gt;. Nothing earth-shattering: just note that you have to do these &amp;quot;tests&amp;quot; &lt;i&gt;by hand&lt;/i&gt;.&lt;br&gt;        &lt;br&gt;&lt;a href="http://www.ibm.com/developerworks/web/library/wa-crossbrowser/index.html" target="_blank"&gt;IBM says&lt;/a&gt;: &amp;quot;For instance, for a monthly fee, Browsercam.com gives you access to a broader range of platforms and browsers—including some mobile platforms—and these pages are dynamic, allowing you to test Ajax apps and other JavaScript-based pages. Some services, like Litmusapp, can integrate with your testing and development workflows, offering versioning support and ways to publish test results to external clients.&amp;quot;&lt;br&gt; &lt;br&gt;Interestingly, if you want to do these things by hand, there are free Microsoft &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=21EABB90-958F-4B64-B5F1-73D0A413C8EF&amp;amp;displaylang=en" target="_blank"&gt;images&lt;/a&gt; of common Windows versions/Browser combos for use by developers.  The bummer is that you have to renew them every so often (and only supported OS/browsers are represented), but it&amp;#39;s a great way to test your app without spending too much money on setup.&lt;br&gt;         &lt;br&gt;A decent rundown of the &amp;quot;images of site&amp;quot; tools is &lt;a href="http://www.masternewmedia.org/browser-compatibility-testing-cross-platform-cross-browser-multiple-resolutions-compatibility-testing-tools/" target="_blank"&gt;here&lt;/a&gt;; (there were other overviews, not as good) we should see what the JavaScript-capable options are really capable of. If you need older versions, you&amp;#39;ll have to install those yourself, but &lt;a href="http://finalbuilds.edskes.net/iecollection.htm" target="_blank"&gt;old IE versions&lt;/a&gt; are still available on the web (not from Microsoft, however).&lt;br&gt;   &lt;br&gt;&lt;font size="4"&gt;&lt;b&gt;Functional (Acceptance) Testing&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;For acceptance testing your Javascript, there are a few choices in the world of headless (ie: much faster) browsers.  &lt;a href="http://htmlunit.sourceforge.net/javascript-howto.html" target="_blank"&gt;HtmlUnit&lt;/a&gt; seems a usable Java &amp;quot;mock&amp;quot; browser. There&amp;#39;s a JRuby wrapper for it called &lt;a href="http://celerity.rubyforge.org/" target="_blank"&gt;Celerity&lt;/a&gt;, which could get &lt;i&gt;me&lt;/i&gt; started faster. Similar is &lt;a href="http://thinkpond.org/articles/2008/jstest-intro.shtml" target="_blank"&gt;jsTest&lt;/a&gt;, also in Java. &lt;a href="http://code.google.com/p/jiffy-web/" target="_blank"&gt;Jiffy&lt;/a&gt; struck me as overly complex, and hard-wired to Oracle for measures. &lt;a href="http://www.joedog.org/index/siege-manual" target="_blank"&gt;Joe Dog Siege&lt;/a&gt; looks like a usable, mostly command-line driven load tester.&lt;br&gt;    &lt;br&gt;An interesting but probably less-useful alternative is to just check the JS for problems using &lt;a href="http://thefrontside.net/crosscheck" target="_blank"&gt;crosscheck&lt;/a&gt;, but as of now it doesn&amp;#39;t seem to have usable documentation, so...&lt;br&gt;        &lt;br&gt;If you don&amp;#39;t mind (or have a need to be) using real browsers, &lt;a href="http://seleniumhq.org/" target="_blank"&gt;Selenium&lt;/a&gt; is the standard right now for writing acceptance tests, and it&amp;#39;s &lt;a href="http://seleniumhq.org/movies/intro.mov" target="_blank"&gt;really easy&lt;/a&gt; to set up.  Whether it adds overhead is an interesting question; I would assume yes based on some comments from other tool&amp;#39;s sites. That said, A) You don&amp;#39;t want to mix your acceptance tests with your performance tests, and B) it seems to be a standard right now, and I do recommend using it because of that.  There are some alternatives, though.  For example, &lt;a href="http://jsunit.net/" target="_blank"&gt;JsUnit&lt;/a&gt; is a way to do the tests in native JavaScript, which is quite possibly useful.&lt;br&gt;  &lt;br&gt;&lt;font size="4"&gt;&lt;b&gt;Performance Testing&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;&amp;quot;Performance testing&amp;quot; (actually lots of sub-categories; read on) is a rather large arena, and I found this stuff quite interesting.  ; )  I found the best introduction to the topic to be this &lt;a href="http://video.google.com/videoplay?docid=-6891978643577501895" target="_blank"&gt;neat video&lt;/a&gt; from Google, which gives some definitions:&lt;br&gt;  &lt;ul&gt;&lt;li&gt;&lt;b&gt;performance testing&lt;/b&gt; - how fast will it respond under load X? You need to test things at least long enough to reach a steady state. Start up slowly: don&amp;#39;t just throw 100 users at it, build it up over a warm-up period. The machines under load periodically push performance dat (see blow) to monitoring servers, which analyze and store the data.  These monitoring servers are also monitoring themselves (so you know what the effect of storing the data is). To the extent possible, remove the network: run everything in its own little environment.&lt;br&gt;    &lt;/li&gt;&lt;li&gt;&lt;b&gt;stress testing - &lt;/b&gt;at what point does the system break under load (and does it do so gracefully)?&lt;/li&gt;&lt;li&gt;&lt;b&gt;load (or liability) testing - &lt;/b&gt;given a high load (80% of max) for an extended period of time (Google does 1 month, 72 hours is a minimum recommendation), how does it perform?  Often there are cron-related or system-level tasks (ex: log rotation) that affect performance only at certain times, so this needs to be examined. &lt;br&gt;    &lt;/li&gt;&lt;li&gt;&lt;b&gt;benchmark - &lt;/b&gt;a simplified measurement that is repeatable, representing a typical customer&amp;#39;s activity on the system.&lt;/li&gt;&lt;li&gt;&lt;b&gt;profiling - &lt;/b&gt;When you change some aspect of the system (memory, load balancer, etc) and measure the differences in benchmark performance.&lt;/li&gt;  &lt;li&gt;&lt;b&gt;availability testing - &lt;/b&gt;when a system fails, how long does it take to come back up? Google operates under the assumption that their equipment sucks, so they will solve that problem in software.&lt;/li&gt;&lt;/ul&gt;Her reasons for testing are 1) to make honest claims to the client backed by data, 2) test hardware changes, and 3) developers can see the effect of their code over time.  NOT for functional testing.&lt;br&gt;    &lt;br&gt;Some other tips included: run every test at least 5 times before you measure it: inconsistency must be accounted for.  She recommends a single five-minute test run &amp;quot;on demand&amp;quot;, when a developer requests it, because you get *some* information from it, but nightlies are still required.&lt;br&gt;    &lt;br&gt;She recommends &lt;a href="http://jakarta.apache.org/jmeter/" target="_blank"&gt;JMeter&lt;/a&gt; to measure loads (but it doesn&amp;#39;t handle JavaScript) (There is a &lt;a href="http://209.85.173.132/search?q=cache:P42H6mWGyrMJ:jakarta.apache.org/jmeter/usermanual/jmeter_distributed_testing_step_by_step.pdf+testing&amp;amp;cd=2&amp;amp;hl=en&amp;amp;ct=clnk&amp;amp;gl=us" target="_blank"&gt;demo&lt;/a&gt; of how to get started, too), or &lt;a href="http://grinder.sourceforge.net/" target="_blank"&gt;Grinder&lt;/a&gt; (for &amp;quot;APIs&amp;quot;).&lt;br&gt;  &lt;br&gt;Note that you should track not only the QPS, response times, etc, but also the CPU load, memory, versions of every piece of software on the machine, and disk i/o.&lt;br&gt;&lt;br&gt;Interestingly, she says that Linux is typically performant as long as you don&amp;#39;t exceed any single resource&amp;#39;s 80% mark.   &lt;br&gt;  &lt;br&gt;You can buy load testing.  &lt;a href="http://loadstorm.com/load-testing-cost" target="_blank"&gt;Prices on LoadStorm&lt;/a&gt;, for example, range from $30 to $200 a month. &lt;a href="http://en.wikipedia.org/wiki/LoadRunner" target="_blank"&gt;LoadRunner&lt;/a&gt; is another alternative (software that you use), by HP, which appears to be rather expensive... (Well, when they don&amp;#39;t &lt;i&gt;list&lt;/i&gt; a price, one must assume...)&lt;br&gt;   &lt;br&gt;BrowserStorm looks reasonable for a paid service, and has an explanation of its features in a &lt;a href="http://ajaxian.com/archives/why-load-testing-ajax-is-hard" target="_blank"&gt;blatant plug on&lt;/a&gt; Ajaxian.&lt;br&gt; &lt;br&gt;&lt;/div&gt;Hope this helps.&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1069467794206617140-3784253429262567765?l=biomime.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biomime.blogspot.com/feeds/3784253429262567765/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1069467794206617140&amp;postID=3784253429262567765' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/3784253429262567765'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/3784253429262567765'/><link rel='alternate' type='text/html' href='http://biomime.blogspot.com/2009/03/testing-your-webapp.html' title='Testing Your WebApp'/><author><name>Jeremy Rice</name><uri>http://www.blogger.com/profile/12256074521855601742</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-wV3OV11Fp0k/TxhzaIa4zSI/AAAAAAAAPXQ/GY4PplLad-I/s220/AllSpiritualLike.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1069467794206617140.post-6356851358957739796</id><published>2009-03-02T07:53:00.001-08:00</published><updated>2009-03-02T07:53:44.049-08:00</updated><title type='text'>AIM Chatroom Death</title><content type='html'>...So we EOL developers hang out in an AOL chatroom.  Last week, I got logged out of it, and couldn&amp;#39;t get back in.  ...Not sure why.  I hoped the problem would just go away, but it never resolved itself.  The error I was getting was:&lt;br&gt; &lt;br&gt;&lt;div style="margin-left: 40px;"&gt;Couldn't join chatroom "".&lt;br&gt;&lt;br&gt;An AIM service error occurred.&lt;br&gt;&lt;br&gt;Error: Serv:RequestTimeout&lt;br&gt;&lt;div style="margin-left: 40px;"&gt;ChatError:NoError&lt;br&gt;&lt;/div&gt;&lt;/div&gt;&lt;br&gt;Useless message!  But eventually I found &lt;a href="http://discussions.apple.com/thread.jspa?threadID=1208110"&gt;a page&lt;/a&gt; describing the problem, with the suggestion to change the AIM server port from 5190 to 443.&lt;br&gt; &lt;br&gt;That worked.&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1069467794206617140-6356851358957739796?l=biomime.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biomime.blogspot.com/feeds/6356851358957739796/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1069467794206617140&amp;postID=6356851358957739796' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/6356851358957739796'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/6356851358957739796'/><link rel='alternate' type='text/html' href='http://biomime.blogspot.com/2009/03/aim-chatroom-death.html' title='AIM Chatroom Death'/><author><name>Jeremy Rice</name><uri>http://www.blogger.com/profile/12256074521855601742</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-wV3OV11Fp0k/TxhzaIa4zSI/AAAAAAAAPXQ/GY4PplLad-I/s220/AllSpiritualLike.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1069467794206617140.post-6326254097909725878</id><published>2009-02-27T07:01:00.001-08:00</published><updated>2009-02-27T07:01:44.496-08:00</updated><title type='text'>Fixing "svn: Checksum mismatch"</title><content type='html'>While trying to check in some changes I made, I ran into a problem that gave me the following error:&lt;br&gt;&lt;br&gt;&lt;div style="margin-left: 40px;"&gt;&lt;b&gt;&lt;font face="courier new,monospace"&gt;&lt;font size="1"&gt;Transmitting file data .svn: Commit failed (details follow):&lt;br&gt; svn: Checksum mismatch for &amp;#39;/Users/jrice/workspace/eol-dev/spec/models/.svn/text-base/taxon_concept_spec.rb.svn-base&amp;#39;; expected: &amp;#39;e4bd7ddf1f3c78447253dbdcd4ab96f6&amp;#39;, actual: &amp;#39;edbe4f2e08778a7d4f33212a812450ec&amp;#39;&lt;/font&gt;&lt;br&gt; &lt;br&gt;&lt;/font&gt;&lt;/b&gt;&lt;/div&gt;...At first, I really freaked out, wondering if I had some kind of virus tacking on additional information to my files or something like that. But, of course, that was just panic. In truth, this is just a bad MD5 checksum in the svn database, and only for one file.  It&amp;#39;s kind of a pain to fix, but it&amp;#39;s simple enough.&lt;br&gt; &lt;br&gt;I found a very nice walkthrough to fix it on &lt;a href="http://glob.bushi.net.nz/glob/2007/02/14/subversion-checksum-mismatch-easy-workaround/"&gt;Chris&amp;#39;s Glob blog&lt;/a&gt;. For posterity, I will re-cap it here.  Start by committing everything you can (basically, everything but the one file that is having trouble).  Here&amp;#39;s the rest of what I did, based on Chris&amp;#39;s walkthrough:&lt;br&gt; &lt;br&gt;&lt;div style="margin-left: 40px;"&gt;&lt;font face="courier new,monospace" size="1"&gt;&lt;b&gt;[models]&lt;br&gt;$ cd /tmp&lt;br&gt;[tmp]&lt;br&gt;$ svn co &lt;a href="https://repository.eol.org/eol/trunk/spec/models"&gt;https://repository.eol.org/eol/trunk/spec/models&lt;/a&gt;&lt;br&gt; A    models/toc_item_spec.rb&lt;br&gt;A    models/taxon_concept_spec.rb&lt;br&gt;A    models/transactions_spec.rb&lt;br&gt;A    models/normalized_names_and_links_spec.rb&lt;br&gt;A    models/data_object_tag_spec.rb&lt;br&gt;A    models/hierarchy_spec.rb&lt;br&gt; A    models/user_spec.rb&lt;br&gt;A    models/factories_spec.rb&lt;br&gt;A    models/hierarchy_entry_spec.rb&lt;br&gt;A    models/name_spec.rb&lt;br&gt;Checked out revision 295.&lt;br&gt;[tmp]&lt;br&gt;$ cd -&lt;br&gt;/Users/jrice/workspace/eol-dev/spec/models&lt;br&gt; [models]&lt;br&gt;$ cd ..&lt;br&gt;[spec]&lt;br&gt;$ mv models /tmp/models.orig&lt;br&gt;[spec]&lt;br&gt;$ mv /tmp/models .&lt;br&gt;[spec]&lt;br&gt;$ svn up&lt;br&gt;At revision 295.&lt;br&gt;[spec]&lt;br&gt;$ cp /tmp/models.orig/taxon_concept_spec.rb models&lt;br&gt;[spec]&lt;br&gt;$ svn st&lt;br&gt; M      models/taxon_concept_spec.rb&lt;br&gt;[spec]&lt;br&gt;$ svn commit -m &amp;quot;Adding specs to taxon_concept in prep. for xml API&amp;quot;&lt;br&gt;Sending        spec/models/taxon_concept_spec.rb&lt;br&gt;Transmitting file data .&lt;br&gt;Committed revision 296.&lt;/b&gt;&lt;/font&gt;&lt;br&gt; &lt;br&gt;&lt;/div&gt;That&amp;#39;s it: as you can see, the file went up just fine after that.&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1069467794206617140-6326254097909725878?l=biomime.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biomime.blogspot.com/feeds/6326254097909725878/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1069467794206617140&amp;postID=6326254097909725878' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/6326254097909725878'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/6326254097909725878'/><link rel='alternate' type='text/html' href='http://biomime.blogspot.com/2009/02/fixing-svn-checksum-mismatch.html' title='Fixing &quot;svn: Checksum mismatch&quot;'/><author><name>Jeremy Rice</name><uri>http://www.blogger.com/profile/12256074521855601742</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-wV3OV11Fp0k/TxhzaIa4zSI/AAAAAAAAPXQ/GY4PplLad-I/s220/AllSpiritualLike.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1069467794206617140.post-285965809501232381</id><published>2009-01-23T13:54:00.001-08:00</published><updated>2009-01-23T13:54:23.773-08:00</updated><title type='text'>Testing [warning: LONG post]</title><content type='html'>So, today, &lt;a href="http://remi.org/" target="_blank"&gt;Remi&lt;/a&gt; (of &lt;a href="http://openrain.com/" target="_blank"&gt;OpenRain&lt;/a&gt;) and I made a presentation to the other developers about what we thought would be the best M.O. would could pick for testing &lt;a href="http://www.eol.org" target="_blank"&gt;our application&lt;/a&gt;. Without going into the &amp;quot;whys&amp;quot; behind this testing sea-change, I thought I would recap what I&amp;#39;ve learned, with Remi&amp;#39;s help.&lt;br&gt; &lt;br&gt;First, we&amp;#39;ve re-defined &lt;i&gt;what to test&lt;/i&gt;. When our testing suite was at its low point, the answer to that question was &amp;quot;everything&amp;quot;.&amp;nbsp; ...And that&amp;#39;s what made the tests so brittle: if anyone made any change at all, the tests let them know about it. So, coming up with a clear definition of what gets tested was important to me.&amp;nbsp; The answer I chose was twofold:&lt;br&gt; &lt;ol&gt;&lt;li&gt;&lt;b&gt;Those parts of the code (namely, APIs) that really should never change, and&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;The functionality that we really need to &lt;i&gt;prove&lt;/i&gt; works.&lt;/b&gt;&lt;/li&gt;&lt;/ol&gt;The latter point is made particularly clear by the &lt;a href="http://merbcamp.com/video/katz1.mp4"&gt;argument for black-box testing&lt;/a&gt;. The most poignant case he makes in that video is to make the assertion that &amp;quot;this really doesn&amp;#39;t prove anything&amp;quot;, and that was &lt;i&gt;very &lt;/i&gt;important to me.&lt;br&gt; &lt;br&gt;So, with those two core definitions, we decided to take two core approaches:&lt;br&gt;&lt;ol&gt;&lt;li&gt;&lt;b&gt;Unit testing&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;Full-stack (or nearly-so) functional testing&lt;/b&gt;&lt;/li&gt;&lt;/ol&gt;...That is to say, &lt;b&gt;no view tests&lt;/b&gt;: they depend too much on everything else to render properly and are too difficult to test in ways that aren&amp;#39;t going to break when you decide to, say, rename a div. Secondly: &lt;b&gt;no controller tests.&lt;/b&gt; As Remi put it, controller tests are &lt;i&gt;huge&lt;/i&gt; tests, and they prove &lt;i&gt;almost nothing.&lt;/i&gt; They are not worth their weight.&lt;br&gt; &lt;br&gt;I looked into a myriad of tools for writing tests, including shoulda, context, matchy, zebra, and a review of RSpec.&amp;nbsp; In a nutshell:&lt;br&gt;&lt;br&gt;&lt;b&gt;Shoulda&lt;/b&gt; is really cool.&amp;nbsp; The assertion that one line of Rails code should require one line of testing code is... superb. I&amp;#39;d like to work under that assumption, and write our own custom assertions to facilitate this. But shoulda also relies heavily on an application being very much in line with the Rails Way, and our app, because of its highly complex, stand-alone database is not particularly so. I feel much of the power of shoulda would be lost on us.&amp;nbsp; So, rather than learn this system, we should just pass it by.&amp;nbsp; Fortunately, RSpec has &lt;a href="http://blog.davidchelimsky.net/2009/1/13/rspec-1-1-12-is-released"&gt;made some changes&lt;/a&gt; to their system that make shoulda-macro-like custom assertions and &amp;quot;one-liners&amp;quot; much easier. &lt;br&gt; &lt;br&gt;&lt;b&gt;Context &lt;/b&gt;and&lt;b&gt; matchy&lt;/b&gt; are also neat, in that they give you much of what RSpec and shoulda give you, with much less baggage. I like that concept! But when I actually installed the code and tried it out, a lot of the things that &amp;quot;just work&amp;quot; in RSpec just... didn&amp;#39;t.&amp;nbsp; Rather than wrestle with it for more than a day, I decided these tools are... well... &lt;i&gt;too&lt;/i&gt; light for our purposes.&lt;br&gt; &lt;br&gt;&lt;b&gt;Zebra&lt;/b&gt; impressed me the most.&amp;nbsp; I think we&amp;#39;ll &lt;i&gt;all&lt;/i&gt; be writing tests in this style (example: &lt;font face="courier new,monospace"&gt;&lt;b&gt;&lt;font size="1"&gt;expect { @&lt;a href="http://my_model.to"&gt;my_model.to&lt;/a&gt; be_invalid() }&lt;/font&gt;&lt;/b&gt;&lt;/font&gt;) in the near future. ...But at the moment, one needs to define too many of those assertions one&amp;#39;s self, and thus I don&amp;#39;t think is is really mature enough for us to start using without serious investment in time.&amp;nbsp; ...which we just don&amp;#39;t have.&lt;br&gt; &lt;br&gt;In the end, I decided it was wisest to &lt;b&gt;stick with Rpec&lt;/b&gt;.&amp;nbsp; It&amp;#39;s got everything one needs to write excellent unit tests... and then some.&amp;nbsp; So, yes, it comes with some overhead and baggage, but on the other hand: the things you need to &amp;quot;just work&amp;quot;... do.&lt;br&gt; &lt;br&gt;That said, the &lt;i&gt;style&lt;/i&gt; of testing we&amp;#39;ll be doing needs to change. As I said earlier, we should focus on testing only those parts of the code that really shouldn&amp;#39;t change.&amp;nbsp; For example, we expect a taxon_concept to have a common name, which comes from a particular part of the database and defaults to the scientific name when that entry isn&amp;#39;t found.&amp;nbsp; These are things we can test, and we can do it without stubbing the tar out of every method that ever gets called to create the end result.&lt;br&gt; &lt;br&gt;Consequently, we will be hitting the database to run tests.&amp;nbsp; And this makes me a little sad, because I know how slow testing can be when it&amp;#39;s dependant on the DB.&lt;br&gt;&lt;br&gt;To alleviate some of this, we are going to try and &lt;b&gt;stop using fixtures in favor of &lt;a href="http://github.com/thoughtbot/factory_girl/tree/master"&gt;factory_girl&lt;/a&gt;&lt;/b&gt;.&amp;nbsp; This has several advantages:&lt;br&gt; &lt;ol&gt;&lt;li&gt;&lt;b&gt;Fewer models than with fixtures.&lt;/b&gt; If you need to test a &amp;quot;special&amp;quot; model, you instantiate one with the special feature.&amp;nbsp; It&amp;#39;s not there in every other test that &lt;i&gt;doesn&amp;#39;t&lt;/i&gt; need it. Hopefully, this will cut down on the time it takes to prepare for any given test.&lt;br&gt; &lt;/li&gt;&lt;li&gt;&lt;b&gt;Easier to define (DRYer) than fixtures. &lt;/b&gt;There&amp;#39;s (nominally) one &lt;b style="font-family: courier new,monospace;"&gt;&lt;font size="1"&gt;factories.rb&lt;/font&gt;&lt;/b&gt; file sitting somewhere, with all of your models defined in a rather succinct syntax.&amp;nbsp; Compare this to the 50+ YML files sitting in a directory.&amp;nbsp; If you tweak the relationship between two models, you&amp;#39;re not doing a search-and-replace on several YML files, you&amp;#39;re changing one definition in one place.&lt;/li&gt; &lt;li&gt;&lt;b&gt;More robust than mocks.&lt;/b&gt; The problem with mocks is that you need to stub each function that gets called on them, and this can be quite expensive (in developer&amp;#39;s time) and non-dry, if not done carefully.&lt;/li&gt; &lt;li&gt;&lt;b&gt;More coverage of class behaviours.&lt;/b&gt; So, when you call that name() method which bounces all over creation to find your common name, you&amp;#39;re flexing the muscles of all the pieces involved to make sure they work.&amp;nbsp; Of course, this &amp;quot;feature&amp;quot; comes at the price of less isolation of code. ...and isolated tests is one of the hallmarks of RSpec.&amp;nbsp; But I think it suits our project better to take the coverage. Plus, our project makes &lt;i&gt;heavy&lt;/i&gt; use of find_by_sql, which may otherwise go untested.&lt;/li&gt; &lt;li&gt;&lt;b&gt;Easier to instantiate than mocks.&lt;/b&gt; Our &amp;quot;top-level&amp;quot; model, a taxon_concept, relies on around 20 other models to actually &lt;i&gt;work.&lt;/i&gt; With RSpec mocking, I had to create each of those mocks and tie them together.&amp;nbsp; The resulting code was very, very ugly.&amp;nbsp; Yes, I probably could have cleaned it up, but I don&amp;#39;t think I could have gotten it &lt;i&gt;nearly&lt;/i&gt; as succinct as factory_girl&amp;#39;s syntax.&lt;/li&gt; &lt;/ol&gt;Factory_girl is a rockin&amp;#39; module.&amp;nbsp; I think everyone should be familiar with it.&amp;nbsp; (And, yes, I am aware that there are a number of viable alternatives with the same underlying behaviour.&amp;nbsp; But f_g seems most popular and least cluttered.)&lt;br&gt; &lt;br&gt;...So we still have the problem of &lt;i&gt;proving&lt;/i&gt; that the website &lt;i&gt;works&lt;/i&gt;.&amp;nbsp; This was a problem with RSpec.&amp;nbsp; Because of its fantastic isolation of testing, one was never &lt;i&gt;really&lt;/i&gt; sure if the whole stack was going to behave properly. I spent the &lt;i&gt;vast&lt;/i&gt; majority of my time in the past 1 1/2 weeks trying to solve this problem of &lt;i&gt;proof&lt;/i&gt; that the damn site actually does what you want.&amp;nbsp; There are plenty of solutions out there, but personally, I found most of them clunky. ...at best.&lt;br&gt; &lt;br&gt;Enter &lt;a href="http://gitrdoc.com/brynary/webrat/tree/master/"&gt;&lt;b&gt;webrat&lt;/b&gt;&lt;/a&gt;.&amp;nbsp; This is a package that makes visiting a site as simple as... well... visit(url).&amp;nbsp; And you can click around, fill in forms, and all of those similar things with other, very simple syntax.&amp;nbsp; Example from the current homepage:&lt;br&gt; &lt;br&gt;&lt;pre&gt;  class SignupTest &amp;lt; ActionController::IntegrationTest&lt;br&gt;&lt;br&gt;    def test_trial_account_sign_up&lt;br&gt;      visit home_path&lt;br&gt;      click_link &amp;quot;Sign up&amp;quot;&lt;br&gt;      fill_in &amp;quot;Email&amp;quot;, :with =&amp;gt; &amp;quot;&lt;a href="mailto:good@example.com"&gt;good@example.com&lt;/a&gt;&amp;quot;&lt;br&gt;       select &amp;quot;Free account&amp;quot;&lt;br&gt;      click_button &amp;quot;Register&amp;quot;&lt;br&gt;    end&lt;br&gt;&lt;br&gt;  end&lt;/pre&gt;...Isn&amp;#39;t that &lt;i&gt;slick?&lt;/i&gt; ...This makes writing good functional tests a piece of cake. And, while we could easily run these kinds of tests with RSpec, I decided that, because we operate on a user-story-centered style of implementing features, I thought we could also adopt &lt;b&gt;cucumber&lt;i&gt;, &lt;/i&gt;&lt;/b&gt;which is another really slick wrapper around user stories.&amp;nbsp; Basically, you write tests in plain english, using Given / When / Then blocks, and write some ruby code to match your plain-english assertions and turn them into webrat (or some other) full-stack tests.&lt;br&gt; &lt;br&gt;I expect some resistance to cucumber. It feels a little... hokey to write tests in plain english, then parse them in ruby... but in practice, I have found the technique to be very readable, very usable, and surprisingly minimal (in terms of the amount of code).&amp;nbsp; Assuming there is sufficient buy-in for this, I actually believe it will turn out to be a really cool, really reliable way to, as I said, &lt;b&gt;prove that the site works.&lt;/b&gt;&lt;br&gt; &lt;br&gt;Of course, all of this is academic as of this afternoon.&amp;nbsp; We&amp;#39;ll see how things pan out in the next week or two.&amp;nbsp; Some of these ideas may not be well-conceived, or may turn out to be ill-applied to our particular codebase. I&amp;#39;ll keep open-minded about it. But I&amp;#39;m also really excited to at least &lt;i&gt;try&lt;/i&gt; and get all of this to fit together nicely.&lt;br&gt; &lt;br&gt;I actually rather enjoy writing tests, and I think these changes will make tests more fun, more useful, and more productive.&amp;nbsp; We&amp;#39;ll see.&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1069467794206617140-285965809501232381?l=biomime.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biomime.blogspot.com/feeds/285965809501232381/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1069467794206617140&amp;postID=285965809501232381' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/285965809501232381'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/285965809501232381'/><link rel='alternate' type='text/html' href='http://biomime.blogspot.com/2009/01/testing-warning-long-post.html' title='Testing [warning: LONG post]'/><author><name>Jeremy Rice</name><uri>http://www.blogger.com/profile/12256074521855601742</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-wV3OV11Fp0k/TxhzaIa4zSI/AAAAAAAAPXQ/GY4PplLad-I/s220/AllSpiritualLike.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1069467794206617140.post-8025536203818246707</id><published>2009-01-23T07:36:00.001-08:00</published><updated>2009-01-23T07:36:21.953-08:00</updated><title type='text'>"Errors running test:units!"</title><content type='html'>Sounds nasty, doesn&amp;#39;t it?&lt;br&gt;&lt;br&gt;Worse, there&amp;#39;s little clue, even with --trace on, as to why it failed.&lt;br&gt;&lt;br&gt;In my case, however, I poked around a bit and noticed that my &amp;quot;&lt;font size="1"&gt;&lt;b style="font-family: courier new,monospace;"&gt;test/test_helper.rb&lt;/b&gt;&lt;/font&gt;&amp;quot; file was missing. (Long story as to why.)&amp;nbsp; Restoring it fixed the &amp;quot;&lt;b&gt;&lt;font style="font-family: courier new,monospace;" size="1"&gt;Errors running test:units!&lt;/font&gt;&lt;/b&gt;&amp;quot; problem.&lt;br&gt; &lt;br&gt;Hope that helps someone else out there (&amp;#39;cause I couldn&amp;#39;t find a good explanation online)...&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1069467794206617140-8025536203818246707?l=biomime.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biomime.blogspot.com/feeds/8025536203818246707/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1069467794206617140&amp;postID=8025536203818246707' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/8025536203818246707'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/8025536203818246707'/><link rel='alternate' type='text/html' href='http://biomime.blogspot.com/2009/01/errors-running-testunits.html' title='&quot;Errors running test:units!&quot;'/><author><name>Jeremy Rice</name><uri>http://www.blogger.com/profile/12256074521855601742</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-wV3OV11Fp0k/TxhzaIa4zSI/AAAAAAAAPXQ/GY4PplLad-I/s220/AllSpiritualLike.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1069467794206617140.post-3695355340846569510</id><published>2009-01-22T10:43:00.001-08:00</published><updated>2009-01-22T10:43:17.295-08:00</updated><title type='text'>config.gem 'rspec'</title><content type='html'>I finally got rspec to install using config.gem (in Rails) with these lines:&lt;br&gt;&lt;br&gt;&lt;b&gt;&lt;font style="font-family: courier new,monospace;" size="1"&gt;&amp;nbsp; config.gem &amp;#39;rspec&amp;#39;,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; :lib =&amp;gt; &amp;#39;spec&amp;#39;&lt;br&gt;&amp;nbsp; config.gem &amp;#39;rspec-rails&amp;#39;, :lib =&amp;gt; false # Note this hack keeps it from failing on this gem.&lt;/font&gt;&lt;/b&gt;&lt;br&gt; &lt;br&gt;...That allowed me to install/unpack them.&amp;nbsp; Which is all well and good.&amp;nbsp; But when I &lt;i&gt;ran&lt;/i&gt; my specs, it failed, complaining about an &lt;span class="entry-content"&gt;&amp;quot;&lt;b&gt;&lt;font style="font-family: courier new,monospace;" size="1"&gt;undefined method `evaluate_value_proc&amp;#39; for class `Spec::Matchers::Change&amp;#39;&lt;/font&gt;&lt;/b&gt;&amp;quot;. Looking around, the claim was that this error was caused by &amp;quot;incompatible versions of rspec and rspec-rails&amp;quot;. But that didn&amp;#39;t jive with the versions I had installed.&lt;br&gt; &lt;br&gt;So I commented out my two lines, above.&amp;nbsp; ...At least I had them in vendor/gems, (and my &amp;quot;script/generate rspec&amp;quot; bootstrap command ran fine, earlier).&lt;br&gt;&lt;br&gt;With the gems commented out, everything worked.&lt;br&gt; &lt;br&gt;[shrug]&amp;nbsp; Go figure.&lt;br&gt;&lt;/span&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1069467794206617140-3695355340846569510?l=biomime.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biomime.blogspot.com/feeds/3695355340846569510/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1069467794206617140&amp;postID=3695355340846569510' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/3695355340846569510'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/3695355340846569510'/><link rel='alternate' type='text/html' href='http://biomime.blogspot.com/2009/01/configgem-rspec.html' title='config.gem &apos;rspec&apos;'/><author><name>Jeremy Rice</name><uri>http://www.blogger.com/profile/12256074521855601742</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-wV3OV11Fp0k/TxhzaIa4zSI/AAAAAAAAPXQ/GY4PplLad-I/s220/AllSpiritualLike.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1069467794206617140.post-7885770420674082332</id><published>2008-12-16T08:11:00.001-08:00</published><updated>2008-12-16T08:11:31.087-08:00</updated><title type='text'>Updating to RubyGems 1.3.1 on OS X</title><content type='html'>As much as I enjoy ruby and rails, I don&amp;#39;t keep up with the community much.&lt;br&gt;&lt;br&gt;This has its price... sometimes I&amp;#39;m blindsided by things that I imagine are &amp;quot;common knowledge&amp;quot; on the mailing-lists, but aren&amp;#39;t documented anywhere that we lesser mortals actually notice.&lt;br&gt; &lt;br&gt;The problem I had this morning was mentioned, in &lt;a href="http://rails.wincent.com/wiki/Updating_to_RubyGems_1.3.0_on_Mac_OS_X_Leopard_10.5.4"&gt;obfuscated form&lt;/a&gt;, on one blog, at least.&amp;nbsp; I thought I would state it more explicitly:&lt;br&gt; &lt;br&gt;&lt;b&gt;I updated to Rails 2.2.2, but it complained that I needed to update to RubyGems 1.3.1.&amp;nbsp; When I tried (&lt;span style="font-family: courier new,monospace;"&gt;sudo gem update --system&lt;/span&gt;), I got this message:&lt;br&gt;&lt;br&gt;&lt;/b&gt;&lt;div style="margin-left: 40px;"&gt; &lt;b&gt;&lt;font style="font-family: courier new,monospace;" size="4"&gt;Updating RubyGems&lt;br&gt;Nothing to update&lt;/font&gt;&lt;br&gt;&lt;br&gt;&lt;/b&gt;&lt;/div&gt;&lt;b&gt;...It turns out you need to use the &amp;quot;alternate install&amp;quot; for RubyGems.&amp;nbsp; ...despite the fact that the documentation says &lt;i&gt;explicitly&lt;/i&gt; that you won&amp;#39;t need to if you have a more recent version.&amp;nbsp; Do this:&lt;br&gt; &lt;font size="4"&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;/font&gt;&lt;/b&gt;&lt;div style="margin-left: 40px;"&gt;&lt;font size="4"&gt;&lt;b style="font-family: courier new,monospace;"&gt;&amp;gt; sudo gem install rubygems-update&lt;/b&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;b style="font-family: courier new,monospace;"&gt;&amp;gt; sudo update_rubygems&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;&lt;/div&gt;...Now you&amp;#39;re running 1.3.1, and Rails will be supplicated.&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1069467794206617140-7885770420674082332?l=biomime.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biomime.blogspot.com/feeds/7885770420674082332/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1069467794206617140&amp;postID=7885770420674082332' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/7885770420674082332'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/7885770420674082332'/><link rel='alternate' type='text/html' href='http://biomime.blogspot.com/2008/12/updating-to-rubygems-131-on-os-x.html' title='Updating to RubyGems 1.3.1 on OS X'/><author><name>Jeremy Rice</name><uri>http://www.blogger.com/profile/12256074521855601742</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-wV3OV11Fp0k/TxhzaIa4zSI/AAAAAAAAPXQ/GY4PplLad-I/s220/AllSpiritualLike.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1069467794206617140.post-520100476271581021</id><published>2008-10-22T09:26:00.001-07:00</published><updated>2008-10-22T09:26:05.697-07:00</updated><title type='text'>Bugs Me:</title><content type='html'>&lt;div style="margin-left: 40px; font-family: courier new,monospace; color: rgb(0, 0, 102);"&gt;&lt;font size="4"&gt;&lt;b&gt;script/console &lt;span style="color: rgb(0, 102, 0);"&gt;test&lt;/span&gt;&lt;br&gt;mongrel &lt;span style="color: rgb(0, 102, 0);"&gt;-e test&lt;/span&gt;&lt;br&gt; rake db:migrate &lt;span style="color: rgb(0, 102, 0);"&gt;RAILS_ENV=test&lt;/span&gt;&lt;br&gt;&lt;/b&gt;&lt;/font&gt;&lt;/div&gt;&lt;br&gt;Why?&lt;br&gt;&lt;br&gt;Consistency is a good thing.&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1069467794206617140-520100476271581021?l=biomime.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biomime.blogspot.com/feeds/520100476271581021/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1069467794206617140&amp;postID=520100476271581021' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/520100476271581021'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/520100476271581021'/><link rel='alternate' type='text/html' href='http://biomime.blogspot.com/2008/10/bugs-me.html' title='Bugs Me:'/><author><name>Jeremy Rice</name><uri>http://www.blogger.com/profile/12256074521855601742</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-wV3OV11Fp0k/TxhzaIa4zSI/AAAAAAAAPXQ/GY4PplLad-I/s220/AllSpiritualLike.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1069467794206617140.post-800386844231890301</id><published>2008-10-14T07:24:00.001-07:00</published><updated>2008-10-14T07:24:21.473-07:00</updated><title type='text'>IE6</title><content type='html'>&lt;div dir="ltr"&gt;I generally don&amp;#39;t pay attention to server stats, but recently I was getitng frustrated with IE6, so I asked those in the know how prevalent IE6 was.&amp;nbsp; The reply:&lt;br&gt;&lt;br&gt;&amp;quot;...as a total, IE 6 is about 22% of all users&amp;quot;&lt;br&gt; &lt;br&gt;My response: &lt;b&gt;holy &lt;i&gt;shit&lt;/i&gt;.&lt;/b&gt; That&amp;#39;s obscene! IE6 is &lt;i&gt;broken&lt;/i&gt;, and to think that over 1 in 5 people are still using that crap-tastic browser is an offense to the internet.&amp;nbsp; Sure, sure, I can understand needing to keep IE6 on some fragile server somewhere that, if you update it, your entire site breaks.&amp;nbsp; Fine.&amp;nbsp; But stop browsing with the damn machine!&amp;nbsp; There&amp;#39;s no good reason to keep using IE6.&lt;br&gt; &lt;br&gt;One in &lt;b&gt;five!!!&lt;/b&gt;&lt;br&gt;&lt;br&gt;People: &lt;i&gt;switch!&lt;/i&gt;&lt;br&gt;&lt;/div&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1069467794206617140-800386844231890301?l=biomime.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biomime.blogspot.com/feeds/800386844231890301/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1069467794206617140&amp;postID=800386844231890301' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/800386844231890301'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/800386844231890301'/><link rel='alternate' type='text/html' href='http://biomime.blogspot.com/2008/10/ie6.html' title='IE6'/><author><name>Jeremy Rice</name><uri>http://www.blogger.com/profile/12256074521855601742</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-wV3OV11Fp0k/TxhzaIa4zSI/AAAAAAAAPXQ/GY4PplLad-I/s220/AllSpiritualLike.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1069467794206617140.post-8313920532383408223</id><published>2008-09-17T20:29:00.001-07:00</published><updated>2008-09-17T20:29:23.594-07:00</updated><title type='text'>Composite Primary Keys (everyone's got an opinion)</title><content type='html'>&lt;div dir="ltr"&gt;&lt;div class="gmail_quote"&gt;&lt;div dir="ltr"&gt;Tonight I was playing around with some of the &amp;quot;cooler&amp;quot; things that Rails can do, and I thought I would try them out on our code.&lt;br&gt;&lt;br&gt;Namely, there are two features that I&amp;#39;d like to use: &lt;span style="color: rgb(51, 0, 0);"&gt;nested_has_many_through&lt;/span&gt;, and &lt;span style="color: rgb(51, 0, 0);"&gt;named_scope&lt;/span&gt;.&lt;br&gt;  &lt;br&gt;This would allow us to write code like &amp;quot;&lt;span style="font-family: courier new,monospace;"&gt;taxon_concept.data_objects.images.visible&lt;/span&gt;&amp;quot; without having to go through a hairy find_by_sql, and it would allow us to more easily make changes to the DB (like, say, how we define &amp;quot;visible&amp;quot; for data_objects).&amp;nbsp; It would have made one of today&amp;#39;s changes painless, too (long story).&lt;br&gt;  &lt;br&gt;It would also reduce the amount of code we have by a significant amount.&amp;nbsp; ...I like less code.&lt;br&gt;&lt;br&gt;...The problem, though, is that DHH doesn&amp;#39;t understand composite primary keys (CPKs) *at all*, and his framework reflects that.&amp;nbsp; Even with the CPK plugin, things don&amp;#39;t work right.&amp;nbsp; ...That is, when you declare a CPK on a model, it seems that it expects &lt;i&gt;every&lt;/i&gt; reference to it to contain &lt;i&gt;all&lt;/i&gt; of the PKs.&amp;nbsp; I tried doing something like (pseudo-code): &amp;quot;&lt;span style="font-family: courier new,monospace;"&gt;DataObject.has_many :data_objects_taxa, :foreign_key =&amp;gt; :data_object_id ; DataObjectsTaxon.has_many :data_objects, :foreign_key =&amp;gt; :id&lt;/span&gt;&amp;quot; (DataObjectsTaxon has a CPK)... but this doesn&amp;#39;t work: it STILL tries to pass in two key values.&amp;nbsp; The resulting queries are actually rather asinine (notice the 1,4 at the end), and fails miserably:&lt;br&gt;  &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="font-family: courier new,monospace;"&gt;SELECT * FROM `data_objects` WHERE (&lt;a href="http://data_objects.id" target="_blank"&gt;data_objects.id&lt;/a&gt; = 1,4)&lt;/span&gt;&lt;br&gt;&lt;br&gt;...I could delve into the CPK plugin code and try to resolve this, but I might be gone for days.&amp;nbsp; ; )&lt;br&gt;  &lt;br&gt;You can &lt;i&gt;kind of &lt;/i&gt;get around this by using a habtm relationship.&amp;nbsp; ...But that only works for that one hop.&amp;nbsp; So I can get data_object.taxa, but I &lt;b&gt;can&amp;#39;t&lt;/b&gt; get data_object.resources, using this code:&lt;br&gt;&lt;br&gt;  &lt;span style="font-family: courier new,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; has_and_belongs_to_many :taxa&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; has_many :resources, :through =&amp;gt; :taxa&lt;/span&gt;&lt;br&gt;  &lt;br&gt;This throws &amp;quot;Unknown column &amp;#39;taxa.data_object_id&amp;#39;&amp;quot;... and the docs even warn about this (&amp;quot;&lt;span style="color: rgb(51, 51, 51);"&gt;You can only use a &lt;/span&gt;&lt;tt style="color: rgb(51, 51, 51);"&gt;:through&lt;/tt&gt;&lt;span style="color: rgb(51, 51, 51);"&gt; query through a &lt;/span&gt;&lt;tt style="color: rgb(51, 51, 51);"&gt;&lt;a href="http://www.railsbrain.com/api/rails-2.1.0/doc/index.html?a=M001493&amp;amp;name=belongs_to" target="_blank"&gt;belongs_to&lt;/a&gt;&lt;/tt&gt;&lt;span style="color: rgb(51, 51, 51);"&gt; or &lt;/span&gt;&lt;tt style="color: rgb(51, 51, 51);"&gt;&lt;a href="http://www.railsbrain.com/api/rails-2.1.0/doc/index.html?a=M001491&amp;amp;name=has_many" target="_blank"&gt;has_many&lt;/a&gt;&lt;/tt&gt;&lt;span style="color: rgb(51, 51, 51);"&gt; association on the join model&lt;/span&gt;&amp;quot;).&lt;br&gt;&lt;br&gt;So.&lt;br&gt;&lt;br&gt;What I would like to do--knowing full well that this is the &lt;b&gt;wrong&lt;/b&gt; thing to do, but bending to the will of Rails--is change our CPKs to Unique Indexes, and add autoincrements to those tables.&amp;nbsp; I could write the migrations to do such things without too much trouble, but I worry about the affect it would have on the related PHP code (I hope none, since the autoinc should just merrily do its thang).&lt;br&gt;  &lt;br&gt;Again: from a database level of understanding, this irks me.&amp;nbsp; Where we use CPKs is where they are &lt;i&gt;uniquely identifying&lt;/i&gt; entries, and that&amp;#39;s how its sputta be.&amp;nbsp; ...but Rails thinks otherwise.&lt;br&gt;&lt;br&gt;...Unless someone knows a way to keep things as-is and get the has_many relationships working in both directions.&amp;nbsp; There my be some trick to it that I&amp;#39;m unaware of. That would be cool, too.&lt;br&gt;  &lt;br&gt;If we could get this to work, I think our code would be much, *much* more elegant (and thus, maintainable/extensible).&amp;nbsp; I&amp;#39;d be happy, assuming there isn&amp;#39;t a noticeable performance hit (but from what people are saying, it&amp;#39;s actually quite efficient).&lt;br&gt;  &lt;br&gt;Thoughts?&lt;br&gt;&lt;br&gt;&lt;br&gt;And: ...apologies to California Pizza Kitchen (CPK).&lt;br&gt;&lt;/div&gt; &lt;/div&gt;&lt;br&gt;&lt;/div&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1069467794206617140-8313920532383408223?l=biomime.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biomime.blogspot.com/feeds/8313920532383408223/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1069467794206617140&amp;postID=8313920532383408223' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/8313920532383408223'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/8313920532383408223'/><link rel='alternate' type='text/html' href='http://biomime.blogspot.com/2008/09/composite-primary-keys-everyones-got.html' title='Composite Primary Keys (everyone&apos;s got an opinion)'/><author><name>Jeremy Rice</name><uri>http://www.blogger.com/profile/12256074521855601742</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-wV3OV11Fp0k/TxhzaIa4zSI/AAAAAAAAPXQ/GY4PplLad-I/s220/AllSpiritualLike.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1069467794206617140.post-4455447393428739711</id><published>2008-09-17T13:43:00.001-07:00</published><updated>2008-09-17T13:43:52.922-07:00</updated><title type='text'>Murphy's Law of Variable Names</title><content type='html'>&lt;div dir="ltr"&gt;There are at least six appropriate names for any given variable, method, column, or table.&lt;br&gt;&lt;br&gt;You will not choose one of them.&lt;br&gt;&lt;/div&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1069467794206617140-4455447393428739711?l=biomime.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biomime.blogspot.com/feeds/4455447393428739711/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1069467794206617140&amp;postID=4455447393428739711' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/4455447393428739711'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/4455447393428739711'/><link rel='alternate' type='text/html' href='http://biomime.blogspot.com/2008/09/murphys-law-of-variable-names.html' title='Murphy&apos;s Law of Variable Names'/><author><name>Jeremy Rice</name><uri>http://www.blogger.com/profile/12256074521855601742</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-wV3OV11Fp0k/TxhzaIa4zSI/AAAAAAAAPXQ/GY4PplLad-I/s220/AllSpiritualLike.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1069467794206617140.post-4300674742405749413</id><published>2008-09-10T12:23:00.001-07:00</published><updated>2008-09-10T12:23:56.078-07:00</updated><title type='text'>You might be a geek if</title><content type='html'>&lt;div dir="ltr"&gt;...&amp;quot;too much rails&amp;quot; sounds grammatical to you.&lt;br&gt;&lt;/div&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1069467794206617140-4300674742405749413?l=biomime.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biomime.blogspot.com/feeds/4300674742405749413/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1069467794206617140&amp;postID=4300674742405749413' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/4300674742405749413'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/4300674742405749413'/><link rel='alternate' type='text/html' href='http://biomime.blogspot.com/2008/09/you-might-be-geek-if.html' title='You might be a geek if'/><author><name>Jeremy Rice</name><uri>http://www.blogger.com/profile/12256074521855601742</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-wV3OV11Fp0k/TxhzaIa4zSI/AAAAAAAAPXQ/GY4PplLad-I/s220/AllSpiritualLike.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1069467794206617140.post-2213924214902676822</id><published>2008-08-01T10:17:00.001-07:00</published><updated>2008-08-01T10:17:55.722-07:00</updated><title type='text'>Composite Primary Keys (CPK) and RSpec Fixtures</title><content type='html'>&lt;div dir="ltr"&gt;I was banging my head against the proverbial wall all week.&amp;nbsp; This morning&amp;#39;s travail was an error like this in my specs:&lt;br&gt;&lt;br&gt;&lt;div style="margin-left: 40px;"&gt;&lt;font color="#000099"&gt;&lt;font face="courier new,monospace"&gt;You have a nil object when you didn&amp;#39;t expect it!&lt;br&gt; You might have expected an instance of Array.&lt;br&gt;The error occurred while evaluating nil.first&lt;br&gt;/path/to/rails/app/vendor/gems/composite_primary_keys-1.0.5/lib/composite_primary_keys/base.rb:239:in `find_from_ids&amp;#39;&lt;br&gt; &lt;/font&gt;&lt;/font&gt;&lt;br&gt;&lt;/div&gt;...After some digging, I found a page that explained the problem, and revealed that you need this in your spec/spec_helper.rb file:&lt;br&gt;&lt;br&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;load &amp;#39;composite_primary_keys/fixtures.rb&amp;#39;&lt;/span&gt;&lt;br&gt; &lt;/div&gt;&lt;br&gt;I feel much better now.&lt;br&gt;&lt;/div&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1069467794206617140-2213924214902676822?l=biomime.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biomime.blogspot.com/feeds/2213924214902676822/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1069467794206617140&amp;postID=2213924214902676822' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/2213924214902676822'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/2213924214902676822'/><link rel='alternate' type='text/html' href='http://biomime.blogspot.com/2008/08/composite-primary-keys-cpk-and-rspec.html' title='Composite Primary Keys (CPK) and RSpec Fixtures'/><author><name>Jeremy Rice</name><uri>http://www.blogger.com/profile/12256074521855601742</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-wV3OV11Fp0k/TxhzaIa4zSI/AAAAAAAAPXQ/GY4PplLad-I/s220/AllSpiritualLike.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1069467794206617140.post-295941151943574391</id><published>2008-07-29T07:25:00.001-07:00</published><updated>2008-07-29T07:25:50.333-07:00</updated><title type='text'>Repetitive Stress</title><content type='html'>&lt;div dir="ltr"&gt;So, I&amp;#39;ve been programming pretty much non-stop for the past few months.&amp;nbsp; My wrists ad neck were suffering.&lt;br&gt;&lt;br&gt;Rather than start wearing braces again, I opted to try&lt;a href="http://tech.inhelsinki.nl/antirsi/"&gt; this program&lt;/a&gt; (Mac-only) that interrupts you every so often.&amp;nbsp; ...I have it set for 12 seconds every few minutes, and 10 minutes every hour.&amp;nbsp; I started using it about a month aogo&lt;br&gt; &lt;br&gt;It seems to have done wonders for my hands and wrists, so I highly recommend it.&lt;br&gt;&lt;br&gt;Ain&amp;#39;t done squat for my neck, though.&amp;nbsp; ...And some days, it gets really bad. : \&lt;br&gt;&lt;/div&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1069467794206617140-295941151943574391?l=biomime.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biomime.blogspot.com/feeds/295941151943574391/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1069467794206617140&amp;postID=295941151943574391' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/295941151943574391'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/295941151943574391'/><link rel='alternate' type='text/html' href='http://biomime.blogspot.com/2008/07/repetitive-stress.html' title='Repetitive Stress'/><author><name>Jeremy Rice</name><uri>http://www.blogger.com/profile/12256074521855601742</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-wV3OV11Fp0k/TxhzaIa4zSI/AAAAAAAAPXQ/GY4PplLad-I/s220/AllSpiritualLike.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1069467794206617140.post-8254968192153641884</id><published>2008-07-23T13:24:00.000-07:00</published><updated>2008-07-23T13:26:34.150-07:00</updated><title type='text'>Open Source, Sickles, and Hammers</title><content type='html'>&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://farm1.static.flickr.com/10/16631508_3588891393_o.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px;" src="http://farm1.static.flickr.com/10/16631508_3588891393_o.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;span style="font-size:85%;"&gt;(Image cc-by &lt;a href="http://flickr.com/photos/jagelado/16631508/"&gt;jagelado&lt;/a&gt;)&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1069467794206617140-8254968192153641884?l=biomime.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biomime.blogspot.com/feeds/8254968192153641884/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1069467794206617140&amp;postID=8254968192153641884' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/8254968192153641884'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/8254968192153641884'/><link rel='alternate' type='text/html' href='http://biomime.blogspot.com/2008/07/open-source-sickles-and-hammers.html' title='Open Source, Sickles, and Hammers'/><author><name>Jeremy Rice</name><uri>http://www.blogger.com/profile/12256074521855601742</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-wV3OV11Fp0k/TxhzaIa4zSI/AAAAAAAAPXQ/GY4PplLad-I/s220/AllSpiritualLike.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1069467794206617140.post-6452364853609729517</id><published>2008-07-02T14:57:00.001-07:00</published><updated>2008-07-02T14:57:09.483-07:00</updated><title type='text'>Using Vim and MySQL to Create Fixtures (for Rails)</title><content type='html'>&lt;div class="gmail_quote"&gt;...I&amp;#39;ve had to build a lot of fixtures using extant data from a MySQL database.&amp;nbsp; I don&amp;#39;t want the whole database in my fixtures... just a subset, based on some examples I use in my specs.&lt;br&gt; &lt;br&gt;So I run a query to get the subset I want, being sure to grab all the contents from a given table (and ONLY one table).&amp;nbsp; Something like this:&lt;br&gt;&lt;br&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(0, 102, 0);"&gt;SELECT st.*&lt;br&gt; &amp;nbsp; FROM a_fancy_table ft&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; JOIN some_table st ON (&lt;a href="http://ft.id"&gt;ft.id&lt;/a&gt; = st.a_fancy_table_id)&lt;br&gt;&amp;nbsp; WHERE &lt;a href="http://ft.id"&gt;ft.id&lt;/a&gt; IN (1, 2, 3)\G&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;/div&gt;The \G is essential, here.&amp;nbsp; I then copy the output of that to the some_table.yml file, created with vim.&lt;br&gt; &lt;br&gt;Then:&lt;br&gt;&lt;ol&gt;&lt;li&gt;&lt;b style="font-family: courier new,monospace;"&gt;&amp;lt;ap&lt;/b&gt; multiple times, until everything is left-justified, then&lt;/li&gt; &lt;li&gt;&lt;b&gt;&lt;span style="font-family: courier new,monospace;"&gt;&amp;gt;ap&lt;/span&gt;&lt;/b&gt; once, so that it&amp;#39;s all indented 1 level, then&lt;br&gt;&lt;/li&gt;&lt;li style="font-family: courier new,monospace;"&gt;&lt;b&gt;:%s/&amp;nbsp; \*\+ \(\d\+\). row \*\+/^Msome_prefix_\1:&lt;/b&gt;&lt;/li&gt; &lt;li&gt;finally, rename any of those that are really significant.&lt;/li&gt;&lt;/ol&gt;...Of course, the &lt;b style="font-family: courier new,monospace;"&gt;^M&lt;/b&gt; is really&lt;b&gt;&lt;span style="font-family: courier new,monospace;"&gt; ^v[ENTER]&lt;/span&gt;&lt;/b&gt;, and the &lt;b style="font-family: courier new,monospace;"&gt;some_prefix&lt;/b&gt; is whatever you want to name your objects.&lt;br&gt;  &lt;br&gt;...If that makes sense, you&amp;#39;ll find it&amp;#39;s a huge time-saver.&amp;nbsp; Unless you&amp;#39;re copying entire tables, in which case you can use &lt;a href="http://code.google.com/p/tuskit/source/browse/trunk/lib/migration_helpers.rb"&gt;Dmitry&amp;#39;s script&lt;/a&gt;.&lt;br&gt; &lt;br&gt;&lt;/div&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1069467794206617140-6452364853609729517?l=biomime.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biomime.blogspot.com/feeds/6452364853609729517/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1069467794206617140&amp;postID=6452364853609729517' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/6452364853609729517'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/6452364853609729517'/><link rel='alternate' type='text/html' href='http://biomime.blogspot.com/2008/07/using-vim-and-mysql-to-create-fixtures.html' title='Using Vim and MySQL to Create Fixtures (for Rails)'/><author><name>Jeremy Rice</name><uri>http://www.blogger.com/profile/12256074521855601742</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-wV3OV11Fp0k/TxhzaIa4zSI/AAAAAAAAPXQ/GY4PplLad-I/s220/AllSpiritualLike.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1069467794206617140.post-4849878912031609844</id><published>2008-06-12T09:05:00.001-07:00</published><updated>2008-06-12T09:05:22.714-07:00</updated><title type='text'>ZenTest and autotest in Windows with RSpec and Rails</title><content type='html'>I&amp;#39;ve been trying to monkey-patch ZenTest&amp;#39;s autotest for over a month now.&amp;nbsp; Originally, I was trying to get it to work (well) with snarl, but that just seems frivolous at this point.&amp;nbsp; My focus now is just to get the damn tests working as they should.&lt;br&gt; &lt;br&gt;First of all, Windows doesn&amp;#39;t let you break out of the loop.&amp;nbsp; ...At least, not that I&amp;#39;ve ever seen.&amp;nbsp; I haven&amp;#39;t heard a SINGLE person on the web talk about this, which is frustrating.&amp;nbsp; Maybe I&amp;#39;m missing something stupid, but I know other people that this is happening to.&lt;br&gt; &lt;br&gt;Anyway, the fix for that is to change the &amp;quot;Kernel.sleep 1.5&amp;quot; on line 291 of autotest.rb... it works if you change it to this: &lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 30.times { Kernel.sleep 0.05 }&lt;br&gt;&lt;br&gt;I don&amp;#39;t know why, but I&amp;#39;m assuming it has something to do with how sleep is implemented on Windows that causes it to lose the scope of self.interrupted.&amp;nbsp; Or something.&amp;nbsp; Whatever: this works.&lt;br&gt; &lt;br&gt;Next, I&amp;#39;ll try to find a regex that will actaully find the right files to run, when there has been a change!&amp;nbsp; Grr.&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1069467794206617140-4849878912031609844?l=biomime.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biomime.blogspot.com/feeds/4849878912031609844/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1069467794206617140&amp;postID=4849878912031609844' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/4849878912031609844'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/4849878912031609844'/><link rel='alternate' type='text/html' href='http://biomime.blogspot.com/2008/06/zentest-and-autotest-in-windows-with.html' title='ZenTest and autotest in Windows with RSpec and Rails'/><author><name>Jeremy Rice</name><uri>http://www.blogger.com/profile/12256074521855601742</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-wV3OV11Fp0k/TxhzaIa4zSI/AAAAAAAAPXQ/GY4PplLad-I/s220/AllSpiritualLike.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1069467794206617140.post-7779407102303164859</id><published>2008-05-28T05:51:00.001-07:00</published><updated>2008-05-28T05:51:11.386-07:00</updated><title type='text'>Optics</title><content type='html'>So, I was just thinking about &lt;a href="http://exemplar.eol.org:8080/fedora/get/data:295987/LocalImage"&gt;microscopic images&lt;/a&gt;, and how they&amp;#39;re always so much blurrier than &lt;a href="http://exemplar.eol.org:8080/fedora/get/data:240976/LocalImage"&gt;illustrations&lt;/a&gt;.&amp;nbsp; I was thinking about how, in &lt;a href="http://video.google.com/videoplay?docid=4045285854844480169&amp;amp;q=microscopic&amp;amp;ei=wVM9SNbZIIjGrQKS9oCCBA"&gt;videos&lt;/a&gt;, you can see various parts of the organism sharply, depending on the focus of the optics... it&amp;#39;s just a razor-thin depth of field.&lt;br&gt; &lt;br&gt;Then I thought: hey, wait, we have &lt;a href="http://range.wordpress.com/2006/07/15/modern-hdr-photography-a-how-to-or-saturday-morning-relaxation/"&gt;HDR photography&lt;/a&gt;.&amp;nbsp; ...Why can&amp;#39;t we use this at a microscopic level to increase clarity?&lt;br&gt; &lt;br&gt;I could even imagine a machine-controlled microscope that produces one image from a composite of multiple images shot at different focal lengths, helping to bring the entire image into maximal focus.&lt;br&gt;&lt;br&gt;...Of course, I&amp;#39;m sure someone else has &lt;a href="http://www.stegerphoto.com/gallery_page/microworld06.html"&gt;already thought of this&lt;/a&gt;.&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1069467794206617140-7779407102303164859?l=biomime.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biomime.blogspot.com/feeds/7779407102303164859/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1069467794206617140&amp;postID=7779407102303164859' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/7779407102303164859'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/7779407102303164859'/><link rel='alternate' type='text/html' href='http://biomime.blogspot.com/2008/05/optics.html' title='Optics'/><author><name>Jeremy Rice</name><uri>http://www.blogger.com/profile/12256074521855601742</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-wV3OV11Fp0k/TxhzaIa4zSI/AAAAAAAAPXQ/GY4PplLad-I/s220/AllSpiritualLike.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1069467794206617140.post-8448703191402974416</id><published>2008-05-21T15:47:00.001-07:00</published><updated>2008-05-21T17:11:36.913-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='formatting'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><title type='text'>Posting Ruby</title><content type='html'>So, I broke down and did some research on how to post code to blogger so that it doesn't look hideous.  It wasn't nearly as simple as I wanted it to be (most notably, it was a serious pain to use cocoa to use the pasteboard for converting text)... so I hacked together a little rails project that handles things for me using web forms.  It would be a long post to explain all the details, but I'll cover the basics.&lt;br /&gt;&lt;br /&gt;First, &lt;span style="color: rgb(0, 0, 102);font-family:courier new;" &gt;sudo gem install syntax&lt;/span&gt;.  Then create a new rails project and get it up and running.  When you've got that, generate a controller called "Convert".  The code for the controller should look like this:&lt;br /&gt;&lt;pre&gt;&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;ConvertController&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt; &lt;span class="constant"&gt;ApplicationController&lt;/span&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;ruby&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;render&lt;/span&gt; &lt;span class="symbol"&gt;:action&lt;/span&gt; &lt;span class="punct"&gt;=&gt;&lt;/span&gt; &lt;span class="symbol"&gt;:ruby&lt;/span&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;to_html&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;syntax/convertors/html&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;convertor&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Syntax&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Convertors&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;HTML&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;for_syntax&lt;/span&gt; &lt;span class="ident"&gt;params&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:type&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt;&lt;br /&gt;    &lt;span class="attribute"&gt;@code&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;convertor&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;convert&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;params&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:text&lt;/span&gt;&lt;span class="punct"&gt;]).&lt;/span&gt;&lt;span class="ident"&gt;gsub&lt;/span&gt;&lt;span class="punct"&gt;(/&lt;/span&gt;&lt;span class="regex"&gt;&amp;lt;span class="punct"&gt;([^&amp;lt;]*)&amp;lt([^&amp;lt;]*)&amp;lt;&lt;/span&gt;&lt;span class="punct"&gt;/,&lt;/span&gt; &lt;span class="punct"&gt;"&lt;/span&gt;&lt;span class="string"&gt;&amp;lt;span class=&lt;span class="escape"&gt;\"&lt;/span&gt;punct&lt;span class="escape"&gt;\"&lt;/span&gt;&gt;&lt;span class="escape"&gt;\\&lt;/span&gt;1&amp;amp;lt&lt;span class="escape"&gt;\\&lt;/span&gt;2&lt;&lt;/span&gt;&lt;span class="punct"&gt;")&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;render&lt;/span&gt; &lt;span class="symbol"&gt;:action&lt;/span&gt; &lt;span class="punct"&gt;=&gt;&lt;/span&gt; &lt;span class="symbol"&gt;:to_html&lt;/span&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And then you'll need a view for 'ruby.html.erb'.:&lt;br /&gt;&lt;pre&gt;&lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;h1&lt;/span&gt;&lt;span class="punct"&gt;&gt;&lt;/span&gt;Convert What?&lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag"&gt;h1&lt;/span&gt;&lt;span class="punct"&gt;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;p&lt;/span&gt;&lt;span class="punct"&gt;&gt;&lt;/span&gt;&lt;br /&gt; &lt;span class="punct"&gt;&amp;lt;%&lt;/span&gt; &lt;span class="attribute"&gt;form_tag(&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;/convert/to_html&lt;/span&gt;&lt;span class="punct"&gt;')&lt;/span&gt; &lt;span class="attribute"&gt;do&lt;/span&gt; %&lt;span class="punct"&gt;&gt;&lt;/span&gt;&lt;br /&gt; &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;table&lt;/span&gt;&lt;span class="punct"&gt;&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;tr&lt;/span&gt;&lt;span class="punct"&gt;&gt;&amp;lt&lt;/span&gt;&lt;span class="tag"&gt;td&lt;/span&gt;&lt;span class="punct"&gt;&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="attribute"&gt;text_area_tag&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;text&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="punct"&gt;'',&lt;/span&gt; {:&lt;span class="attribute"&gt;cols&lt;/span&gt; &lt;span class="punct"&gt;=&gt;&lt;/span&gt; 80, :rows =&gt; 30} %&gt;&lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag"&gt;td&lt;/span&gt;&lt;span class="punct"&gt;&gt;&lt;/span&gt;&lt;br /&gt;   &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;td&lt;/span&gt;&lt;span class="punct"&gt;&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="attribute"&gt;radio_button_tag&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;type&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;ruby&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="attribute"&gt;true%&lt;/span&gt;&lt;span class="punct"&gt;&gt;&lt;/span&gt;Ruby&lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;br&lt;/span&gt;&lt;span class="punct"&gt;/&gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="punct"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="attribute"&gt;radio_button_tag&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;type&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;xml&lt;/span&gt;&lt;span class="punct"&gt;'%&gt;&lt;/span&gt;HTML/XML&lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;br&lt;/span&gt;&lt;span class="punct"&gt;/&gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="punct"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="attribute"&gt;submit_tag&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;convert to HTML&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="punct"&gt;&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;td&lt;/span&gt;&lt;span class="punct"&gt;&gt;&lt;/span&gt;&lt;span class="tag"&gt;tr&lt;/span&gt;&lt;span class="punct"&gt;&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;table&lt;/span&gt;&lt;span class="punct"&gt;&gt;&lt;/span&gt;&lt;br /&gt; &lt;span class="punct"&gt;&amp;lt;%&lt;/span&gt; &lt;span class="attribute"&gt;end&lt;/span&gt; %&lt;span class="punct"&gt;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag"&gt;p&lt;/span&gt;&lt;span class="punct"&gt;&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;...And a basic response form in 'to_html.html.erb':&lt;br /&gt;&lt;pre&gt;&lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;h1&lt;/span&gt;&lt;span class="punct"&gt;&gt;&lt;/span&gt;The raw HTML:&lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag"&gt;h1&lt;/span&gt;&lt;span class="punct"&gt;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;pre&lt;/span&gt;&lt;span class="punct"&gt;&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="tag"&gt;text_area_tag&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;whatever&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; @&lt;span class="attribute"&gt;code&lt;/span&gt;&lt;span class="punct"&gt;, {:&lt;/span&gt;&lt;span class="attribute"&gt;cols&lt;/span&gt; &lt;span class="punct"&gt;=&gt;&lt;/span&gt; 80, :rows =&gt; 30}) %&gt;&lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag"&gt;pre&lt;/span&gt;&lt;span class="punct"&gt;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;h1&lt;/span&gt;&lt;span class="punct"&gt;&gt;&lt;/span&gt;The results:&lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag"&gt;h1&lt;/span&gt;&lt;span class="punct"&gt;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="punct"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="attribute"&gt;@code.gsub(/&amp;amp;amp;/,&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;&amp;amp;&lt;/span&gt;&lt;span class="punct"&gt;')&lt;/span&gt; &lt;span class="punct"&gt;%&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;...You'll also want to set up the CSS for your site, using &lt;a href="http://blog.wolfman.com/articles/2006/05/26/howto-format-ruby-code-for-blogs"&gt;the CSS&lt;/a&gt; from the site where I stole this idea from.  Polishing things is an exercise left to the reader... but that should get you started.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1069467794206617140-8448703191402974416?l=biomime.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biomime.blogspot.com/feeds/8448703191402974416/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1069467794206617140&amp;postID=8448703191402974416' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/8448703191402974416'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/8448703191402974416'/><link rel='alternate' type='text/html' href='http://biomime.blogspot.com/2008/05/posting-ruby.html' title='Posting Ruby'/><author><name>Jeremy Rice</name><uri>http://www.blogger.com/profile/12256074521855601742</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-wV3OV11Fp0k/TxhzaIa4zSI/AAAAAAAAPXQ/GY4PplLad-I/s220/AllSpiritualLike.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1069467794206617140.post-6296057618339255525</id><published>2008-05-21T12:56:00.001-07:00</published><updated>2008-05-21T15:36:42.779-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><title type='text'>Assumptions</title><content type='html'>So, I was writing a few RSpec tests today, and required Hpricot to look at a few views.  This was the code I wrote:&lt;br /&gt;&lt;pre&gt;     &lt;span class="ident"&gt;links&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;each&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;link&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;&lt;br /&gt;        &lt;span class="ident"&gt;this_taxa_name&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;nil&lt;/span&gt; &lt;span class="comment"&gt;# scope&lt;/span&gt;&lt;br /&gt;        &lt;span class="ident"&gt;img&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;link&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;at&lt;/span&gt;&lt;span class="punct"&gt;(&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;img&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;)&lt;/span&gt;&lt;br /&gt;        &lt;span class="keyword"&gt;if&lt;/span&gt;  &lt;span class="ident"&gt;img&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;nil?&lt;/span&gt;&lt;br /&gt;          &lt;span class="ident"&gt;this_taxa_name&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;link&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;inner_text&lt;/span&gt; &lt;span class="comment"&gt;# This was the text link&lt;/span&gt;&lt;br /&gt;        &lt;span class="keyword"&gt;else&lt;/span&gt;&lt;br /&gt;          &lt;span class="ident"&gt;has_image&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;true&lt;/span&gt; &lt;span class="comment"&gt;# This is the image.&lt;/span&gt;&lt;br /&gt;          &lt;span class="ident"&gt;this_taxa_name&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;img&lt;/span&gt;&lt;span class="punct"&gt;['&lt;/span&gt;&lt;span class="string"&gt;alt&lt;/span&gt;&lt;span class="punct"&gt;']&lt;/span&gt;&lt;br /&gt;        &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;        &lt;span class="ident"&gt;taxa_name&lt;/span&gt; &lt;span class="punct"&gt;||=&lt;/span&gt; &lt;span class="ident"&gt;this_taxa_name&lt;/span&gt;&lt;br /&gt;        &lt;span class="ident"&gt;assert_equal&lt;/span&gt; &lt;span class="ident"&gt;taxa_name&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;this_taxa_name&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;The names for the featured species were inconsistent (image alt/text)&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;&lt;br /&gt;        &lt;span class="ident"&gt;taxa_link&lt;/span&gt; &lt;span class="punct"&gt;||=&lt;/span&gt; &lt;span class="ident"&gt;link&lt;/span&gt;&lt;span class="punct"&gt;['&lt;/span&gt;&lt;span class="string"&gt;href&lt;/span&gt;&lt;span class="punct"&gt;']&lt;/span&gt;&lt;br /&gt;        &lt;span class="ident"&gt;assert_equal&lt;/span&gt; &lt;span class="ident"&gt;taxa_link&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;link&lt;/span&gt;&lt;span class="punct"&gt;['&lt;/span&gt;&lt;span class="string"&gt;href&lt;/span&gt;&lt;span class="punct"&gt;'],&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;The links for the featured species were inconsistent (image/text)&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;&lt;br /&gt;      &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;      &lt;span class="ident"&gt;assert&lt;/span&gt; &lt;span class="ident"&gt;has_image&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;There was no image for the featured species&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;...This was all because I was trying NOT to assume that the image always precedes the text for the image.  The test ended up being a bit longer than one page, so I asked a co-worker to look at it.  His simple suggestion was "it's okay to assume the image comes before the text".  By making that assumption, this block of code above becomes:&lt;br /&gt;&lt;span style="font-family:courier new,monospace;"&gt;      &lt;pre&gt;      &lt;span class="ident"&gt;assert&lt;/span&gt; &lt;span class="punct"&gt;!(&lt;/span&gt;&lt;span class="ident"&gt;links&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;nil?&lt;/span&gt; &lt;span class="keyword"&gt;or&lt;/span&gt; &lt;span class="ident"&gt;links&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;length&lt;/span&gt; &lt;span class="punct"&gt;==&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;),&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;The featured species had no links&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;&lt;br /&gt;      &lt;span class="ident"&gt;assert_not_nil&lt;/span&gt; &lt;span class="ident"&gt;links&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;].&lt;/span&gt;&lt;span class="ident"&gt;at&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;img&lt;/span&gt;&lt;span class="punct"&gt;'),&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;There was no image for the featured species&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;&lt;br /&gt;      &lt;span class="ident"&gt;assert_equal&lt;/span&gt; &lt;span class="ident"&gt;links&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;]['&lt;/span&gt;&lt;span class="string"&gt;href&lt;/span&gt;&lt;span class="punct"&gt;'],&lt;/span&gt; &lt;span class="ident"&gt;links&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;]['&lt;/span&gt;&lt;span class="string"&gt;href&lt;/span&gt;&lt;span class="punct"&gt;'],&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;The links for the featured species were inconsistent (image/text)&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;&lt;br /&gt;      &lt;span class="ident"&gt;assert_equal&lt;/span&gt; &lt;span class="ident"&gt;links&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;].&lt;/span&gt;&lt;span class="ident"&gt;at&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;img&lt;/span&gt;&lt;span class="punct"&gt;')['&lt;/span&gt;&lt;span class="string"&gt;alt&lt;/span&gt;&lt;span class="punct"&gt;'],&lt;/span&gt; &lt;span class="ident"&gt;links&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;].&lt;/span&gt;&lt;span class="ident"&gt;inner_text&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;The names for the featured species were inconsistent (image &lt;/span&gt;&lt;/pre&gt;&lt;/span&gt; It's very easy to see why assumptions are the #1 problem that developers have.  They make life much, MUCH easier.&lt;br /&gt;&lt;br /&gt;I suppose that's true of life as well.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1069467794206617140-6296057618339255525?l=biomime.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biomime.blogspot.com/feeds/6296057618339255525/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1069467794206617140&amp;postID=6296057618339255525' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/6296057618339255525'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/6296057618339255525'/><link rel='alternate' type='text/html' href='http://biomime.blogspot.com/2008/05/assumptions.html' title='Assumptions'/><author><name>Jeremy Rice</name><uri>http://www.blogger.com/profile/12256074521855601742</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-wV3OV11Fp0k/TxhzaIa4zSI/AAAAAAAAPXQ/GY4PplLad-I/s220/AllSpiritualLike.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1069467794206617140.post-2860122530477051540</id><published>2008-05-18T13:20:00.001-07:00</published><updated>2008-05-21T15:38:42.964-07:00</updated><title type='text'>Oh, and when adding methods to core classes...</title><content type='html'>There's this neat pattern of checking to see if it's there first.  I'm not sure if this really saves any cycles (I would imagine a few), but may aid in avoiding collisions, at the very least.  For example thus:&lt;br /&gt;&lt;br /&gt;&lt;div style="margin-left: 40px;"&gt;&lt;pre&gt;&lt;span class="keyword"&gt;unless&lt;/span&gt; &lt;span class="constant"&gt;String&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;instance_methods&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;include?&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;_sp_clean&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;String&lt;/span&gt;&lt;br /&gt;    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;_sp_clean&lt;/span&gt;&lt;br /&gt;      &lt;span class="ident"&gt;str&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;self&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;clone&lt;/span&gt;&lt;br /&gt;      &lt;span class="ident"&gt;str&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;CGI&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;escape&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;str&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="comment"&gt;# Turns spaces into '+' rather than '%20'... we expect that, though&lt;/span&gt;&lt;br /&gt;                            &lt;span class="comment"&gt;# URI.escape allows [=&amp;amp;], etc... which we don't want.&lt;/span&gt;&lt;br /&gt;    &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/pre&gt; &lt;/div&gt;&lt;br /&gt;...Now I hope that formats nicely when this message posts.  : \&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1069467794206617140-2860122530477051540?l=biomime.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biomime.blogspot.com/feeds/2860122530477051540/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1069467794206617140&amp;postID=2860122530477051540' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/2860122530477051540'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/2860122530477051540'/><link rel='alternate' type='text/html' href='http://biomime.blogspot.com/2008/05/oh-and-when-adding-methods-to-core.html' title='Oh, and when adding methods to core classes...'/><author><name>Jeremy Rice</name><uri>http://www.blogger.com/profile/12256074521855601742</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-wV3OV11Fp0k/TxhzaIa4zSI/AAAAAAAAPXQ/GY4PplLad-I/s220/AllSpiritualLike.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1069467794206617140.post-8997782546237768694</id><published>2008-05-18T13:15:00.001-07:00</published><updated>2008-05-18T13:15:23.776-07:00</updated><title type='text'>Built my first gem</title><content type='html'>...And it was rather easy.&amp;nbsp; After using the &amp;quot;&lt;a href="http://newgem.rubyforge.org/"&gt;newgem&lt;/a&gt;&amp;quot; gem to create the skeleton, I just followed some bloke&amp;#39;s &lt;a href="http://blogs.cocoondev.org/crafterm/archives/004653.html"&gt;instructions&lt;/a&gt; for editing the Rakefile.&amp;nbsp; Piece of cake.&lt;br&gt; &lt;br&gt;Just thought I&amp;#39;d mention it.&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1069467794206617140-8997782546237768694?l=biomime.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biomime.blogspot.com/feeds/8997782546237768694/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1069467794206617140&amp;postID=8997782546237768694' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/8997782546237768694'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/8997782546237768694'/><link rel='alternate' type='text/html' href='http://biomime.blogspot.com/2008/05/built-my-first-gem.html' title='Built my first gem'/><author><name>Jeremy Rice</name><uri>http://www.blogger.com/profile/12256074521855601742</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-wV3OV11Fp0k/TxhzaIa4zSI/AAAAAAAAPXQ/GY4PplLad-I/s220/AllSpiritualLike.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1069467794206617140.post-5206957809925146246</id><published>2008-05-15T13:37:00.001-07:00</published><updated>2008-05-15T13:37:06.302-07:00</updated><title type='text'>Text and HTML in Thunderbird</title><content type='html'>So, I&amp;#39;m using Thunderbird now.&lt;br&gt;&lt;br&gt;One of the first pains that I&amp;#39;ve encountered is that, when replying to email, I get a warning that HTML may be unavailable to the recipient.&lt;br&gt;&lt;br&gt;To turn this warning off (and select whatever you want as a default), look under Tools &amp;gt; Options &amp;gt; Composition &amp;gt; Send Options.&amp;nbsp; The rest should be self-explanatory.&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1069467794206617140-5206957809925146246?l=biomime.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biomime.blogspot.com/feeds/5206957809925146246/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1069467794206617140&amp;postID=5206957809925146246' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/5206957809925146246'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/5206957809925146246'/><link rel='alternate' type='text/html' href='http://biomime.blogspot.com/2008/05/text-and-html-in-thunderbird.html' title='Text and HTML in Thunderbird'/><author><name>Jeremy Rice</name><uri>http://www.blogger.com/profile/12256074521855601742</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-wV3OV11Fp0k/TxhzaIa4zSI/AAAAAAAAPXQ/GY4PplLad-I/s220/AllSpiritualLike.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1069467794206617140.post-1905634887052250031</id><published>2008-05-15T11:22:00.001-07:00</published><updated>2008-05-15T11:22:12.108-07:00</updated><title type='text'>Learning</title><content type='html'>Wow, what a blast these past three days have been!&amp;nbsp; We had a consultant in from MySQL, and I learned hoards of new tricks, tips, and techniques.&amp;nbsp; Here are a few:&lt;br&gt;&lt;ul&gt;&lt;li&gt;You can store images on the filesystem based on their PK, to save having a field with the path.&amp;nbsp; For example, &lt;a href="http://image.id"&gt;image.id&lt;/a&gt; = 15579, image.path = images/1/5/5/7/9.png (or whatever level of separation you find appropriate).&lt;/li&gt; &lt;li&gt;EXT3--though it can be tuned--is not an ideal filesystem for databases.&amp;nbsp; XFS is much better.&amp;nbsp; (He didn&amp;#39;t give specific reasons, and I don&amp;#39;t particularly care to look into it.)&lt;br&gt;&lt;/li&gt;&lt;li&gt;QCache_hits should be much higher than QCache_inserts.&amp;nbsp; (show with &amp;quot;show global status like &amp;#39;qc%&amp;#39;&amp;quot;)&amp;nbsp; If it&amp;#39;s not, you need to hard-code which queries use the cache and which don&amp;#39;t.&amp;nbsp; Global status can also tell you about the number of locks that are occurring, which you may also wish to tweak.&lt;br&gt; &lt;/li&gt;&lt;li&gt;query_cache_type values are: 0 = off, 1 = on, 2 = on demand&lt;/li&gt;&lt;li&gt;QCache hits are &lt;i&gt;never&lt;/i&gt; logged.&amp;nbsp; That would take more time.&amp;nbsp; So if you want to really see how often queries are running, you have to turn of caches.&lt;/li&gt; &lt;li&gt;400M is a reasonable limit for query cache.&lt;/li&gt;&lt;li&gt;Stop apache from forking: this is what brings so many sites down.&amp;nbsp; Instead, figure out how many concurrent processes your box can &lt;i&gt;really&lt;/i&gt; handle, and then set the number of connections to this limit. If this is exceeded, the OS will queue additional requests, and keep the system from dying.&amp;nbsp; 100 is a reasonable place to start.&lt;/li&gt; &lt;li&gt;MyISAM tables are fine if you&amp;#39;re read-only (or nearly so): they will be faster.&amp;nbsp; But InnoDB is much, much faster, since they store the table completely in memory.&amp;nbsp; Of course, this means you have to have enough memory to fit the damned thing.&amp;nbsp; ; )&amp;nbsp; ...And, of course, there are caveats about very large fields (like blobs, texts, and varchars with large average size).&amp;nbsp; Shrinking your data as much as possible is important with large datasets... even one unused byte becomes a Meg with a million rows!&lt;br&gt; &lt;/li&gt;&lt;li&gt;&amp;quot;show innodb status\g&amp;quot; is a tool for checking InnoDB performance.&lt;/li&gt;&lt;li&gt;strace shows all the system calls used for a command (linux).&amp;nbsp; Very cool!&amp;nbsp; Not sure how I hadn&amp;#39;t seen this one before...&lt;br&gt; &lt;/li&gt;&lt;li&gt;Sharding is what massive scaling is all about... but that&amp;#39;s a topic you&amp;#39;ll have to look up on the web, since there&amp;#39;s so much to it.&amp;nbsp; ; )&lt;/li&gt;&lt;/ul&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1069467794206617140-1905634887052250031?l=biomime.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biomime.blogspot.com/feeds/1905634887052250031/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1069467794206617140&amp;postID=1905634887052250031' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/1905634887052250031'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/1905634887052250031'/><link rel='alternate' type='text/html' href='http://biomime.blogspot.com/2008/05/learning.html' title='Learning'/><author><name>Jeremy Rice</name><uri>http://www.blogger.com/profile/12256074521855601742</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-wV3OV11Fp0k/TxhzaIa4zSI/AAAAAAAAPXQ/GY4PplLad-I/s220/AllSpiritualLike.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1069467794206617140.post-9154111721338786352</id><published>2008-05-06T21:03:00.001-07:00</published><updated>2008-05-06T21:03:53.655-07:00</updated><title type='text'>One more Annoyance with Tiger Terminal</title><content type='html'>...So, when I moved .bashrc to .bash_profile, I lost my PATH environment variable.&amp;nbsp; (Rather, it was stripped down to next to nothing.)&lt;br&gt;&lt;br&gt;To fix this, I moved .bash_profile aside, re-ran terminal, ran &lt;font face="courier new,monospace"&gt;env&lt;font face="arial,sans-serif"&gt; to get the old PATH, and pasted that into my .bash_profile where I used to say &amp;quot;$PATH&amp;quot;.&amp;nbsp; Something like this:&lt;br&gt; &lt;br&gt;&lt;/font&gt;&lt;/font&gt;&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;export PATH=/sw/bin:/sw/sbin:$GEM_HOME/bin:/opt/local/bin:/usr/local/bin:/opt/local/sbin:/usr/local/mysql/bin:/Users/cpr4cpu/bin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/X11R6/bin&lt;/span&gt;&lt;br&gt; &lt;/div&gt;&lt;br&gt;&lt;font face="arial,sans-serif"&gt;...Pain in the arse, this.&lt;/font&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1069467794206617140-9154111721338786352?l=biomime.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biomime.blogspot.com/feeds/9154111721338786352/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1069467794206617140&amp;postID=9154111721338786352' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/9154111721338786352'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/9154111721338786352'/><link rel='alternate' type='text/html' href='http://biomime.blogspot.com/2008/05/one-more-annoyance-with-tiger-terminal.html' title='One more Annoyance with Tiger Terminal'/><author><name>Jeremy Rice</name><uri>http://www.blogger.com/profile/12256074521855601742</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-wV3OV11Fp0k/TxhzaIa4zSI/AAAAAAAAPXQ/GY4PplLad-I/s220/AllSpiritualLike.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1069467794206617140.post-3553322129462218618</id><published>2008-05-06T20:36:00.001-07:00</published><updated>2008-05-06T20:36:20.467-07:00</updated><title type='text'>Bash Profile, not BashRC</title><content type='html'>Another lesson learned:&lt;br&gt;&lt;br&gt;In Tiger, the Terminal doesn&amp;#39;t used .bashrc.&amp;nbsp; Why?&amp;nbsp; Couldn&amp;#39;t say.&lt;br&gt;&lt;br&gt;Just move your &lt;span style="font-family: courier new,monospace;"&gt;.bashrc&lt;/span&gt; file to &lt;span style="font-family: courier new,monospace;"&gt;.bash_profile&lt;/span&gt;&lt;br&gt; &lt;br&gt;Problem solved.&amp;nbsp; Lame.&amp;nbsp; There&amp;#39;s more discussion about this on the &lt;a href="http://macosx.com/forums/archive/t-296233.html"&gt;Mac site&lt;/a&gt;, but I didn&amp;#39;t really care to dig past the workaround.&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1069467794206617140-3553322129462218618?l=biomime.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biomime.blogspot.com/feeds/3553322129462218618/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1069467794206617140&amp;postID=3553322129462218618' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/3553322129462218618'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/3553322129462218618'/><link rel='alternate' type='text/html' href='http://biomime.blogspot.com/2008/05/bash-profile-not-bashrc.html' title='Bash Profile, not BashRC'/><author><name>Jeremy Rice</name><uri>http://www.blogger.com/profile/12256074521855601742</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-wV3OV11Fp0k/TxhzaIa4zSI/AAAAAAAAPXQ/GY4PplLad-I/s220/AllSpiritualLike.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1069467794206617140.post-2001081700739888035</id><published>2008-05-06T20:29:00.001-07:00</published><updated>2008-05-06T20:29:17.653-07:00</updated><title type='text'>gVIM</title><content type='html'>I&amp;#39;ve spent the past couple of days setting up my Mac for Rails development. I&amp;#39;m still running Tiger, which is problematic (to say the least)... I hear that Leopard is all set up correctly, but I&amp;#39;m stuck for the time being.&lt;br&gt; &lt;br&gt;I finally gave up on Aptana, which was just screwing up left and right.&amp;nbsp; ...This means that I need to fall back to my old friend, Vim.&amp;nbsp; &lt;br&gt;&lt;br&gt;There&amp;#39;s a &lt;a href="http://macvim.org/OSX/files/gvim"&gt;script&lt;/a&gt; for calling gvim from a terminal, but I also wanted to change the color scheme on load (because my terminal is dark-on-light and my .vimrc colors are customized for that).&amp;nbsp; To accomplish this, add to your .gvimrc:&lt;br&gt; &lt;br&gt;&lt;div style="margin-left: 40px;"&gt;&lt;font face="courier new,monospace"&gt;colorscheme desert&lt;br&gt;&lt;br&gt;&lt;/font&gt;&lt;/div&gt;&lt;font face="arial,sans-serif"&gt;(Or whatever other scheme you care for.)&lt;br&gt;&lt;br&gt;This was surprisingly difficult to find (&lt;i&gt;why?!?&lt;/i&gt;), so... I hope you stumbled on this page before too much extra work.&amp;nbsp; ; )&lt;br&gt; &lt;/font&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1069467794206617140-2001081700739888035?l=biomime.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biomime.blogspot.com/feeds/2001081700739888035/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1069467794206617140&amp;postID=2001081700739888035' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/2001081700739888035'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/2001081700739888035'/><link rel='alternate' type='text/html' href='http://biomime.blogspot.com/2008/05/gvim.html' title='gVIM'/><author><name>Jeremy Rice</name><uri>http://www.blogger.com/profile/12256074521855601742</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-wV3OV11Fp0k/TxhzaIa4zSI/AAAAAAAAPXQ/GY4PplLad-I/s220/AllSpiritualLike.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1069467794206617140.post-4136076270755806359</id><published>2008-04-29T14:16:00.001-07:00</published><updated>2008-04-29T14:16:17.642-07:00</updated><title type='text'>Vim and Windows</title><content type='html'>This is just a note for those who are searching the web...&lt;br&gt;&lt;br&gt;So, today I was on someone else&amp;#39;s machine, and noticed he used &amp;quot;File -&amp;gt; Open&amp;quot; from gVim... and I never do that!&amp;nbsp; I just right-click and say &amp;quot;open with vim&amp;quot;.&lt;br&gt; &lt;br&gt;&amp;quot;Well,&amp;quot; he explained, &amp;quot;when the file I&amp;#39;m opening is on the network, I don&amp;#39;t get my _vimrc loaded&amp;quot;.&lt;br&gt;&lt;br&gt;This has never happened to me on my machine, so we looked into it.&amp;nbsp; Turns out that gVim loads _vimrc from your %HOME% environment variable, but it does so from whatever &lt;i&gt;drive&lt;/i&gt; your file is in.&amp;nbsp; My %HOME% was specific about C:\, and his--actually just a reference to %HOMEPATH%--had no drive designation.&amp;nbsp; When we added it, all was well.&lt;br&gt; &lt;br&gt;The error message we were getting only came up when you &lt;i&gt;quit &lt;/i&gt;gVim, and was something along the lines of &amp;quot;can&amp;#39;t write _vimrc&amp;quot; or some-such.&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1069467794206617140-4136076270755806359?l=biomime.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biomime.blogspot.com/feeds/4136076270755806359/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1069467794206617140&amp;postID=4136076270755806359' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/4136076270755806359'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/4136076270755806359'/><link rel='alternate' type='text/html' href='http://biomime.blogspot.com/2008/04/vim-and-windows.html' title='Vim and Windows'/><author><name>Jeremy Rice</name><uri>http://www.blogger.com/profile/12256074521855601742</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-wV3OV11Fp0k/TxhzaIa4zSI/AAAAAAAAPXQ/GY4PplLad-I/s220/AllSpiritualLike.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1069467794206617140.post-894530236704559024</id><published>2008-04-29T07:05:00.001-07:00</published><updated>2008-04-29T07:05:06.981-07:00</updated><title type='text'>Web Developers, PLEASE USE DATES</title><content type='html'>If I could teach the world of web development &lt;i&gt;one&lt;/i&gt; thing, it would be &lt;b&gt;have a date on every relevant page.&lt;/b&gt;&lt;br&gt;&lt;br&gt;Whether you like to admit it or not, someday your page is going to go stale, and the visitor &lt;i&gt;needs&lt;/i&gt; some indication of this.&amp;nbsp; I can&amp;#39;t tell you how many times a month I&amp;#39;m at a site, find some interesting information, and later find out that it&amp;#39;s totally useless because the page it came from is three years old.&lt;br&gt; &lt;br&gt;Date &lt;i&gt;everything&lt;/i&gt;.&lt;br&gt;&lt;br&gt;...If you could teach webdevs one thing, what would it be?&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1069467794206617140-894530236704559024?l=biomime.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biomime.blogspot.com/feeds/894530236704559024/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1069467794206617140&amp;postID=894530236704559024' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/894530236704559024'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/894530236704559024'/><link rel='alternate' type='text/html' href='http://biomime.blogspot.com/2008/04/web-developers-please-use-dates.html' title='Web Developers, PLEASE USE DATES'/><author><name>Jeremy Rice</name><uri>http://www.blogger.com/profile/12256074521855601742</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-wV3OV11Fp0k/TxhzaIa4zSI/AAAAAAAAPXQ/GY4PplLad-I/s220/AllSpiritualLike.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1069467794206617140.post-7144415008032649333</id><published>2008-04-17T08:26:00.001-07:00</published><updated>2008-04-17T08:26:10.312-07:00</updated><title type='text'>Seeing Red (or Not)</title><content type='html'>It&amp;#39;s always interesting to have one&amp;#39;s beliefs paddled over the head by science.&lt;br&gt;&lt;br&gt;Today I learned that &lt;a href="http://www.imt.liu.se/edu/courses/TBMT36/pdf/blue.pdf"&gt;our blood is &lt;i&gt;not&lt;/i&gt; blue&lt;/a&gt;, even when deoxygenated [&lt;a href="http://scienceblogs.com/scientificactivist/"&gt;via&lt;/a&gt;, &lt;a href="http://skepchick.org/blog/?p=1297"&gt;via&lt;/a&gt;].&amp;nbsp; Who&amp;#39;d&amp;#39;a thunk?!?&lt;br&gt; &lt;br&gt;In short, it turns out that our venous blood is actually deep maroon... ie, not much different from arterial blood.&amp;nbsp; When vessels are close to the surface of our skin, we see the red.&amp;nbsp; ...Which is why pale folk like me look vaguely pink.&amp;nbsp; But as the vessels get deeper (to about .5 mm), some measure of absorbing and reflecting of light takes place, and you end up with a purple color.&amp;nbsp; Thus, when compared to the pink of your skin, our eyes interpret that purple as blue.&lt;br&gt; &lt;br&gt;Whacky!&amp;nbsp; ...And humbling.&amp;nbsp; There are still too many urban myths that I believe, even if I have become increasingly skeptical over the years.&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1069467794206617140-7144415008032649333?l=biomime.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biomime.blogspot.com/feeds/7144415008032649333/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1069467794206617140&amp;postID=7144415008032649333' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/7144415008032649333'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/7144415008032649333'/><link rel='alternate' type='text/html' href='http://biomime.blogspot.com/2008/04/seeing-red-or-not.html' title='Seeing Red (or Not)'/><author><name>Jeremy Rice</name><uri>http://www.blogger.com/profile/12256074521855601742</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-wV3OV11Fp0k/TxhzaIa4zSI/AAAAAAAAPXQ/GY4PplLad-I/s220/AllSpiritualLike.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1069467794206617140.post-6976307442116669325</id><published>2008-04-14T19:54:00.001-07:00</published><updated>2008-04-14T20:13:09.775-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='biomimicry'/><title type='text'>Design Ideas from Nature</title><content type='html'>Tonight I watched a series of videos on TED.  &lt;a href="http://www.ted.com/index.php/talks/view/id/195"&gt;One&lt;/a&gt; in particular got me thinking about how code should have more responsibility on a smaller level (the idea of the sticky foot doing everything it needs to on its own), and how failover might work (the idea of the leg acting as "foot" as needed).&lt;br /&gt;&lt;br /&gt;Janine Benyus is not the most engaging public speaker, but it might be worth watching her &lt;a href="http://www.ted.com/index.php/talks/view/id/18"&gt;speech&lt;/a&gt; as well, since there are some really huge ideas in there that could be applied to software.  Lots of ideas of self-assembly... could data "flow" over code that captured the bits that belong there?  Is this kind of what mapreduce is doing?&lt;br /&gt;&lt;br /&gt;And this one is still one of my favorites... but that's more eye-candy than biomimicry:&lt;br /&gt;&lt;br /&gt;&lt;a style="left: 0px ! important; top: 0px ! important;" title="Click here to block this object with Adblock Plus" class="abp-objtab-05105729042036146 visible ontop" href="http://static.videoegg.com/ted/flash/loader.swf"&gt;&lt;/a&gt;&lt;object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" id="VE_Player" align="middle" height="285" width="432"&gt;&lt;param name="movie" value="http://static.videoegg.com/ted/flash/loader.swf"&gt;&lt;param name="FlashVars" value="bgColor=FFFFFF&amp;amp;file=http://static.videoegg.com/ted/movies/DAVIDGALLO-2007_high.flv&amp;amp;autoPlay=false&amp;amp;fullscreenURL=http://static.videoegg.com/ted/flash/fullscreen.html&amp;amp;forcePlay=false&amp;amp;logo=&amp;amp;allowFullscreen=true"&gt;&lt;param name="quality" value="high"&gt;&lt;param name="allowScriptAccess" value="always"&gt;&lt;param name="bgcolor" value="#FFFFFF"&gt;&lt;param name="scale" value="noscale"&gt;&lt;param name="wmode" value="window"&gt;&lt;embed src="http://static.videoegg.com/ted/flash/loader.swf" flashvars="bgColor=FFFFFF&amp;amp;file=http://static.videoegg.com/ted/movies/DAVIDGALLO-2007_high.flv&amp;amp;autoPlay=false&amp;amp;fullscreenURL=http://static.videoegg.com/ted/flash/fullscreen.html&amp;amp;forcePlay=false&amp;amp;logo=&amp;amp;allowFullscreen=true" quality="high" allowscriptaccess="always" bgcolor="#FFFFFF" scale="noscale" wmode="window" name="VE_Player" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" align="middle" height="285" width="432"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1069467794206617140-6976307442116669325?l=biomime.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biomime.blogspot.com/feeds/6976307442116669325/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1069467794206617140&amp;postID=6976307442116669325' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/6976307442116669325'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/6976307442116669325'/><link rel='alternate' type='text/html' href='http://biomime.blogspot.com/2008/04/design-ideas-from-nature.html' title='Design Ideas from Nature'/><author><name>Jeremy Rice</name><uri>http://www.blogger.com/profile/12256074521855601742</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-wV3OV11Fp0k/TxhzaIa4zSI/AAAAAAAAPXQ/GY4PplLad-I/s220/AllSpiritualLike.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1069467794206617140.post-3002913382659341021</id><published>2008-04-14T19:28:00.000-07:00</published><updated>2008-04-14T19:44:17.275-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='tiger'/><category scheme='http://www.blogger.com/atom/ns#' term='gems'/><category scheme='http://www.blogger.com/atom/ns#' term='setup'/><title type='text'>Getting Ruby to Run on Tiger (as if you haven't heard that before)</title><content type='html'>Today I had the [ahem] &lt;span class="Apple-style-span" style="font-style: italic;"&gt;pleasure&lt;/span&gt; of getting ruby to run in Tiger.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I had been using Locomotive... but that appears to be terribly out-of-date (May 2007).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I had hopes that &lt;a href="http://wearesakuzaku.com/goodie_basket/os_x_rails_auto_installation_pak"&gt;sakuzaku's script&lt;/a&gt; would do the trick... but it failed in several places. Afterwards, nothing worked.  Honestly, I wasn't paying very close attention to it as it ran, and didn't crack it open to see what was going on... but that was my starting point.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I think the basic problem was that I had two other installations of ruby: one in &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;/sw/bin/ruby&lt;/span&gt;, and the second in &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;/usr/bin/ruby&lt;/span&gt;.  ...So, after the script failed, I went and nuked those two executables and made them symlinks to &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;/usr/local/bin/ruby&lt;/span&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;But my gems were still miffed (I was trying to write a very, very simple script to go grab some XML from a web-app, and I was parsing it with hpricot).  That turned out to be an easy fix:&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;export PATH=$GEM_HOME/bin:$PATH&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;export RUBYOPT=rubygems&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;export RUBYLIB=$GEM_HOME/lib/ruby/site_ruby/1.8/&lt;/span&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;(clearly, this is in bash) ...And that did the trick.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Yes, yes, I know: I need to upgrade to Leopard.  But I'm running on a G5, and I've heard the performance hit is considerable... so I'm dragging my feet.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1069467794206617140-3002913382659341021?l=biomime.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://biomime.blogspot.com/feeds/3002913382659341021/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1069467794206617140&amp;postID=3002913382659341021' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/3002913382659341021'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1069467794206617140/posts/default/3002913382659341021'/><link rel='alternate' type='text/html' href='http://biomime.blogspot.com/2008/04/getting-ruby-to-run-on-tiger-as-if-you.html' title='Getting Ruby to Run on Tiger (as if you haven&apos;t heard that before)'/><author><name>Jeremy Rice</name><uri>http://www.blogger.com/profile/12256074521855601742</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-wV3OV11Fp0k/TxhzaIa4zSI/AAAAAAAAPXQ/GY4PplLad-I/s220/AllSpiritualLike.jpg'/></author><thr:total>0</thr:total></entry></feed>
