<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Technology Musings</title>
    <link>http://www.bartlettpublishing.com/site/bartpub/blog/3</link>
    <description></description>
    <language>en-us</language>
    <item>
      <title>Super Fuzzy Searching on PostgreSQL</title>
      <description>&lt;p&gt;I have been working on doing some fuzzy searching on PostgreSQL for a while, and thought I'd share some of my experiences here.&amp;nbsp; Many people are not yet aware of the incredible fuzzy search capabilities of PostgreSQL, especially that were added in the 9.1 release.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Most people use an external engine such as Lucene to do fuzzy searches.&amp;nbsp; While, as you will see, there are still reasons to do so, they are much fewer now than they used to be.&lt;/p&gt;
&lt;h4&gt;Fuzzy Search Using Trigrams&lt;/h4&gt;
&lt;p&gt;While PostgreSQL has lots of different fuzzy search options (soundex, levenshtein, etc.), the one which has the most support is trigram searching.&amp;nbsp; What is a trigram?&amp;nbsp; Trigrams break a word up into 3-letter sequences, which can then be used to do similarity matches.&amp;nbsp; Think of the word &quot;hello&quot;.&amp;nbsp; It has the following trigrams: &quot;h&quot;, &quot;he&quot;, &quot;hel&quot;, &quot;ell&quot;, &quot;llo&quot;, &quot;lo&quot;, and &quot;o&quot;.&amp;nbsp; Now look at the word &quot;hallo&quot;.&amp;nbsp; It has the following trigrams: &quot;h&quot;, &quot;ha&quot;, &quot;hal&quot;, &quot;all&quot;, &quot;llo&quot;, &quot;lo&quot;, and &quot;o&quot;.&amp;nbsp; You can see that there are several trigrams that match, and several that don't match.&amp;nbsp; Similarity is computed via &lt;a href=&quot;http://en.wikipedia.org/wiki/Cosine_similarity&quot; target=&quot;_blank&quot;&gt;cosine similarity&lt;/a&gt; (which I don't totally understand), but, basically, the more trigrams you have in common the closer the match.&amp;nbsp; In the present case, 'hallo' and 'hello' have a similarity of 0.333333.&amp;nbsp; You can see this in PostgreSQL by saying:&lt;/p&gt;
&lt;pre&gt;select similarity('hello', 'hallo')&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;PostgreSQL also has two other relevant operators that use similarity - the &quot;&amp;lt;-&amp;gt;&quot; operator and the &quot;%&quot; operator.&amp;nbsp; &quot;&amp;lt;-&amp;gt;&quot; is the &quot;distance&quot; operator, which is simply one minus the similarity (i.e. if the similarity is 0.2 the distance will be 0.8).&amp;nbsp; For text searching, &quot;%&quot; is the &quot;similar&quot; operator, which returns true if two strings are similar, or false if they are not.&amp;nbsp; Two strings are defined as &quot;similar&quot; if their similarity is 0.3 or greater.&amp;nbsp; This can be set with set_limit(), but it is not usually useful to do so (we will deal with custom similarities later).&amp;nbsp; The &quot;%&quot; operator is important, because of its heavy use in indexing.&lt;/p&gt;
&lt;h4&gt;Installing Trigrams&lt;/h4&gt;
&lt;p&gt;The trigram module (&lt;a href=&quot;http://www.postgresql.org/docs/9.1/interactive/pgtrgm.html&quot; target=&quot;_blank&quot;&gt;pg_trgm&lt;/a&gt;) is not installed by default in PostgreSQL, but is one of their standard (and supported!) extensions.&amp;nbsp; To install, you need to make sure you build the module in the source code.&amp;nbsp; To do this, go into the contrib/pg_trgm directory of the source code and do a &quot;make; make install&quot;.&amp;nbsp; This will install the plugin, but will not activate it.&amp;nbsp; Then, in any database you want to use this plugin, put in the command:&lt;/p&gt;
&lt;pre&gt;CREATE EXTENSION pg_trgm;&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;This will load the necessary SQL to install the functions and operators needed to make trigrams work.&amp;nbsp; If you type that command in the template1 database, then all future databases created on that system will have the extension installed.&lt;/p&gt;
&lt;h4&gt;Using Trigrams Without an Index&lt;/h4&gt;
&lt;p&gt;The simplest use of trigrams would be to have a table with a name column, and do a search like this:&lt;/p&gt;
&lt;pre&gt;SELECT * FROM people WHERE lastname % 'Schmoe'&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;This will return a list of people where the trigram similarity is greater than the default threshold.&amp;nbsp; If you want to specify the similarity you are looking for, you can change that to:&lt;/p&gt;
&lt;pre&gt;SELECT * FROM people WHERE similarity(lastname, 'Schmoe') &amp;gt; 0.5&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;This will give a less-tolerant match than the default.&lt;/p&gt;
&lt;p&gt;The problem with doing this is that it takes a lot of processing power.&amp;nbsp; The reason people usually use databases is because they have a huge number of records and need to be able to search them quickly.&amp;nbsp; If we have 10,000 records, manually doing trigram matches will take quite a bit of time.&lt;/p&gt;
&lt;p&gt;So, one of the best features of PostgreSQL 9.1 is the ability for PostgreSQL to incorporate trigrams into an index.&amp;nbsp; So, to make an index to speed up our search, do:&lt;/p&gt;
&lt;pre&gt;CREATE INDEX people_lastname_trigram_idx ON people USING gist(lastname gist_trgm_ops);&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;This will create a &quot;gist&quot; index, which is a special type of index which is often used in spacial and other vector-oriented matching.&amp;nbsp; The &quot;gist_trgm_ops&quot; is a little bit of magic that tells gist how to use a text field as a vector of trigrams.&lt;/p&gt;
&lt;p&gt;Now, your query will use the index, provided you have enough rows to make it worthwhile.&amp;nbsp; HOWEVER, it is not yet using the index efficiently.&amp;nbsp; While PostgreSQL &lt;em&gt;can&lt;/em&gt; (and will) use the index for this query, it doesn't actually check the condition until a later step (I believe, but am not sure, that it is using the index to get everything in the right order, and then at a later stage doing filtering).&amp;nbsp; For large tables, this can still be several orders of magnitude worse than you want.&amp;nbsp; To fix this, you MUST use the &quot;%&quot; operator.&amp;nbsp; This will cause the index to have an &quot;index condition&quot;, which it will use to limit the results that it puts out.&amp;nbsp; So, if you have:&lt;/p&gt;
&lt;pre&gt;SELECT * FROM people WHERE lastname % 'Schmoe';&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;This will use the index AND the index condition, and will be super-fast (except in extremely large datasets - see next section).&amp;nbsp; However, this uses the built-in cutoff point of 0.3 similarity.&amp;nbsp; What if I want my results to be tighter than that?&amp;nbsp; The best way is to combine % with similarity(), like this:&lt;/p&gt;
&lt;pre&gt;SELECT * FROM people WHERE lastname % 'Schmoe' AND similarity(lastname, 'Schmoe') &amp;gt; 0.5;&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;In this case, the database will use the &quot;%&quot; condition for the index, which will be incredibly fast, and the &quot;similarity()&quot; call as a post-index filter, which, since there is a much smaller dataset, will still be pretty fast.&lt;/p&gt;
&lt;h4&gt;Working With Larger Datasets&lt;/h4&gt;
&lt;p&gt;I had trouble working with trigrams because my main dataset is about 14 million titles.&amp;nbsp; At this size, trigram searching is really slow.&amp;nbsp; With the whole database loaded in-memory (either in PG's cache or in the filesystem cache - I have many, many gigs of memory), a trigram search of the database &lt;em&gt;USING THE INDEX&lt;/em&gt; took between 3 and 12 seconds, depending on the string.&amp;nbsp; Poking around, I came out with the following basic results for a database on an Amazon EC2 4XL instance without any other load:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;100,000 records: 40 milliseconds&lt;/li&gt;
&lt;li&gt;1,000,000 records: 0.4 seconds&lt;/li&gt;
&lt;li&gt;14,000,000 records: 7 seconds&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So, as you can see, the useful limit to these queries is about 1 million records.&amp;nbsp; Therefore, if you have more than 14 million rows, if you want to do trigrams, you need to find a way to boost performance.&amp;nbsp; I've found there are two basic methods you can use to speed up trigrams on large datasets:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create specialized indexes with subsets of your data&lt;/li&gt;
&lt;li&gt;Create a separate wordlist table with unique words&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;#1 is much preferred if you can do it, because it is an entirely database-oriented method.&amp;nbsp; Basically, what I did, is I figured out that on my queries I only needed to trigram search on about 1 million of my 14 million records.&amp;nbsp; Therefore, I specialized the index by adding a &quot;WHERE&quot; clause to the index itself.&amp;nbsp; On my database, I have a &quot;type&quot; field, and I'm only searching certain types of records.&amp;nbsp; Therefore, I changed my index to the following:&lt;/p&gt;
&lt;pre&gt;CREATE INDEX people_lastname_restricted_trigram_idx ON people USING gist(lastname gist_trgm_ops) WHERE type IN ('my_type1', 'my_type2');&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;This meant that only about a million records were being stored in the index, which brought down my search time considerably.&amp;nbsp; Another search that I was doing was based on the person's &quot;popularity&quot;, in which case, I added another index for popularity being greater than 20.&amp;nbsp; This restricted the set down to about 100,000 records, which made it blazingly fast.&lt;/p&gt;
&lt;p&gt;The other alternative (#2) I mentioned is to create a separate table of words which is searched.&amp;nbsp; The idea is that while you may have 14 million records, there probably aren't 14 million words.&amp;nbsp; Therefore, you create a table using unique words from the database, and then add a trigram index on that.&amp;nbsp; The problem, though, is that this takes either (a) a lot of manual work, or (b) a lot of triggers, none of which is the way I like to administer databases.&amp;nbsp; Nonetheless, it can work if you are merely wanting to use trigrams to fuzzy-match individual words.&amp;nbsp; It can be especially helpful in conjunction with PostgreSQL's &lt;a href=&quot;http://www.postgresql.org/docs/9.1/interactive/textsearch.html&quot; target=&quot;_blank&quot;&gt;full-text search&lt;/a&gt; (previously known as tsearch2), which still operates blazingly-fast on 14 million records.&amp;nbsp; Fuzzy string matching on words can be combined with full-text search on records to present a powerful and fast method of searching.&amp;nbsp;&amp;nbsp; The wordlist can be fuzzy-matched to provide better hints at what words are in the fulltext.&lt;/p&gt;
&lt;p&gt;To create a wordlist, do something like this:&lt;/p&gt;
&lt;pre&gt;CREATE TABLE search_words (word text);&lt;br /&gt;CREATE INDEX search_words_word_trigram_idx ON search_words USING gist(word gist_trgm_ops);&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;Then, every time you need to regenerate your wordlist, do the following:&lt;/p&gt;
&lt;pre&gt;DELETE FROM search_words;&lt;br /&gt;INSERT INTO search_words (word) SELECT DISTINCT lower(word) FROM (SELECT unnest(regexp_split_to_array(lastname, E'\\\\W+')) AS word FROM people) words WHERE word IS NOT NULL AND length(word) &amp;gt; 3;&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;What that does is explode the lastname field out into words (in case a lastname is multi-word), where each word is its own record.&amp;nbsp; It also filters out excessively short words (optional).&amp;nbsp; It then inserts these into the search_words table, which has a trigram index.&amp;nbsp; So, now, if you want to fuzzy-match individual words, you can use the search_words table!&lt;/p&gt;
&lt;p&gt;Anyway, additional fun can be had by using unaccent to remove accents before all of this processing, or other fun to massage your data however you feel is best.&amp;nbsp; The important thing is that, for all but the most strenuous data sets, we can now keep all of the searching located within the database itself, managed by database tools, without having to rely on external search engines such as Lucene, which take time, management, machine power, and their own sets of headaches.&amp;nbsp; Lucene itself &lt;a href=&quot;http://www.nearinfinity.com/blogs/aaron_mccurry/what_happens_to_lucene_when.html&quot; target=&quot;_blank&quot;&gt;often has to be hand-rigged for large datasets even&lt;/a&gt;.&amp;nbsp; I am a big believer in pushing as much data work to the database as possible, and PostgreSQL keeps pushing the bar higher!&lt;/p&gt;</description>
      <author>JB</author>
      <pubDate>Thu, 12 Jan 2012 16:58:00 +0000</pubDate>
      <link>http://www.bartlettpublishing.com/site/bartpub/blog/3/entry/350</link>
      <guid>http://www.bartlettpublishing.com/site/bartpub/blog/3/entry/350</guid>
    </item>
    <item>
      <title>Enjoy Skyrim's Alchemy?  Check Out Nature's Own Alchemy System</title>
      <description>&lt;p&gt;If you have played The Elder Scrolls V: Skyrim, you have probably made use of their &quot;alchemy&quot; system. &amp;nbsp;What you may not have known is that this is based, in some degree, on the real-life practices of both ancient and modern herbalists, who combine herbs and herbal actions to produce desired effects on the body and the body's health. &amp;nbsp;&lt;/p&gt;
&lt;p&gt;If you are interested in learning more, you should check out &lt;a href=&quot;http://itunes.apple.com/app/the-herbalist/id489767701&quot; target=&quot;_blank&quot;&gt;The Herbalist&lt;/a&gt;, a new iPhone/iPad/iPod/iOS app which describes a number of herbs and the actions that herbalists use them for. &amp;nbsp;In addition, you can even search the herbal database by the action you are looking for or by the specific malady for which it is often used. &amp;nbsp;It also includes information on different ways of preparing herbs for usage in tinctures, oils, infusions, lotions, and other preparations.&lt;/p&gt;
&lt;p&gt;Anyway, if you enjoy Skyrim's alchemy, you'll love seeing how practicing herbalists make use of the same basic ideas.&lt;/p&gt;</description>
      <author>JB</author>
      <pubDate>Thu, 22 Dec 2011 23:55:00 +0000</pubDate>
      <link>http://www.bartlettpublishing.com/site/bartpub/blog/3/entry/349</link>
      <guid>http://www.bartlettpublishing.com/site/bartpub/blog/3/entry/349</guid>
    </item>
    <item>
      <title>Misc stuff I found out</title>
      <description>&lt;p&gt;Objective-C PostgreSQL stuff:&lt;/p&gt;
&lt;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://code.google.com/p/objectivepq/source/checkout&quot; target=&quot;_blank&quot;&gt;ObjectivePQ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.postgresqlformac.com/&quot; target=&quot;_blank&quot;&gt;PostgreSQL For Mac&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://code.google.com/p/postgres-kit/&quot; target=&quot;_blank&quot;&gt;Postgres-Kit&lt;/a&gt;&amp;nbsp;(includes a solution for embedding a PostgreSQL database *in* your app)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://sourceforge.net/projects/pgsqlcocoa/&quot; target=&quot;_blank&quot;&gt;pgsqlcocoa&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bitbucket.org/mka/baseten/wiki/Home&quot; target=&quot;_blank&quot;&gt;BaseTen&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;Misc:&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://code.google.com/p/entropydb/&quot; target=&quot;_blank&quot;&gt;EntropyDB&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.slideshare.net/guest9efd1a1/building-server-applications-using-objectivec-and-gnustep&quot; target=&quot;_blank&quot;&gt;Building Server Applications Using Objective-C and GNUstep&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://stackoverflow.com/questions/714100/os-detecting-makefile&quot; target=&quot;_blank&quot;&gt;How to detect the OS in a Makefile&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;Building a shared library on OSX: (see &lt;a href=&quot;http://www.finkproject.org/doc/porting/shared.php&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;):&lt;/div&gt;
&lt;/div&gt;
&lt;pre&gt;gcc -dynamiclib -install_name /usr/local/lib/libfoo.2.dylib &amp;nbsp;-compatibility_version 2.4 -current_version 2.4.5 -o libfoo.2.4.5.dylib source.o code.o&lt;/pre&gt;
&lt;p&gt;I have also seen the options&amp;nbsp;-undefined suppress -flat_namespace &lt;a href=&quot;http://stackoverflow.com/questions/3532589/how-to-build-a-dylib-from-several-o-in-mac-os-x-using-gcc&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Another &lt;a href=&quot;http://qin.laya.com/tech_coding_help/dylib_linking.html&quot; target=&quot;_blank&quot;&gt;dylib link&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://g4u0419c.houston.hp.com/en/B2355-90655/ch05s11.html&quot; target=&quot;_blank&quot;&gt;Caution mixing shared and archive libs&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Seth Godin - &lt;a href=&quot;http://sethgodin.typepad.com/seths_blog/2005/11/how_to_run_a_us.html&quot; target=&quot;_blank&quot;&gt;how to run a useless conference&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/p&gt;</description>
      <author>JB</author>
      <pubDate>Sun, 26 Jun 2011 19:56:00 +0000</pubDate>
      <link>http://www.bartlettpublishing.com/site/bartpub/blog/3/entry/342</link>
      <guid>http://www.bartlettpublishing.com/site/bartpub/blog/3/entry/342</guid>
    </item>
    <item>
      <title>Introducing Newm: An Objective-C Framework for Web Applications</title>
      <description>&lt;p&gt;I am working on starting a web application framework called &lt;a href=&quot;https://github.com/johnnyb/Newm&quot; target=&quot;_blank&quot;&gt;Newm&lt;/a&gt;. It is kind of like an Objective-C-on-Rails. &amp;nbsp;&lt;a href=&quot;https://github.com/johnnyb/Newm&quot; target=&quot;_blank&quot;&gt;Check it out&lt;/a&gt;!&lt;/p&gt;</description>
      <author>JB</author>
      <pubDate>Tue, 21 Jun 2011 11:48:00 +0000</pubDate>
      <link>http://www.bartlettpublishing.com/site/bartpub/blog/3/entry/341</link>
      <guid>http://www.bartlettpublishing.com/site/bartpub/blog/3/entry/341</guid>
    </item>
    <item>
      <title>Objective-C Hackery</title>
      <description>&lt;p&gt;Been working on several objective-c projects.&amp;nbsp; I love to get into the fun tricks you can do with languages and stuff.&amp;nbsp; Here's some interesting tidbits I found:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://stackoverflow.com/questions/25746/whats-the-difference-between-a-string-constant-and-a-string-literal&quot; target=&quot;_blank&quot;&gt;Global string constants versus string literals&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://developer.apple.com/library/ios/#DOCUMENTATION/Cocoa/Conceptual/CocoaFundamentals/AddingBehaviortoaCocoaProgram/AddingBehaviorCocoa.html&quot; target=&quot;_blank&quot;&gt;Cocoa fundamentals&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://developer.apple.com/library/ios/#DOCUMENTATION/Cocoa/Conceptual/Strings/introStrings.html#//apple_ref/doc/uid/10000035i&quot; target=&quot;_blank&quot;&gt;Cocoa string programming&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.geekhideout.com/urlcode.shtml&quot; target=&quot;_blank&quot;&gt;URLEncode/Decode in C&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.faqs.org/docs/Linux-HOWTO/Program-Library-HOWTO.html#INIT-AND-CLEANUP&quot; target=&quot;_blank&quot;&gt;How to write code that executes *BEFORE* main() is called&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.mentalcases.net/texts/security/TextSectionStudy.txt&quot; target=&quot;_blank&quot;&gt;A study of ELF .text sections&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.haible.de/bruno/documentation/ffcall/callback/callback.html&quot; target=&quot;_blank&quot;&gt;Closures in C?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://thirdcog.eu/pwcblocks/&quot; target=&quot;_blank&quot;&gt;Introduction to C Blocks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html#Common-Predefined-Macros&quot; target=&quot;_blank&quot;&gt;gcc predefined macros&lt;/a&gt; (__COUNTER__ is cool)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://stackoverflow.com/questions/992070/static-constructor-equivalent-in-objective-c&quot; target=&quot;_blank&quot;&gt;Class initialization in Objective C using +initialize&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://stackoverflow.com/questions/5012935/static-initializers-in-objective-c&quot; target=&quot;_blank&quot;&gt;Static initializers for heap-based objects?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://osmorphis.blogspot.com/2009/02/objective-c-initializer-patterns_2937.html&quot; target=&quot;_blank&quot;&gt;Objective C initializers important patterns&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ObjCRuntimeRef/Reference/reference.html&quot; target=&quot;_blank&quot;&gt;The Objective C runtime reference (always useful)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://stackoverflow.com/questions/4864866/c-c-with-gcc-statically-add-resource-files-to-executable-library&quot; target=&quot;_blank&quot;&gt;Add resources to binary (1)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://stackoverflow.com/questions/1997172/is-there-a-linux-equivalent-of-windows-resource-files&quot; target=&quot;_blank&quot;&gt;Add resources to binary (2)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://stackoverflow.com/questions/1656968/platform-independant-resource-management&quot; target=&quot;_blank&quot;&gt;Add resources to binary (3)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.linuxjournal.com/content/embedding-file-executable-aka-hello-world-version-5967&quot; target=&quot;_blank&quot;&gt;Add resources to binary (4)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <author>JB</author>
      <pubDate>Sat, 18 Jun 2011 17:55:00 +0000</pubDate>
      <link>http://www.bartlettpublishing.com/site/bartpub/blog/3/entry/340</link>
      <guid>http://www.bartlettpublishing.com/site/bartpub/blog/3/entry/340</guid>
    </item>
    <item>
      <title>Miscellaneous RFID Links</title>
      <description>&lt;p&gt;Learning RFID for a project I'm going to work on soon.&amp;nbsp; Here are some handy dandy links!&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://tenderlovemaking.com/2009/09/19/ruby-and-rfid-tags/&quot; target=&quot;_blank&quot;&gt;Using RFID tags with Ruby&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.libnfc.org/documentation/introduction&quot; target=&quot;_blank&quot;&gt;libnfc - free RFID reading library&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.smartlab.deusto.es/java-rfid/&quot; target=&quot;_blank&quot;&gt;Java-based RFID developer kit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Radio-frequency_identification&quot; target=&quot;_blank&quot;&gt;Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.rfid-in-china.com/products_702_1.html&quot; target=&quot;_blank&quot;&gt;Long-range RFID readers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.gaorfidassettracking.com/RFID_Asset_Tracking_Resources/rfid_understanding/&quot; target=&quot;_blank&quot;&gt;Other interesting stuff&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.iautomate.com/products/Wavetrend-L%252dRX201-Long-Range-RFID-Reader.html&quot; target=&quot;_blank&quot;&gt;Long-Range RFID reader with development kit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.aliexpress.com/product-fm/320979826-UHF-RFID-Long-Range-Reader-4-port--wholesalers.html&quot; target=&quot;_blank&quot;&gt;Another reader&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.rfid-in-china.com/2011-03-20/products_detail_2328.html&quot; target=&quot;_blank&quot;&gt;Another reader&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <author>JB</author>
      <pubDate>Tue, 07 Jun 2011 02:47:00 +0000</pubDate>
      <link>http://www.bartlettpublishing.com/site/bartpub/blog/3/entry/339</link>
      <guid>http://www.bartlettpublishing.com/site/bartpub/blog/3/entry/339</guid>
    </item>
    <item>
      <title>Ideas 2011-05-25</title>
      <description>&lt;p&gt;Had some thoughts today, thought I'd write them down:&lt;/p&gt;
&lt;p&gt;Been looking at Google refine.&amp;nbsp; Some of this is pretty obvious, but I'm thinking it would be pretty awesome to port this to use on a database backend.&amp;nbsp; Basically, do the transforms on the data in the database, and, if you want, it will serialize it back out to a new table, or replace the existing one.&lt;/p&gt;
&lt;p&gt;What would also be cool is a generalized report generator for Rails, possibly using AREL.&amp;nbsp; You could do security by defining mandatory filters for tables, limiting the tables/columns, and other things.&amp;nbsp; It could predict the time the report will take to run by using PostgreSQL's &quot;explain&quot; command.&lt;/p&gt;</description>
      <author>JB</author>
      <pubDate>Wed, 25 May 2011 19:18:00 +0000</pubDate>
      <link>http://www.bartlettpublishing.com/site/bartpub/blog/3/entry/337</link>
      <guid>http://www.bartlettpublishing.com/site/bartpub/blog/3/entry/337</guid>
    </item>
    <item>
      <title>Database Scaling with PostgreSQL</title>
      <description>&lt;p&gt;I've been digging around on various database scaling options for PostgreSQL. &amp;nbsp;Here's some interesting links I've stumbled upon:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://s3.amazonaws.com/lcp/porras/myfiles/ror_db_balancing.html&quot; target=&quot;_blank&quot;&gt;Runtime selection of databases&lt;/a&gt; (for selecting between readonly and readwrite databases)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.postgresql.org/docs/9.0/interactive/hot-standby.html&quot; target=&quot;_blank&quot;&gt;Hot standby in PostgreSQL&lt;/a&gt;&amp;nbsp;and &lt;a href=&quot;http://www.postgresql.org/docs/9.0/static/warm-standby.html&quot; target=&quot;_blank&quot;&gt;log-shipping/streaming&lt;/a&gt; (and&lt;a href=&quot;http://wiki.postgresql.org/wiki/Binary_Replication_Tutorial&quot; target=&quot;_blank&quot;&gt; a tutorial&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;A &lt;a href=&quot;https://github.com/technoweenie/masochism&quot;&gt;Rails mechanism for sending write requests to a separate server than read requests&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Sharding Links:
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://highscalability.com/unorthodox-approach-database-design-coming-shard&quot; target=&quot;_blank&quot;&gt;Introduction to sharding&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://tech.myemma.com/managing-sequences-sharded-environment/&quot; target=&quot;_blank&quot;&gt;Sequence Management with Postgres Sharding&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.postgresqlconference.org/content/practical-postgres-sharding-scaling-horizon&quot; target=&quot;_blank&quot;&gt;PostgreSQL sharding on Pandora&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://stackoverflow.com/questions/994882/what-is-a-good-way-to-horizontal-shard-in-postgresql&quot; target=&quot;_blank&quot;&gt;Interesting PostgreSQL partitioning features&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.postgresqlconference.org/sites/default/files/ScalingWithGridSQL.odp&quot; target=&quot;_blank&quot;&gt;GridSQL stuff&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.gluster.org/&quot; target=&quot;_blank&quot;&gt;Gluster&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <author>JB</author>
      <pubDate>Tue, 24 May 2011 02:35:00 +0000</pubDate>
      <link>http://www.bartlettpublishing.com/site/bartpub/blog/3/entry/336</link>
      <guid>http://www.bartlettpublishing.com/site/bartpub/blog/3/entry/336</guid>
    </item>
    <item>
      <title>Getting EC2 Instances to Talk to Each Other</title>
      <description>&lt;p&gt;I am getting started with EC2, and I noticed a problem - I was unable to get my instances to talk to each other - specifically, mounting an NFS drive.&amp;nbsp; After searching through my forums, I found my answer - I was using a custom Security Group.&lt;/p&gt;
&lt;p&gt;In the default security group, instances within that security group can talk freely to each other.&amp;nbsp; What is surprising is that the default mode for a custom security group is to prevent all communication between the instances.&amp;nbsp; Therefore, you have to add permissions for the security group to be able to receive incoming traffic from the security group itself.&amp;nbsp; In the &quot;host&quot; line, rather than put an IP address, you can put in a security group ID (i.e. sg-abc123), and then specify 0-65535 for the port range.&lt;/p&gt;
&lt;p&gt;Then, viola!&amp;nbsp; It works!&lt;/p&gt;</description>
      <author>JB</author>
      <pubDate>Mon, 23 May 2011 02:02:00 +0000</pubDate>
      <link>http://www.bartlettpublishing.com/site/bartpub/blog/3/entry/335</link>
      <guid>http://www.bartlettpublishing.com/site/bartpub/blog/3/entry/335</guid>
    </item>
    <item>
      <title>Blocks in Objective C</title>
      <description>&lt;p&gt;Blocks is a new feature of Objective C that was announced roughly at the same time as Apple announced Grand Central Dispatch.&amp;nbsp; I haven't had the time to look into it thoroughly, so I'm sticking my bookmarks here for future reference:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://overooped.com/post/174960131/the-one-objective-c-block-memory-management-example-you&quot; target=&quot;_blank&quot;&gt;The One Objective-C Block Memory Example You Need to Read&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://cocoawithlove.com/2009/10/how-blocks-are-implemented-and.html&quot; target=&quot;_blank&quot;&gt;How Blocks are Implemented (and the Consequences)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://thirdcog.eu/pwcblocks/&quot; target=&quot;_blank&quot;&gt;Programming with C Blocks&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <author>JB</author>
      <pubDate>Wed, 18 May 2011 18:51:00 +0000</pubDate>
      <link>http://www.bartlettpublishing.com/site/bartpub/blog/3/entry/332</link>
      <guid>http://www.bartlettpublishing.com/site/bartpub/blog/3/entry/332</guid>
    </item>
    <item>
      <title>Using Indexes on LIKE queries on PostgreSQL</title>
      <description>&lt;p&gt;Apparently, under some configurations (I think they are compile settings dealing with the locale), PostgreSQL will not, by default, use an index for LIKE queries.&amp;nbsp; First of all, note that PostgreSQL will NEVER use an index for an ILIKE query (case-insensitive like).&amp;nbsp; For that, you should use a functional index using the LOWER function.&amp;nbsp; It will also not use an index if the LIKE starts with a wildcard.&amp;nbsp; But, for queries that *end* in a wildcard, if you set it up right, you can get PostgreSQL to use an index.&lt;/p&gt;
&lt;p&gt;Anyway, apparently the problem is that PostgreSQL doesn't know what locale it is in, and therefore doesn't know how to order the characters.&amp;nbsp; Therefore, you have to give it some help.&amp;nbsp; After your index column, you need to add text_pattern_ops.&amp;nbsp; So, for my own table, I did the following:&lt;/p&gt;
&lt;p&gt;create index entity_lower_name_idx on entities(lower(name) text_pattern_ops)&lt;/p&gt;
&lt;p&gt;And viola!&amp;nbsp; Postgres is now using the index.&amp;nbsp; Since this is a functional index, it indexes queries like&lt;/p&gt;
&lt;p&gt;select * from entities where lower(name) like 'hello%'&lt;/p&gt;
&lt;p&gt;Hope that helps someone!&amp;nbsp; I received the information &lt;a href=&quot;http://archives.postgresql.org/pgsql-hackers/2008-02/msg01000.php&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt; and &lt;a href=&quot;http://www.postgresql.org/docs/8.4/static/indexes-opclass.html&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;</description>
      <author>JB</author>
      <pubDate>Wed, 11 May 2011 15:25:00 +0000</pubDate>
      <link>http://www.bartlettpublishing.com/site/bartpub/blog/3/entry/329</link>
      <guid>http://www.bartlettpublishing.com/site/bartpub/blog/3/entry/329</guid>
    </item>
    <item>
      <title>Making Reusable iPhone Widgets with Interface Builder</title>
      <description>&lt;p&gt;One annoying thing about Interface Builder, at least for the iPhone, is that there is not a direct way of making reusable widgets that are both made *in* Interface Builder and *for* Interface Builder.&amp;nbsp; I came up, though, with a set of instructions and helpers that make the process fairly painless.&amp;nbsp; The class is called IBView, and should be used as the parent class for your reusable widget.&lt;/p&gt;
&lt;p&gt;Here's how to create the widget:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create a class for your new widget, called MyWidget.&amp;nbsp; Inherit from the IBView class (code provided below).&amp;nbsp; Create all of the IBOutlets you want for your widget.&lt;/li&gt;
&lt;li&gt;Create a view &lt;strong&gt;with the same name&lt;/strong&gt; as your widget class in Interface Builder.&amp;nbsp; If your widget was named &quot;MyWidget.m&quot; then your interface should be called &quot;MyWidget.xib&quot;.&amp;nbsp; &lt;strong&gt;DO NOT&lt;/strong&gt; set the class of this view or any subview to be of the MyWidget (or whatever class you are create) type.&amp;nbsp; DO NOT do it.&lt;/li&gt;
&lt;li&gt;Set the &quot;File's Owner&quot; of your interface in Interface Builder to be the name of the class that you are creating - MyWidget in this case.&lt;/li&gt;
&lt;li&gt;Set up any connections you want between your IB view and File's Owner (i.e. your widget).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now, your widget is created.&amp;nbsp; You can now use the view in any IB panel by doing putting in a generic UIView, and setting the class name to your new class (MyWidget in this case).&lt;/p&gt;
&lt;p&gt;Important caveat - one consequence of creating the view in Interface Builder is that there will be an extra view between the main view represented by your class and the rest of the elements of your class.&amp;nbsp; Basically, your custom view acts as a generic view, and then *loads in* your Interface Builder file as a subview, meaning that the toplevel view in Interface Builder will sit under your MyWidget view.&amp;nbsp; This is usually unimportant if you are just using IBOutlet stuff, but if you do advanced view management, it would be important to know that a view sits between you and the rest of your sub-widgets.&lt;/p&gt;
&lt;p&gt;Okay, here is the code for IBView.m - just very simple code, with a tiny bit of Objective-C magic thrown in:&lt;/p&gt;
&lt;pre&gt;#import &quot;IBView.h&quot;&lt;br /&gt;&lt;br /&gt;@implementation IBView&lt;br /&gt;&lt;br /&gt;-(void) loadViewsFromBundle {&lt;br /&gt;	NSString *class_name = NSStringFromClass([self class]);&lt;br /&gt;	NSLog(@&quot;Loading bundle: %@&quot;, class_name);&lt;br /&gt;	UIView *mainSubView = [[[NSBundle mainBundle] loadNibNamed:class_name owner:self options:nil] lastObject];&lt;br /&gt;	[self addSubview:mainSubView];&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;-(id) initWithCoder:(NSCoder *)coder {&lt;br /&gt;	self = [super initWithCoder:coder];&lt;br /&gt;	if(self) {&lt;br /&gt;		[self loadViewsFromBundle];&lt;br /&gt;	}&lt;br /&gt;	return self;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;- (id)initWithFrame:(CGRect)frame {&lt;br /&gt;    self = [super initWithFrame:frame];&lt;br /&gt;    if (self) {&lt;br /&gt;		[self loadViewsFromBundle];&lt;br /&gt;        // Initialization code.&lt;br /&gt;    }&lt;br /&gt;    return self;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@end&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;And IBView.h is super-simple:&lt;/p&gt;
&lt;pre&gt;#import &amp;lt;UIKit/UIKit.h&amp;gt;&lt;br /&gt;@interface IBView : UIView {&lt;br /&gt;}&lt;br /&gt;@end&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;And that's all there is to it!&lt;/p&gt;</description>
      <author>JB</author>
      <pubDate>Thu, 05 May 2011 15:10:00 +0000</pubDate>
      <link>http://www.bartlettpublishing.com/site/bartpub/blog/3/entry/327</link>
      <guid>http://www.bartlettpublishing.com/site/bartpub/blog/3/entry/327</guid>
    </item>
    <item>
      <title>Readings around the Web</title>
      <description>&lt;p&gt;Here's a collection of links that I have open.&amp;nbsp; Just putting them here so I can close them :)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://aws-musings.com/how-to-expand-your-ebs-volume/&quot; target=&quot;_blank&quot;&gt;How to resize an EC2 EBS filesystem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://patodirahul.blogspot.com/2011/03/create-ami.html&quot; target=&quot;_blank&quot;&gt;Basic steps for creating an EC2 AMI&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://stackoverflow.com/questions/2331983/objective-c-class-string-like-nsarray-classname-nsarray&quot; target=&quot;_blank&quot;&gt;How to get the string name of a class from Objective C&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://iphonedevelopertips.com/cocoa/launching-your-own-application-via-a-custom-url-scheme.html&quot; target=&quot;_blank&quot;&gt;Registering a custom URL scheme on iPhone&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://applookup.com/&quot; target=&quot;_blank&quot;&gt;More iOS URL schemes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://stackoverflow.com/questions/4299403/how-to-handle-app-urls-in-a-uiwebview&quot; target=&quot;_blank&quot;&gt;Interesting discussion on handling URLs from UIWebViews&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://wiki.akosma.com/IPhone_URL_Schemes&quot; target=&quot;_blank&quot;&gt;Current iPhone URL Schemes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://stackoverflow.com/questions/2594321/how-to-launch-ibooks-e-reader-programmatically-on-ipad/2596002#2596002&quot; target=&quot;_blank&quot;&gt;Launch iBooks from iPad&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.w3.org/TR/offline-webapps/&quot; target=&quot;_blank&quot;&gt;HTML5 Offline Web Apps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://sixrevisions.com/web-development/html5-iphone-app/&quot; target=&quot;_blank&quot;&gt;HTML5 Offline Webapp Tutorial&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://diveintohtml5.org/storage.html&quot; target=&quot;_blank&quot;&gt;HTML5 Local Storage&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://us.blackberry.com/developers/choosingtargetos.jsp?IID=DEVTRG1222&quot; target=&quot;_blank&quot;&gt;Choosing Blackberry Targets&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://blackberry.sys-con.com/node/1643966&quot; target=&quot;_blank&quot;&gt;Blackberry-specific application caching&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://devblog.blackberry.com/2010/08/blackberry-html5/&quot; target=&quot;_blank&quot;&gt;HTML5 Blackberry Elements&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://blog.sourcebender.com/building-an-html5-application-part3.html&quot; target=&quot;_blank&quot;&gt;More HTML5 Offlien stuff&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <author>JB</author>
      <pubDate>Mon, 02 May 2011 04:19:00 +0000</pubDate>
      <link>http://www.bartlettpublishing.com/site/bartpub/blog/3/entry/325</link>
      <guid>http://www.bartlettpublishing.com/site/bartpub/blog/3/entry/325</guid>
    </item>
    <item>
      <title>Fixing Clicking Hard Drives</title>
      <description>&lt;p&gt;All right - my wife's computer died today. &amp;nbsp;It gave the Apple folder-with-a-question-mark sign which says it can't find the system software. &amp;nbsp;Booting from the install disk - I found out that it couldn't even find the drive.&lt;/p&gt;
&lt;p&gt;In addition to that, the hard drive was making clicking sounds when the computer first turned on.&lt;/p&gt;
&lt;p&gt;I was certain that the computer was fried.&lt;/p&gt;
&lt;p&gt;However, I dug through a bunch of forums. &amp;nbsp;Most of them agreed - if your hard drive makes a clicking noises, then it is probably dead. &amp;nbsp;I ran through all of Apple's troubleshooting steps - nothing. &amp;nbsp;It seemed that it was truly dead.&lt;/p&gt;
&lt;p&gt;Then, at the bottom of a &lt;a href=&quot;http://ocaoimh.ie/the-blinking-folder-and-question-mark-is-bad-right/&quot; target=&quot;_blank&quot;&gt;forum post&lt;/a&gt;, a poster named &quot;deepika&quot; gave an amazing piece of advice. &amp;nbsp;I thought it was a joke when I first read it. &amp;nbsp;But, since the hard drive was probably dead anyway, I felt it couldn't hurt. &amp;nbsp;The advice? &amp;nbsp;It seems that the drive is having trouble spinning up. &amp;nbsp;Therefore, you have to &quot;convince&quot; it to spin up. &amp;nbsp;How?&lt;/p&gt;
&lt;p&gt;&lt;ol&gt;
&lt;li&gt;Turn off the computer&lt;/li&gt;
&lt;li&gt;Put the computer on a flat surface&lt;/li&gt;
&lt;li&gt;Close the computer (it's a laptop)&lt;/li&gt;
&lt;li&gt;Bang on it a few times&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Seriously.&lt;/p&gt;
&lt;div&gt;And guess what? &amp;nbsp;When I turned on my wife's computer again - it worked!&lt;/div&gt;
&lt;/p&gt;</description>
      <author></author>
      <pubDate>Wed, 09 Feb 2011 17:10:00 +0000</pubDate>
      <link>http://www.bartlettpublishing.com/site/bartpub/blog/3/entry/319</link>
      <guid>http://www.bartlettpublishing.com/site/bartpub/blog/3/entry/319</guid>
    </item>
    <item>
      <title>Opening other apps from the iPhone</title>
      <description>&lt;p&gt;I was looking into how to open another app from the current app today, and came across these posts which look interesting:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://iphonedevelopertips.com/cocoa/launching-your-own-application-via-a-custom-url-scheme.html&quot; target=&quot;_blank&quot;&gt;How to create your own URL scheme so other apps can launch your apps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.iphonedevsdk.com/forum/iphone-sdk-development/37103-finding-out-what-apps-installed.html&quot; target=&quot;_blank&quot;&gt;Ways to find out what other apps are installed&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://stackoverflow.com/questions/3649201/how-to-know-the-apps-installed-in-iphone&quot; target=&quot;_blank&quot;&gt;Probably the best method for launching other apps, and determining if appropriate apps are installed&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://wiki.akosma.com/IPhone_URL_Schemes&quot; target=&quot;_blank&quot;&gt;A partial list of apps which support iPhone URL schemes&lt;/a&gt;&amp;nbsp;(another one &lt;a href=&quot;http://applookup.com/&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://developer.apple.com/library/ios/#documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/StandardBehaviors/StandardBehaviors.html%23//apple_ref/doc/uid/TP40007072-CH4-SW7&quot; target=&quot;_blank&quot;&gt;Apple's documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;Anyway, an interesting list for anyone trying to do this.&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <author>JB</author>
      <pubDate>Fri, 10 Dec 2010 22:27:00 +0000</pubDate>
      <link>http://www.bartlettpublishing.com/site/bartpub/blog/3/entry/315</link>
      <guid>http://www.bartlettpublishing.com/site/bartpub/blog/3/entry/315</guid>
    </item>
    <item>
      <title>Bundler is Evil</title>
      <description>&lt;p&gt;If anyone is thinking about using the Bundler plugin for ruby-on-rails for *any* reason, DON'T!!!!!!!!!&lt;/p&gt;
&lt;p&gt;I have lost probably 5-6 hours just messing around with bundler trying to get it to work consistently. &amp;nbsp;Unfortunately, a fairly decent library, formtastic, requires it, for some reason I really don't understand. &amp;nbsp;Anyway, I've lost hours of sleep and work time trying to mess with bundler. &amp;nbsp;So, for all of you wondering if this will be worthwhile - beware!!! &amp;nbsp;It just eats up your time and sanity with no real payoff.&lt;/p&gt;
&lt;p&gt;It is especially evil if you are trying to manage dependencies for the same app running on multiple boxes, which, in theory, that's the problem it is trying to solve.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TO UNINSTALL BUNDLER&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Amazingly, there is NOTHING AT ALL in the documentation to tell you how to uninstall bundler. &amp;nbsp;How nice. &amp;nbsp;&lt;/p&gt;
&lt;p&gt;Here's what I found out:&lt;/p&gt;
&lt;p&gt;1) Remove config/preinitializer.rb&lt;/p&gt;
&lt;p&gt;2) Bundler adds a function at the bottom of config/boot.rb. &amp;nbsp;It looks something like this:&lt;/p&gt;
&lt;pre&gt;class Rails::Boot
  def run
    load_initializer

    Rails::Initializer.class_eval do
      def load_gems
        @bundler_loaded ||= Bundler.require :default, Rails.env
      end
    end

    Rails::Initializer.run(:set_load_path)
  end
end&lt;/pre&gt;
&lt;p&gt;Get rid of that function. &amp;nbsp;&lt;/p&gt;
&lt;p&gt;3) Bundler should now be gone! &amp;nbsp;You can remove the gem, now, too. &amp;nbsp;I'll let you know if I find any other vestiges of bundler laying around.&lt;/p&gt;
&lt;p&gt;And, it looks like formtastic still works after you remove bundler. &amp;nbsp;So if you must use formtastic, maybe you should use bundler to install it, and then remove bundler to use it.&lt;/p&gt;</description>
      <author>JB</author>
      <pubDate>Mon, 06 Dec 2010 19:55:00 +0000</pubDate>
      <link>http://www.bartlettpublishing.com/site/bartpub/blog/3/entry/314</link>
      <guid>http://www.bartlettpublishing.com/site/bartpub/blog/3/entry/314</guid>
    </item>
    <item>
      <title>Model Rocket Stuff</title>
      <description>&lt;p&gt;Playing around with model rockets this week. &amp;nbsp;I found that you could use crepe paper (or even cellulose wall insulation) for recovery wadding, and that loctite at walmart was a decent substitute for plastic cement. &amp;nbsp;There's also a link to make your own fire-resistant wadding &lt;a href=&quot;http://www.instructables.com/id/Model-rocket-recovery-wadding/&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;, but it looks like you have to pay for the content.&lt;/p&gt;
&lt;p&gt;Also, while looking around, I found that someone even came up with &lt;a href=&quot;http://www.rusticgirls.com/fun/model-rocket-engines.html&quot; target=&quot;_blank&quot;&gt;a method of making homemade engines&lt;/a&gt;&amp;nbsp;(also other sites&amp;nbsp;&lt;a href=&quot;http://shadow.yak.net/125&quot;&gt;here&lt;/a&gt;, &lt;a href=&quot;http://www.ehow.com/how_4929615_rocket-fuel-out-of-sugar.html&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;,&amp;nbsp;and &lt;a href=&quot;http://www.skylighter.com/skylighter_info_pages/article.asp?Item=141&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;&amp;nbsp;- that last link also has info on homemade fireworks)! &amp;nbsp; That's pretty cool, but I don't think I'm ready for it yet. &amp;nbsp;Also a link for &lt;a href=&quot;http://makeprojects.com/Project/Make-your-own-model-rocket-igniters/386/1&quot; target=&quot;_blank&quot;&gt;homemade igniters&lt;/a&gt;. &amp;nbsp;&lt;/p&gt;
&lt;p&gt;Anyway, I think the only part of that I'm brave enough to try is using crepe paper for recovery wadding, but the rest sure is interesting!&lt;/p&gt;</description>
      <author>JB</author>
      <pubDate>Fri, 03 Dec 2010 16:25:00 +0000</pubDate>
      <link>http://www.bartlettpublishing.com/site/bartpub/blog/3/entry/313</link>
      <guid>http://www.bartlettpublishing.com/site/bartpub/blog/3/entry/313</guid>
    </item>
    <item>
      <title>When XCode Won't Symbolicate your Crash Log</title>
      <description>&lt;p&gt;On the iPhone, when you get crash logs, XCode is supposed to automatically look up symbols for you.&amp;nbsp; Sometimes, it doesn't.&amp;nbsp; Just had a crash report from the app store.&amp;nbsp; Loaded it up in the XCode organizer, and... nothing.&amp;nbsp; Zilch.&amp;nbsp; A lot of posts on the internet talked about &quot;atos&quot; but I just kept on getting the error:&lt;/p&gt;
&lt;pre&gt;atos cannot load symbols for the file&lt;/pre&gt;
&lt;p&gt;So, thankfully, I found this page on &lt;a href=&quot;http://www.picsoftware.ca/blog/?p=8&quot; target=&quot;_blank&quot;&gt;manually symbolicating your file&lt;/a&gt;.&amp;nbsp; Yay!&lt;/p&gt;
&lt;p&gt;Basically, you can just run gdb on your archived package, set some configs, and then do p/a on the addresses and it will give you the proper symbols, files, and line numbers.&amp;nbsp; Magic!&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/Developer/Platforms/iPhoneOS.platform/Developer/usr/libexec/gdb/gdb-arm-apple-darwin YOURFILE.app&lt;br /&gt;&lt;/code&gt;&lt;code&gt;set print asm-demangle on&lt;/code&gt;&lt;code&gt;&lt;br /&gt;set print symbol-filename on&lt;br /&gt;p/a 0x0whatever&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Thanks so much to PiC Software for pointing this out.&amp;nbsp; And, of course, yay to the gcc and gdb developers who never get the credit that they should.&lt;/p&gt;</description>
      <author></author>
      <pubDate>Wed, 06 Oct 2010 22:18:00 +0000</pubDate>
      <link>http://www.bartlettpublishing.com/site/bartpub/blog/3/entry/311</link>
      <guid>http://www.bartlettpublishing.com/site/bartpub/blog/3/entry/311</guid>
    </item>
    <item>
      <title>Why to Not Use Dreamhost for Important Sites</title>
      <description>&lt;p&gt;I host one of my sites on Dreamhost.&amp;nbsp; Dreamhost is very alluring, because of the number of features you get for almost no money at all.&amp;nbsp; The problem is, Dreamhost has the right to pull the rug out from under you with no warning.&lt;/p&gt;
&lt;p&gt;I had spent hours trying to get my rails app to work under Dreamhost.&amp;nbsp; I had frozen Rails, specified which version of Rack to use, and a number of other tweaks.&amp;nbsp; Then, today, I go there, and I get the dreaded &quot;Passenger Error&quot;.&amp;nbsp; I logged in, and tried to change some settings, and got nothing.&amp;nbsp; However, I noticed that the error message continued to display the same line numbers even though I had changed the file.&amp;nbsp; Wierd.&lt;/p&gt;
&lt;p&gt;So I keep messing with it, and even start deleting files.&amp;nbsp; The errors *still* pop up, no matter which files I delete - it keeps the same filenames and line numbers even though the files no longer exist.&amp;nbsp; I had assumed that it just wasn't restarting, and maybe it had cached the files.&amp;nbsp; So I went looking for a force-restart thingy on the Dreamhost panel.&lt;/p&gt;
&lt;p&gt;I didn't find one, but I found something else - Dreamhost had, without so much as an email saying so, moved me to a completely different server!&amp;nbsp; They left the files on the old server, but my domain was no longer pointed there.&amp;nbsp; Surprise!&amp;nbsp; I had been working on the wrong server altogether!&lt;/p&gt;
&lt;p&gt;So, once I logged into the correct server, I was able to delete my frozen version of Rails, and unset my Rack preferences, and all was well with the world.&amp;nbsp; But who in the world switches apps to a box with a different configuration without notifying the customer!&lt;/p&gt;
&lt;p&gt;If you want to know why you shouldn't buy webhosting for $5/month, this is it.&lt;/p&gt;
&lt;p&gt;I'll probably still keep my account, but I'll stick with only having very-low-profile domains there.&lt;/p&gt;</description>
      <author>JB</author>
      <pubDate>Wed, 29 Sep 2010 05:13:00 +0000</pubDate>
      <link>http://www.bartlettpublishing.com/site/bartpub/blog/3/entry/310</link>
      <guid>http://www.bartlettpublishing.com/site/bartpub/blog/3/entry/310</guid>
    </item>
    <item>
      <title>Change in Video Playback in iOS 4 (MPMoviePlayerController)</title>
      <description>&lt;p&gt;It seems that Apple has changed the way that it handles video playback in iOS 4. &amp;nbsp;In previous iPhone OS releases, you merely initialized the movie player instance and then hit play. &amp;nbsp;iOS 4 is slightly more complicated because it no longer presumes that all video playback will be fullscreen, or even that there will only be one video on the screen at a time. &amp;nbsp;So here is the code to get the old behavior:&amp;nbsp;&lt;/p&gt;
&lt;pre&gt;MPMoviePlayerController* thePlayer = [[MPMoviePlayerController alloc] initWithContentURL: [NSURL URLWithString: trailerURL]];
thePlayer.scalingMode = MPMovieScalingModeAspectFill;
thePlayer.view.frame = self.view.bounds;
[self.view addSubview: thePlayer.view];[thePlayer setFullscreen: YES animated: YES];
&lt;/pre&gt;
&lt;p&gt;Unfortunately, Apple still keeps its &lt;a href=&quot;http://developer.apple.com/iphone/library/DOCUMENTATION/Cocoa/Conceptual/LoadingResources/ImageSoundResources/ImageSoundResources.html&quot;&gt;old documentation&lt;/a&gt; around.  &lt;a href=&quot;http://developer.apple.com/library/ios/#DOCUMENTATION/MediaPlayer/Reference/MPMoviePlayerController_Class/MPMoviePlayerController/MPMoviePlayerController.html%23//apple_ref/occ/cl/MPMoviePlayerController&quot;&gt;Here are the updated docs&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I ran into this when I was updating an app from 3.0 to 4.0.  When you clicked on the button to play the video, rather than playing a video, nothing happened, and then a few seconds later only the audio would start playing.  I had listed in my code the URL for the docs from Apple which I had used, and verified that it was correct - I had no idea that the document itself was out-of-date!  It was quite a problem for me, and at first I thought it was a bug in my code.  Later I learned that Apple updated their API, but not all their docs.  Anyway, hope this helps someone.&lt;/p&gt;</description>
      <author>JB</author>
      <pubDate>Sat, 18 Sep 2010 00:52:00 +0000</pubDate>
      <link>http://www.bartlettpublishing.com/site/bartpub/blog/3/entry/308</link>
      <guid>http://www.bartlettpublishing.com/site/bartpub/blog/3/entry/308</guid>
    </item>
  </channel>
</rss>

