scrapes 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,61 @@
1
+ ################################################################################
2
+ #
3
+ # Copyright (C) 2006 Peter J Jones (pjones@pmade.com)
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining
6
+ # a copy of this software and associated documentation files (the
7
+ # "Software"), to deal in the Software without restriction, including
8
+ # without limitation the rights to use, copy, modify, merge, publish,
9
+ # distribute, sublicense, and/or sell copies of the Software, and to
10
+ # permit persons to whom the Software is furnished to do so, subject to
11
+ # the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be
14
+ # included in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ #
24
+ ###############################################################################
25
+ class LocalPagination < Scrapes::Page
26
+ paginated
27
+ acts_as_array(:links)
28
+
29
+ selector(:select_next_image) do |doc|
30
+ doc.search '//img'
31
+ end
32
+
33
+ extractor(:extract_next_link) do |element|
34
+ p = element.parent and p.name.downcase == 'a' and p.attributes['href'].match(/foil/)
35
+ p.attributes['href']
36
+ end
37
+
38
+ validates_presence_of(:next_link)
39
+ rule(:next_link, :select_next_image, :extract_next_link, 1)
40
+
41
+ selector(:select_llink) do |doc|
42
+ doc.search 'a[@href^="foil"]'
43
+ end
44
+
45
+ validates_presence_of(:llink)
46
+ rule(:llink, :select_llink, '@href')
47
+
48
+ def next_page
49
+ return nil if self.next_link == self.uri
50
+ self.next_link
51
+ end
52
+
53
+ def append_page (sister)
54
+ self.llink += sister.llink
55
+ end
56
+
57
+ def links
58
+ self.llink.sort.uniq
59
+ end
60
+ end
61
+ ###############################################################################
@@ -0,0 +1,38 @@
1
+ ################################################################################
2
+ #
3
+ # Copyright (C) 2006 Peter J Jones (pjones@pmade.com)
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining
6
+ # a copy of this software and associated documentation files (the
7
+ # "Software"), to deal in the Software without restriction, including
8
+ # without limitation the rights to use, copy, modify, merge, publish,
9
+ # distribute, sublicense, and/or sell copies of the Software, and to
10
+ # permit persons to whom the Software is furnished to do so, subject to
11
+ # the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be
14
+ # included in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ #
24
+ ###############################################################################
25
+ class Foils < Scrapes::Page
26
+ validates_presence_of :text_test
27
+ rule :text_test, 'body', 'text()'
28
+
29
+ validates_presence_of :texts_test
30
+ rule :texts_test, 'body', 'texts()'
31
+
32
+ validates_presence_of :content_test
33
+ rule :content_test, 'body', 'content()'
34
+
35
+ validates_presence_of :contents_test
36
+ rule :contents_test, 'body', 'contents()'
37
+ end
38
+ ###############################################################################
@@ -0,0 +1,36 @@
1
+ ################################################################################
2
+ #
3
+ # Copyright (C) 2006 Peter J Jones (pjones@pmade.com)
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining
6
+ # a copy of this software and associated documentation files (the
7
+ # "Software"), to deal in the Software without restriction, including
8
+ # without limitation the rights to use, copy, modify, merge, publish,
9
+ # distribute, sublicense, and/or sell copies of the Software, and to
10
+ # permit persons to whom the Software is furnished to do so, subject to
11
+ # the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be
14
+ # included in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ #
24
+ ################################################################################
25
+ class LocalRedhandedEntries < Scrapes::Page
26
+ acts_as_array :entries
27
+
28
+ class Entry < Scrapes::Page
29
+ rule_1 :entry_title, 'h2.entryTitle', 'text()'
30
+ validates_presence_of :entry_title
31
+ end
32
+
33
+ rule :entries, '.entry', Entry
34
+ validates_presence_of :entries
35
+ end
36
+ ################################################################################
@@ -0,0 +1,58 @@
1
+ ################################################################################
2
+ #
3
+ # Copyright (C) 2006 Peter J Jones (pjones@pmade.com)
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining
6
+ # a copy of this software and associated documentation files (the
7
+ # "Software"), to deal in the Software without restriction, including
8
+ # without limitation the rights to use, copy, modify, merge, publish,
9
+ # distribute, sublicense, and/or sell copies of the Software, and to
10
+ # permit persons to whom the Software is furnished to do so, subject to
11
+ # the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be
14
+ # included in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ #
24
+ ################################################################################
25
+ class LocalRedhanded < Scrapes::Page
26
+ rule :syndicate_link, 'a[@title^="Syndicate"]', '@href', 1
27
+ rule :syndicate_content, 'a[@title^="Syndicate"]', 'text()', 2
28
+ rule :script_language, 'script[@language="JavaScript"]', '@language', 1
29
+ rule :links, 'a', '@href'
30
+ rule :yo, 'div', 'texts()'
31
+ rule :foo, 'div', 'content()'
32
+ rule :bar, 'div', 'contents()'
33
+
34
+ rule :element, nil, nil, 1 do |doc|
35
+ doc.search('.div')
36
+ end
37
+
38
+ selector :dude do |doc|
39
+ doc.search('div')
40
+ end
41
+ extractor :dudes do |elem|
42
+ elem.name
43
+ end
44
+ rule :dude_rule, :dude, :dudes
45
+ rule :li, 'li' do |elem|
46
+ nil
47
+ end
48
+
49
+ validates_presence_of \
50
+ :syndicate_link,
51
+ :syndicate_content,
52
+ :links,
53
+ # :element,
54
+ :dude_rule,
55
+ # :dude_rule2,
56
+ :script_language
57
+ end
58
+ ################################################################################
@@ -0,0 +1,81 @@
1
+ ################################################################################
2
+ #
3
+ # Copyright (C) 2006 Peter J Jones (pjones@pmade.com)
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining
6
+ # a copy of this software and associated documentation files (the
7
+ # "Software"), to deal in the Software without restriction, including
8
+ # without limitation the rights to use, copy, modify, merge, publish,
9
+ # distribute, sublicense, and/or sell copies of the Software, and to
10
+ # permit persons to whom the Software is furnished to do so, subject to
11
+ # the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be
14
+ # included in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ #
24
+ ################################################################################
25
+ class RuleParserTest < Scrapes::Page
26
+ ################################################################################
27
+ rule :p_test, 'p'
28
+ rule :div_test, 'div'
29
+ rule_1 :p_test_1, 'p'
30
+ rule_1 :div_test_1, 'div'
31
+ ################################################################################
32
+ selector :just_doc do |doc| doc end
33
+ selector :css_search do |doc| doc.search(".ya") end
34
+ selector :xpath_search do |doc| doc.search("//span/div") end
35
+ rule_1 :just_doc_test, :just_doc
36
+ rule_1 :css_search_test, :css_search
37
+ rule_1 :xpath_search_test, :xpath_search
38
+ ################################################################################
39
+ selector :font
40
+ rule :font_test, :font
41
+ selector :string, "//span/p"
42
+ rule :string_test, :string
43
+ ################################################################################
44
+ extractor :just_node do |node| node end
45
+ extractor :attributes_class do |node| node.attributes['class'] end
46
+ rule_1 :just_node_test, nil, :just_node
47
+ rule :attributes_class_test, 'div', :attributes_class
48
+ ################################################################################
49
+ # TODO dry!
50
+ ################################################################################
51
+ rule :font_content, 'font', 'content()'
52
+ rule_1 :font_content_1, 'font', 'content()'
53
+ rule_1 :div_this, 'div#this', 'content()'
54
+ rule_1 :title, 'title', 'content()'
55
+ ################################################################################
56
+ rule :font_contents, 'font', 'contents()'
57
+ rule_1 :font_contents_1, 'font', 'contents()'
58
+ rule_1 :div_this_s, 'div#this', 'contents()'
59
+ rule_1 :title_s, 'title', 'contents()'
60
+ ################################################################################
61
+ rule :font_text, 'font', 'text()'
62
+ rule_1 :font_text_1, 'font', 'text()'
63
+ rule_1 :div_this_t, 'div#this', 'text()'
64
+ rule_1 :title_t, 'title', 'text()'
65
+ ################################################################################
66
+ rule :font_texts, 'font', 'texts()'
67
+ rule_1 :font_texts_1, 'font', 'texts()'
68
+ rule_1 :div_this_ts, 'div#this', 'texts()'
69
+ rule_1 :title_ts, 'title', 'texts()'
70
+ ################################################################################
71
+ rule :font_word, 'font', 'text()'
72
+ rule_1 :font_word_1, 'font', 'text()'
73
+ rule_1 :div_this_w, 'div#this', 'word()'
74
+ rule_1 :title_w, 'title', 'word()'
75
+ ################################################################################
76
+ rule :font_words, 'font', 'texts()'
77
+ rule_1 :font_words_1, 'font', 'texts()'
78
+ rule_1 :div_this_ws, 'div#this', 'words()'
79
+ rule_1 :title_ws, 'title', 'words()'
80
+ end
81
+ ################################################################################
@@ -0,0 +1,21 @@
1
+ class LocalSimple < Scrapes::Page
2
+
3
+ rule :div, 'div', 'xml()'
4
+
5
+ rule :content_one, '#one', 'content()'
6
+ rule :content_two, '#two', 'content()'
7
+ rule :content_three, '#three', 'content()'
8
+
9
+ rule :contents_one, '#one', 'contents()'
10
+ rule :contents_two, '#two', 'contents()'
11
+ rule :contents_three, '#three', 'contents()'
12
+
13
+ rule :text_one, '#one', 'text()'
14
+ rule :text_two, '#two', 'text()'
15
+ rule :text_three, '#three', 'text()'
16
+
17
+ rule :texts_one, '#one', 'texts()'
18
+ rule :texts_two, '#two', 'texts()'
19
+ rule :texts_three, '#three', 'texts()'
20
+
21
+ end
@@ -0,0 +1,10 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd">
2
+ <html>
3
+ <head>
4
+ <title>Pagination</title>
5
+ </head>
6
+ <body>
7
+ <a href="foil72.html"><img/></a>
8
+ <a href="OpenDocument0.html"></a>
9
+ </body>
10
+ </html>
@@ -0,0 +1,9 @@
1
+ <html>
2
+ <head>
3
+ <title>Pagination</title>
4
+ </head>
5
+ <body>
6
+ <a href="foil72.html"><img/></a>
7
+ <a href="OpenDocument1.html"></a>
8
+ </body>
9
+ </html>
@@ -0,0 +1,11 @@
1
+ <html>
2
+ <head>
3
+ <title>Pagination</title>
4
+ </head>
5
+ <body>
6
+ <a href="foil73.html"><img/></a>
7
+ <a href="OpenDocument2.html"><b>ya</b></a>
8
+ <a href="foil72.html"><img/>dude</a>
9
+ <p type=1>index.html<p>
10
+ </body>
11
+ </html>
@@ -0,0 +1 @@
1
+ yo
@@ -0,0 +1,20 @@
1
+ <html><head><meta http-equiv="content-type" content="text/html; charset=ISO-8859-1"><title>Google</title><style><!--
2
+ body,td,a,p,.h{font-family:arial,sans-serif}
3
+ .h{font-size:20px}
4
+ .q{color:#00c}
5
+ --></style>
6
+ <script>
7
+ <!--
8
+ function sf(){document.f.q.focus();}
9
+ // -->
10
+ </script>
11
+ </head><body bgcolor=#ffffff text=#000000 link=#0000cc vlink=#551a8b alink=#ff0000 onLoad=sf() topmargin=3 marginheight=3><center><div align=right nowrap style="padding-bottom:4px" width=100%><font size=-1><a href="/url?sa=p&pref=ig&pval=3&q=http://www.google.com/ig%3Fhl%3Den&sig=__yvmOvIrk79QYmDkrJAeuYO8jTmo=">Personalized Home</a>&nbsp;|&nbsp;<a href="https://www.google.com/accounts/Login?continue=http://www.google.com/&hl=en">Sign in</a></font></div><img src="/intl/en/images/logo.gif" width=276 height=110 alt="Google"><br><br>
12
+ <form action=/search name=f><table border=0 cellspacing=0 cellpadding=4><tr><td nowrap><font size=-1><b>Web</b>&nbsp;&nbsp;&nbsp;&nbsp;<a class=q href="/imghp?hl=en&ie=UTF-8&tab=wi">Images</a>&nbsp;&nbsp;&nbsp;&nbsp;<a class=q href="http://video.google.com/?hl=en&ie=UTF-8&tab=wv">Video</a>&nbsp;&nbsp;&nbsp;&nbsp;<a class=q href="http://news.google.com/nwshp?hl=en&ie=UTF-8&tab=wn">News</a>&nbsp;&nbsp;&nbsp;&nbsp;<a class=q href="/maps?hl=en&ie=UTF-8&tab=wl">Maps</a>&nbsp;&nbsp;&nbsp;&nbsp;<b><a href="/intl/en/options/" class=q onclick="this.blur();return togDisp(event);">more&nbsp;&raquo;</a></b><script><!--
13
+ function togDisp(e){stopB(e);var elems=document.getElementsByName('more');for(var i=0;i<elems.length;i++){var obj=elems[i];var dp="";if(obj.style.display==""){dp="none";}obj.style.display=dp;}return false;}
14
+ function stopB(e){if(!e)e=window.event;e.cancelBubble=true;}
15
+ document.onclick=function(event){var elems=document.getElementsByName('more');if(elems[0].style.display == ""){togDisp(event);}}
16
+ //-->
17
+ </script><style><!--
18
+ .cb{margin:.5ex}
19
+ --></style>
20
+ <span name=more id=more style="display:none;position:absolute;background:#fff;border:1px solid #369;margin:-.5ex 1.5ex;padding:0 0 .5ex .8ex;width:16ex;line-height:1.9;z-index:1000" onclick="stopB(event);"><a href=# onclick="return togDisp(event);"><img border=0 src=/images/x2.gif width=12 height=12 alt="Close menu" align=right class=cb></a><a class=q href="http://books.google.com/bkshp?hl=en&ie=UTF-8&tab=wp">Books</a><br><a class=q href="http://froogle.google.com/frghp?hl=en&ie=UTF-8&tab=wf">Froogle</a><br><a class=q href="http://groups.google.com/grphp?hl=en&ie=UTF-8&tab=wg">Groups</a><br><a href="/intl/en/options/" class=q><b>even more &raquo;</b></a></span></font></td></tr></table><table cellspacing=0 cellpadding=0><tr><td width=25%>&nbsp;</td><td align=center><input type=hidden name=hl value=en><input type=hidden name=ie value="ISO-8859-1"><input maxlength=2048 size=55 name=q value="" title="Google Search"><br><input type=submit value="Google Search" name=btnG><input type=submit value="I'm Feeling Lucky" name=btnI></td><td valign=top nowrap width=25%><font size=-2>&nbsp;&nbsp;<a href=/advanced_search?hl=en>Advanced Search</a><br>&nbsp;&nbsp;<a href=/preferences?hl=en>Preferences</a><br>&nbsp;&nbsp;<a href=/language_tools?hl=en>Language Tools</a></font></td></tr></table></form><br><br><font size=-1><a href="/intl/en/ads/">Advertising&nbsp;Programs</a> - <a href=/services/>Business Solutions</a> - <a href=/intl/en/about.html>About Google</a></font><p><font size=-2>&copy;2006 Google</font></p></center></body></html>
@@ -0,0 +1,1208 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd">
2
+ <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
3
+ <head>
4
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5
+ <title>RedHanded &raquo; sneaking Ruby through the system</title>
6
+ <link rel="alternate" type="application/rss+xml" title="RSS" href="http://redhanded.hobix.com/index.xml" />
7
+ <script type="text/javascript" language="JavaScript" src="/js/strftime.js"></script>
8
+
9
+ <style type="text/css">
10
+ @import "/site.css";
11
+ </style>
12
+ </head>
13
+ <body>
14
+
15
+ <div id="page">
16
+
17
+ <div id="hoodwinkd">
18
+ <a href="http://hoodwinkd.hobix.com/"><span>hoodwink.d enhanced</span></a>
19
+
20
+ </div>
21
+ <div id="buttons">
22
+ <dl class="tab">
23
+ <dt><a title="Syndicate this Site" href="/index.xml">RSS</a></dt>
24
+ <dd><a title="Syndicate this Site" href="/index.xml">2.0</a></dd>
25
+ </dl>
26
+ <dl class="tab xhtml">
27
+ <dt><a title="Validate this Site" href="http://validator.w3.org/check?uri=http://redhanded.hobix.com/">XHTML</a></dt>
28
+ <dd><a title="Validate this Site" href="http://validator.w3.org/check?uri=http://redhanded.hobix.com/">1.0</a></dd>
29
+ </dl>
30
+ </div>
31
+ <h1 class="title"><a href="http://redhanded.hobix.com"><img src="/images/redhanded.gif" alt="RedHanded" /></a></h1>
32
+ <div id="banner">
33
+ <div class="tagline">sneaking Ruby through the system</div>
34
+ <div class="nav"><a href="/5.gets/">5.gets</a> | <a href="/bits/">bits</a> |
35
+ <a href="/inspect/">inspect</a> | <a href="/cult/">the cult</a> | <a href="/-h/">-h</a></div>
36
+ </div>
37
+
38
+
39
+ <div id="content">
40
+ <div id="sidebar">
41
+ <p>New to RedHanded? <a href="/-h/pardonAndWelcome.html">About our sections.</a></p>
42
+
43
+ <div class="sidebarBox">
44
+ <h2 class="sidebarTitle">Archive</h2>
45
+ <ul>
46
+
47
+ <li><a href="http://redhanded.hobix.com//2004/12/">December 2004</a></li>
48
+
49
+ <li><a href="http://redhanded.hobix.com//2005/01/">January 2005</a></li>
50
+
51
+ <li><a href="http://redhanded.hobix.com//2005/02/">February 2005</a></li>
52
+
53
+ <li><a href="http://redhanded.hobix.com//2005/03/">March 2005</a></li>
54
+
55
+ <li><a href="http://redhanded.hobix.com//2005/04/">April 2005</a></li>
56
+
57
+ <li><a href="http://redhanded.hobix.com//2005/05/">May 2005</a></li>
58
+
59
+ <li><a href="http://redhanded.hobix.com//2005/06/">June 2005</a></li>
60
+
61
+ <li><a href="http://redhanded.hobix.com//2005/07/">July 2005</a></li>
62
+
63
+ <li><a href="http://redhanded.hobix.com//2005/08/">August 2005</a></li>
64
+
65
+ <li><a href="http://redhanded.hobix.com//2005/09/">September 2005</a></li>
66
+
67
+ <li><a href="http://redhanded.hobix.com//2005/10/">October 2005</a></li>
68
+
69
+ <li><a href="http://redhanded.hobix.com//2005/11/">November 2005</a></li>
70
+
71
+ <li><a href="http://redhanded.hobix.com//2005/12/">December 2005</a></li>
72
+
73
+ <li><a href="http://redhanded.hobix.com//2006/01/">January 2006</a></li>
74
+
75
+ <li><a href="http://redhanded.hobix.com//2006/02/">February 2006</a></li>
76
+
77
+ <li><a href="http://redhanded.hobix.com//2006/03/">March 2006</a></li>
78
+
79
+ <li><a href="http://redhanded.hobix.com//2006/04/">April 2006</a></li>
80
+
81
+ <li><a href="http://redhanded.hobix.com//2006/05/">May 2006</a></li>
82
+
83
+ <li><a href="http://redhanded.hobix.com//2006/06/">June 2006</a></li>
84
+
85
+ <li><a href="http://redhanded.hobix.com//2006/07/">July 2006</a></li>
86
+
87
+ <li><a href="http://redhanded.hobix.com//2006/08/">August 2006</a></li>
88
+
89
+ <li><a href="http://redhanded.hobix.com//2006/09/">September 2006</a></li>
90
+
91
+ <li><a href="http://redhanded.hobix.com//2006/10/">October 2006</a></li>
92
+
93
+ </ul>
94
+ </div>
95
+
96
+ <p><a href="http://www.pragmaticprogrammer.com/titles/ruby/index.html"><img src="/images/prag-ruby-book.jpg" alt="PickAxe II" /></a><br />
97
+ <a href="http://www.pragmaticprogrammer.com/titles/ruby/index.html">Get your copy of <i>Programming Ruby</i>!</a></p>
98
+
99
+ <div class="sidebarBox">
100
+ <h2 class="sidebarTitle">Links</h2>
101
+ <a href="http://technorati.com/tags/ruby">@technorati</a><br />
102
+ <a href="http://del.icio.us/tag/ruby">@del.icio.us</a><br />
103
+ <a href="http://www.flickr.com/photos/tags/ruby">@flickr</a><br />
104
+ <a href="http://www.artima.com/articles/index.jsp?topic=ruby">@artima</a><br />
105
+ <a href="http://blog.caboo.se/">@caboo</a><br />
106
+ <a href="http://www.oreillynet.com/ruby">@oreilly</a><br />
107
+ <a href="http://ruby-lang.org/">ruby</a><br />
108
+ <a href="http://ruby-doc.org/">-&gt; docs</a><br />
109
+ <a href="http://rubyforge.org/">-&gt; wares</a><br />
110
+ <a href="http://rubygarden.org/ruby/">-&gt; wiki</a><br />
111
+ <a href="http://www.sitepoint.com/forums/forumdisplay.php?f=227">-&gt; forum</a><br />
112
+ <a href="http://www.rubyquiz.com/">-&gt; quizzes</a><br />
113
+ <a href="http://planetruby.0x42.net/">-&gt; planet</a><br />
114
+ <a href="http://meme.b9.com/cdates.html?channel=ruby-lang">-&gt; irc</a><br />
115
+ <a href="http://www.rubyweeklynews.org/">rubyweeklynews</a><br />
116
+ <a href="http://weblog.rubyonrails.com/">rails</a><br />
117
+ <a href="http://wiki.rubyonrails.org/">-&gt; wiki</a><br />
118
+ <a href="http://www.planetrubyonrails.org/">-&gt; planet</a><br />
119
+ <a href="http://thesaq.com/rubyonrails/">-&gt; irc</a><br />
120
+ <a href="http://anarchaia.org/">%anarchaia</a><br />
121
+ <a href="http://project.ioni.st/">%projectionist</a><br />
122
+ <a href="http://pugs.blogs.com/">~audreyt</a><br />
123
+ <a href="http://dablog.rubypal.com/">~black</a><br />
124
+ <a href="http://www.jamesbritt.com/">~britt</a><br />
125
+ <a href="http://www.jamisbuck.org/jamis/">~buck</a><br />
126
+ <a href="http://tomcopeland.blogs.com/juniordeveloper/">~copeland</a><br />
127
+ <a href="http://eigenclass.org/">~fernandez</a><br />
128
+ <a href="http://www.chadfowler.com/">~fowler</a><br />
129
+ <a href="http://www.loudthinking.com/">~hansson</a><br />
130
+ <a href="http://blog.segment7.net/">~hodel</a><br />
131
+ <a href="http://slash7.com/">~hoy/7</a><br />
132
+ <a href="http://fhwang.net/">~hwang</a><br />
133
+ <a href="http://blog.leetsoft.com/">~luetke</a><br />
134
+ <a href="http://www.worldlingo.com/wl/translate?wl_lp=JA-en&amp;wl_glossary=gl1&amp;wl_fl=3&amp;wl_rurl=http%3A%2F%2Fwww.rubyist.net%2F%7Ematz%2F&amp;wl_url=http%3A%2F%2Fwww.rubyist.net%2F%7Ematz%2F&amp;wl_g_table=-3">~matz</a><br />
135
+ <a href="http://moonbase.rydia.net/">~mental</a><br />
136
+ <a href="http://techno-weenie.net/">~olson</a><br />
137
+ <a href="http://pragprog.com/pragdave">~pragdave</a><br />
138
+ <a href="http://www.livejournal.com/users/premshree/">~premshree</a><br />
139
+ <a href="http://kronavita.de/chris/blog/">~neukirchen</a><br />
140
+ <a href="http://www.robbyonrails.com/">~robby</a><br />
141
+ <a href="http://www.rousette.org.uk/">~rousette</a><br />
142
+ <a href="http://nubyonrails.com/">~topfunky</a><br />
143
+ <a href="http://www.jvoorhis.com/">~voorhis</a><br />
144
+ <a href="http://onestepback.org/">~weirich</a><br />
145
+ <a href="http://blog.zenspider.com/">~zenspider</a><br />
146
+ </div>
147
+ <div class="sidebarBox">
148
+ <h2 class="sidebarTitle">Syndicate</h2>
149
+ <ul>
150
+ <li><a href="http://redhanded.hobix.com/index.xml">RSS 2.0</a></li>
151
+ </ul>
152
+ </div>
153
+ <div class="sidebarBox">
154
+ <p>Built upon <a href="http://hobix.com">Hobix</a></p>
155
+ </div>
156
+ <img src="/images/redhanded-duck.gif" alt="Type the Duck" />
157
+ <div class="email">Got a story for us? <a href="mailto:redhanded@hobix.com">E-mail it!</a></div>
158
+ <div class='technorati'><p><a href='http://www.technorati.com/profile/whytheluckystiff'>Technorati Profile</a>
159
+ <a href='http://www.technorati.com/cosmos/search.html?url=http&#37;3A&#37;2F&#37;2Fredhanded&#46;hobix&#46;com'><br />
160
+ <img src='/images/bubble_icon.gif' height='20' width='24' alt='Get Conversations about RedHanded &#187; sneaking Ruby through the system' /></a>
161
+ </p>
162
+ </div>
163
+
164
+ </div>
165
+
166
+
167
+ <div id="blog">
168
+
169
+ <a name="20061023"></a>
170
+ <div class="dayHeader">
171
+ <div class="dayBox">
172
+ <h2>Monday</h2>
173
+ <h3><a href="/2006/">2006</a>.<a href="/2006/10/">10</a>.<a href="/2006/10/23.html">23</a></h3>
174
+ </div>
175
+ </div>
176
+
177
+
178
+ <div class="entry">
179
+ <h2 class="entryTitle">Denver Accord
180
+ <span class="entryPermalink"><a href="http://redhanded.hobix.com/inspect/denverAccord.html"
181
+ title="Permanent link to &#8220;Denver Accord&#8221;">#</a></span>
182
+ </h2>
183
+
184
+ <div class="entrySection">by <a href="http://www.sgtpepper.net/hyspro/diary/"
185
+ title="Visit daigo's homepage">daigo</a>
186
+ in <a href="/inspect" title="List of entries in the &#8220;inspect&#8221; category">inspect</a>
187
+ </div>
188
+
189
+ <div class="entryContent">
190
+
191
+ <p>Takahashi, Matz, Ko1, Urabe, Ogino and me talked about a plan of the near future
192
+ (hopefully this year) in Ko1&#8217;s room at the Sunday night for 4 hours. Here are the
193
+ summaries. Matz has agreed them and will post announcements. We are sure that it makes sense for you as well.</p>
194
+ <p><a href="http://redhanded.hobix.com/inspect/denverAccord.html">Continue to full post.</a> <em>(527 words)</em></p>
195
+
196
+ </div>
197
+ </div>
198
+ <div class="entryFooter"> <a href="http://redhanded.hobix.com/inspect/denverAccord.html">
199
+ <script type="text/javascript" language="JavaScript">
200
+ document.write((new Date(1161602213000)).strftime("%H:%M"));
201
+ </script>
202
+ <noscript>
203
+ 06:16 UTC
204
+ </noscript>
205
+ </a> |
206
+ <a href="http://redhanded.hobix.com/inspect/denverAccord.html#comments">Comments (14)</a>
207
+ </div>
208
+
209
+
210
+ <a name="20061020"></a>
211
+ <div class="dayHeader">
212
+ <div class="dayBox">
213
+ <h2>Friday</h2>
214
+ <h3><a href="/2006/">2006</a>.<a href="/2006/10/">10</a>.<a href="/2006/10/20.html">20</a></h3>
215
+ </div>
216
+ </div>
217
+
218
+
219
+ <div class="entry">
220
+ <h2 class="entryTitle">Nic.d Gets Punct
221
+ <span class="entryPermalink"><a href="http://redhanded.hobix.com/cult/whoNicDOffWithTheYummyJunkDomains.html"
222
+ title="Permanent link to &#8220;Nic.d Gets Punct&#8221;">#</a></span>
223
+ </h2>
224
+
225
+ <div class="entrySection">by <a href="http://whytheluckystiff.net/"
226
+ title="Visit why's homepage">why</a>
227
+ in <a href="/cult" title="List of entries in the &#8220;cult&#8221; category">cult</a>
228
+ </div>
229
+
230
+ <div class="entryContent">
231
+
232
+ <p style="float:right"><a href="http://nic.d/"><img src="/images/hoodwinkd-registrar.png" alt="" /></a></p>
233
+
234
+
235
+ <p>Announcing <a href="http://nic.d/">Nic.d</a>&#8212;for registering invalid domains in the underground.</p>
236
+
237
+
238
+ <p>While most registrars disallow use of equals signs, plusses, bangs, cashies, snails, guillemets, pig pens, pilcrows and the bunch in hostnames&#8212;nic.d refuses this grave hypocrisy! I am thief.</p>
239
+
240
+
241
+ <p>If you are thief, set your <span class="caps">DNS</span> to <code>nic.d.hobix.com</code> and cross over to the bad side forever.</p>
242
+
243
+ </div>
244
+ </div>
245
+ <div class="entryFooter"> <a href="http://redhanded.hobix.com/cult/whoNicDOffWithTheYummyJunkDomains.html">
246
+ <script type="text/javascript" language="JavaScript">
247
+ document.write((new Date(1161383232000)).strftime("%H:%M"));
248
+ </script>
249
+ <noscript>
250
+ 17:27 UTC
251
+ </noscript>
252
+ </a> |
253
+ <a href="http://redhanded.hobix.com/cult/whoNicDOffWithTheYummyJunkDomains.html#comments">Comments (44)</a>
254
+ </div>
255
+
256
+ <div class="entry">
257
+ <h2 class="entryTitle">He Paid to Go and Type
258
+ <span class="entryPermalink"><a href="http://redhanded.hobix.com/cult/hePaidToGoAndTypeAllDay.html"
259
+ title="Permanent link to &#8220;He Paid to Go and Type&#8221;">#</a></span>
260
+ </h2>
261
+
262
+ <div class="entrySection">by <a href="http://whytheluckystiff.net/"
263
+ title="Visit why's homepage">why</a>
264
+ in <a href="/cult" title="List of entries in the &#8220;cult&#8221; category">cult</a>
265
+ </div>
266
+
267
+ <div class="entryContent">
268
+
269
+ <p>Rubyist, <span class="caps">MINI</span> motorist, agile saxophonist and bullet-pointilist Nick Sieger is my forecast for Mile-High Scrivener of The Moment (weekend of October 20th to the 22nd, 2006) for <a href="http://blog.nicksieger.com/articles/tag/rubyconf2006">his work</a> transcribing RubyConf 2006. So put that in your saxophone and blow it. Anyway, just stay put in your chairs, I&#8217;m sure Zed will be on soon.</p>
270
+
271
+ </div>
272
+ </div>
273
+ <div class="entryFooter"> <a href="http://redhanded.hobix.com/cult/hePaidToGoAndTypeAllDay.html">
274
+ <script type="text/javascript" language="JavaScript">
275
+ document.write((new Date(1161380617000)).strftime("%H:%M"));
276
+ </script>
277
+ <noscript>
278
+ 16:43 UTC
279
+ </noscript>
280
+ </a> |
281
+ <a href="http://redhanded.hobix.com/cult/hePaidToGoAndTypeAllDay.html#comments">Comments (3)</a>
282
+ </div>
283
+
284
+
285
+ <a name="20061019"></a>
286
+ <div class="dayHeader">
287
+ <div class="dayBox">
288
+ <h2>Thursday</h2>
289
+ <h3><a href="/2006/">2006</a>.<a href="/2006/10/">10</a>.<a href="/2006/10/19.html">19</a></h3>
290
+ </div>
291
+ </div>
292
+
293
+
294
+ <div class="entry">
295
+ <h2 class="entryTitle">The Soda Languages
296
+ <span class="entryPermalink"><a href="http://redhanded.hobix.com/cult/theSodaLanguages.html"
297
+ title="Permanent link to &#8220;The Soda Languages&#8221;">#</a></span>
298
+ </h2>
299
+
300
+ <div class="entrySection">by <a href="http://whytheluckystiff.net/"
301
+ title="Visit why's homepage">why</a>
302
+ in <a href="/cult" title="List of entries in the &#8220;cult&#8221; category">cult</a>
303
+ </div>
304
+
305
+ <div class="entryContent">
306
+
307
+ <p>Whoa, get ready to spend your whole afternoon tooling around with a small pile of little languages and compilers. I am completely hooked on <a href="http://piumarta.com/pepsi/">Idst</a>, a compiler for a hybrid prototype-based Smalltalk-plus-C language by Ian Piumarta. And atop the bedrock of Idst: the soda languages.</p>
308
+
309
+
310
+ <p>I first heard about Ian&#8217;s stuff in a #camping discussion where <a href="http://piumarta.com/pepsi/pepsi.html">Pepsi</a> (the Smalltalk/C hybrid) was brought up. Well, it turns out Idst also comes with a Lisp-like soda language called Jolt (see <strong>examples/jolt</strong>.) Other examples are just great and include a teensy Squeak VM (<strong>examples/sqvm</strong>) and some <span class="caps">X11</span> samples (<strong>examples/x11</strong>.)</p>
311
+
312
+
313
+ <p>He explains the Pepsi syntax in <a href="http://weeklysqueak.wordpress.com/2006/10/16/dynamic-messages-a-tour-of-pepsi/">an interview</a> a few days ago on the Weekly Squeak:</p>
314
+
315
+
316
+ <blockquote>
317
+ <p>You can mix C-code and “Id” code in a very simple way. So it is easy to integrate with O.S. services. The idea is quite the opposite of Objective-C: you think in terms of objects all the time (as in SmallTalk). Then you “come back” to C-Language for the dirty part of your work.</p>
318
+ </blockquote>
319
+
320
+
321
+ <p>The syntax is suprisingly terse. You use curly braces to break out into a method written in C. Square brackets for Smalltalk-style.</p>
322
+
323
+
324
+ <pre>
325
+ X11Display newWindow [ ^X11Window withDisplay: self ]
326
+
327
+ X11Display _createSimpleWindow_: _x _: _y _: _w _: _h _: _bw _: _b _: _bg
328
+ {
329
+ return (oop)XCreateSimpleWindow((Display *)self-&gt;v__dpy,
330
+ DefaultRootWindow((Display *)self-&gt;v__dpy),
331
+ (int)v__x, (int)v__y, (int)v__w, (int)v__h,
332
+ (int)v__bw, (int)v__b, (int)v__bg);
333
+ }
334
+
335
+ X11Display createWindow: bounds borderWidth: borderWidth
336
+ border: border background: background
337
+ [
338
+ ^self newWindow
339
+ _win_: (self _createSimpleWindow_: (bounds _x) _: (bounds _y)
340
+ _: (bounds _w) _: (bounds _h)
341
+ _: borderWidth _integerValue
342
+ _: border _integerValue
343
+ _: background _integerValue)
344
+ ]
345
+ </pre>
346
+
347
+ <p>Can you get over that?</p>
348
+
349
+
350
+ <p class="update"><strong>Update:</strong> Some of the above interview appears to be taken from <a href="http://article.gmane.org/gmane.comp.lang.smalltalk.squeak.general/107455">a post</a> on the Smalltalk newsgroup, which goes into greater detail concerning Coke and Jolt, as well as the other literal man-decades of work Ian has assigned himself.</p>
351
+
352
+
353
+ <blockquote>
354
+ <p>It&#8217;s often said that Smalltalk and Lisp suffer because they are systems that eat all of their young. If <span class="caps">COLA</span> succeeds it might be called the system that ate its parents.</p>
355
+ </blockquote>
356
+
357
+ </div>
358
+ </div>
359
+ <div class="entryFooter"> <a href="http://redhanded.hobix.com/cult/theSodaLanguages.html">
360
+ <script type="text/javascript" language="JavaScript">
361
+ document.write((new Date(1161282793000)).strftime("%H:%M"));
362
+ </script>
363
+ <noscript>
364
+ 13:33 UTC
365
+ </noscript>
366
+ </a> |
367
+ <a href="http://redhanded.hobix.com/cult/theSodaLanguages.html#comments">Comments (9)</a>
368
+ </div>
369
+
370
+
371
+ <a name="20061016"></a>
372
+ <div class="dayHeader">
373
+ <div class="dayBox">
374
+ <h2>Monday</h2>
375
+ <h3><a href="/2006/">2006</a>.<a href="/2006/10/">10</a>.<a href="/2006/10/16.html">16</a></h3>
376
+ </div>
377
+ </div>
378
+
379
+
380
+ <div class="entry">
381
+ <h2 class="entryTitle">Running Pugs Across Your Browser
382
+ <span class="entryPermalink"><a href="http://redhanded.hobix.com/cult/runPugsInYourBrowser.html"
383
+ title="Permanent link to &#8220;Running Pugs Across Your Browser&#8221;">#</a></span>
384
+ </h2>
385
+
386
+ <div class="entrySection">by <a href="http://whytheluckystiff.net/"
387
+ title="Visit why's homepage">why</a>
388
+ in <a href="/cult" title="List of entries in the &#8220;cult&#8221; category">cult</a>
389
+ </div>
390
+
391
+ <div class="entryContent">
392
+
393
+ <p style="float:left"><a href="http://run.pugscode.org/"><img src="/images/runpugs.png" alt="" /></a></p>
394
+
395
+
396
+ <p>The Pugs team (more specifically: Wim Vanderbauwhede) has an online <span class="caps">REPL</span> up for trying out Perl 6! <a href="http://run.pugscode.org/">Run Perl 6 Now</a> gives you a Pugs shell over <span class="caps">CGI</span>. Hopefully this means some of the tools I&#8217;ve worked on (<a href="http://tryruby.hobix.com/try.js">ruby.js</a>, <a href="http://tryruby.hobix.com/try.sh">ruby.sh</a>) can be redone for learning Pugs sans installation. From the looks of it, <a href="http://svn.openfoundry.org/pugs/misc/runpugs/">the code</a> uses a very similar query string, so I&#8217;ll bet the colory prompt could be overlaid pretty easily as well.</p>
397
+
398
+ </div>
399
+ </div>
400
+ <div class="entryFooter"> <a href="http://redhanded.hobix.com/cult/runPugsInYourBrowser.html">
401
+ <script type="text/javascript" language="JavaScript">
402
+ document.write((new Date(1161026918000)).strftime("%H:%M"));
403
+ </script>
404
+ <noscript>
405
+ 14:28 UTC
406
+ </noscript>
407
+ </a> |
408
+ <a href="http://redhanded.hobix.com/cult/runPugsInYourBrowser.html#comments">Comments (8)</a>
409
+ </div>
410
+
411
+ <div class="entry">
412
+ <h2 class="entryTitle">Stop-Motion Hacking and a Bit of Celebratory Flag Waving
413
+ <span class="entryPermalink"><a href="http://redhanded.hobix.com/cult/stopMotionHackingAndABitOfCelebratoryFlagWaving.html"
414
+ title="Permanent link to &#8220;Stop-Motion Hacking and a Bit of Celebratory Flag Waving&#8221;">#</a></span>
415
+ </h2>
416
+
417
+ <div class="entrySection">by <a href="http://whytheluckystiff.net/"
418
+ title="Visit why's homepage">why</a>
419
+ in <a href="/cult" title="List of entries in the &#8220;cult&#8221; category">cult</a>
420
+ </div>
421
+
422
+ <div class="entryContent">
423
+
424
+ <p>Oh, yes, this is classic. From <a href="http://hoodwink.d/Palmer">Palmer</a>, his 24-hour code-a-thon on time lapse.</p>
425
+
426
+
427
+ <p style="text-align:center"><object width="425" height="350"><param name="movie" value="http://www.youtube.com/v/xfodlPqG1vM"></param><param name="wmode" value="transparent"></param><embed src="http://www.youtube.com/v/xfodlPqG1vM" type="application/x-shockwave-flash" wmode="transparent" width="425" height="350"></embed></object></p>
428
+
429
+ </div>
430
+ </div>
431
+ <div class="entryFooter"> <a href="http://redhanded.hobix.com/cult/stopMotionHackingAndABitOfCelebratoryFlagWaving.html">
432
+ <script type="text/javascript" language="JavaScript">
433
+ document.write((new Date(1161020465000)).strftime("%H:%M"));
434
+ </script>
435
+ <noscript>
436
+ 12:41 UTC
437
+ </noscript>
438
+ </a> |
439
+ <a href="http://redhanded.hobix.com/cult/stopMotionHackingAndABitOfCelebratoryFlagWaving.html#comments">Comments (4)</a>
440
+ </div>
441
+
442
+ <div class="entry">
443
+ <h2 class="entryTitle">Yay, Matz is on the Cusp of Unveiling Ruby's Unicode Support!
444
+ <span class="entryPermalink"><a href="http://redhanded.hobix.com/cult/yayMatzIsOnTheCuspOfUnveilingRubySUnicodeSupport.html"
445
+ title="Permanent link to &#8220;Yay, Matz is on the Cusp of Unveiling Ruby's Unicode Support!&#8221;">#</a></span>
446
+ </h2>
447
+
448
+ <div class="entrySection">by <a href="http://whytheluckystiff.net/"
449
+ title="Visit why's homepage">why</a>
450
+ in <a href="/cult" title="List of entries in the &#8220;cult&#8221; category">cult</a>
451
+ </div>
452
+
453
+ <div class="entryContent">
454
+
455
+ <blockquote>
456
+ <p><a href="http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/9196">matz</a>: You will have chars and each_chars along with other <span class="caps">M17N</span>
457
+ functionality. I wanted merge it before RubyConf (to show Tim Bray
458
+ working code), but regretfully failed. ;-&lt;</p>
459
+ </blockquote>
460
+
461
+
462
+ <p>He <a href="http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/9192">goes on</a> to explain how having symbols inherit from strings is part of that master plan, to ensure symbols know their encoding and everything jives nation-to-nation. Heal the world, make it a better place and all that. (Also <a href="http://redhanded.hobix.com/inspect/SymbolIs_aString.html">see here</a> in the comments for a big list of pros + cons.)</p>
463
+
464
+ </div>
465
+ </div>
466
+ <div class="entryFooter"> <a href="http://redhanded.hobix.com/cult/yayMatzIsOnTheCuspOfUnveilingRubySUnicodeSupport.html">
467
+ <script type="text/javascript" language="JavaScript">
468
+ document.write((new Date(1161014351000)).strftime("%H:%M"));
469
+ </script>
470
+ <noscript>
471
+ 10:59 UTC
472
+ </noscript>
473
+ </a> |
474
+ <a href="http://redhanded.hobix.com/cult/yayMatzIsOnTheCuspOfUnveilingRubySUnicodeSupport.html#comments">Comments (14)</a>
475
+ </div>
476
+
477
+
478
+ <a name="20061013"></a>
479
+ <div class="dayHeader">
480
+ <div class="dayBox">
481
+ <h2>Friday</h2>
482
+ <h3><a href="/2006/">2006</a>.<a href="/2006/10/">10</a>.<a href="/2006/10/13.html">13</a></h3>
483
+ </div>
484
+ </div>
485
+
486
+
487
+ <div class="entry">
488
+ <h2 class="entryTitle">The Least Surprised #13: Those Are Stars In Our Eyes
489
+ <span class="entryPermalink"><a href="http://redhanded.hobix.com/cult/theLeastSurprised13.html"
490
+ title="Permanent link to &#8220;The Least Surprised #13: Those Are Stars In Our Eyes&#8221;">#</a></span>
491
+ </h2>
492
+
493
+ <div class="entrySection">by <a href="http://whytheluckystiff.net/"
494
+ title="Visit why's homepage">why</a>
495
+ in <a href="/cult" title="List of entries in the &#8220;cult&#8221; category">cult</a>
496
+ </div>
497
+
498
+ <div class="entryContent">
499
+
500
+ <p style="text-align:center;"><img src="/images/the-least-suprised-13.png" title="The Least Surprised #13: Those Are Stars In Our Eyes" alt="The Least Surprised #13: Those Are Stars In Our Eyes" /></p>
501
+
502
+ </div>
503
+ </div>
504
+ <div class="entryFooter"> <a href="http://redhanded.hobix.com/cult/theLeastSurprised13.html">
505
+ <script type="text/javascript" language="JavaScript">
506
+ document.write((new Date(1160777671000)).strftime("%H:%M"));
507
+ </script>
508
+ <noscript>
509
+ 17:14 UTC
510
+ </noscript>
511
+ </a> |
512
+ <a href="http://redhanded.hobix.com/cult/theLeastSurprised13.html#comments">Comments (12)</a>
513
+ </div>
514
+
515
+
516
+ <a name="20061012"></a>
517
+ <div class="dayHeader">
518
+ <div class="dayBox">
519
+ <h2>Thursday</h2>
520
+ <h3><a href="/2006/">2006</a>.<a href="/2006/10/">10</a>.<a href="/2006/10/12.html">12</a></h3>
521
+ </div>
522
+ </div>
523
+
524
+
525
+ <div class="entry">
526
+ <h2 class="entryTitle">Manfred Smacks Open a Camping Piñata
527
+ <span class="entryPermalink"><a href="http://redhanded.hobix.com/cult/manfredSmacksOpenACampingPiAta.html"
528
+ title="Permanent link to &#8220;Manfred Smacks Open a Camping Piñata&#8221;">#</a></span>
529
+ </h2>
530
+
531
+ <div class="entrySection">by <a href="http://whytheluckystiff.net/"
532
+ title="Visit why's homepage">why</a>
533
+ in <a href="/cult" title="List of entries in the &#8220;cult&#8221; category">cult</a>
534
+ </div>
535
+
536
+ <div class="entryContent">
537
+
538
+ <p>Stuff like: <a href="http://svn.dwerg.net/cushion/trunk">Cushion</a>, a Camping app for blogging movies and stuff; his <a href="http://operation0.org/2006/10/camping-demo-with-rabbits-without-the-rabbits">campcast</a> titled <em>Camping Demo With Rabbits, Without the Rabbits</em>; and, his <a href="http://operation0.org/">operation0</a> journal that promises to have a wealth of other hacks. Yay, manf! (<strong>Disclaimer:</strong> I disapprove of Quicktime, with its outlandish disobeyal of my 4k creed, and stridently believe that Camping-related vids should be in animated gif.)</p>
539
+
540
+ </div>
541
+ </div>
542
+ <div class="entryFooter"> <a href="http://redhanded.hobix.com/cult/manfredSmacksOpenACampingPiAta.html">
543
+ <script type="text/javascript" language="JavaScript">
544
+ document.write((new Date(1160693623000)).strftime("%H:%M"));
545
+ </script>
546
+ <noscript>
547
+ 17:53 UTC
548
+ </noscript>
549
+ </a> |
550
+ <a href="http://redhanded.hobix.com/cult/manfredSmacksOpenACampingPiAta.html#comments">Comments (12)</a>
551
+ </div>
552
+
553
+ <div class="entry">
554
+ <h2 class="entryTitle">5.gets BradPauly
555
+ <span class="entryPermalink"><a href="http://redhanded.hobix.com/5.gets/5GetsBradpauly.html"
556
+ title="Permanent link to &#8220;5.gets BradPauly&#8221;">#</a></span>
557
+ </h2>
558
+
559
+ <div class="entrySection">by <a href="http://whytheluckystiff.net/"
560
+ title="Visit why's homepage">why</a>
561
+ in <a href="/5.gets" title="List of entries in the &#8220;5.gets&#8221; category">5.gets</a>
562
+ </div>
563
+
564
+ <div class="entryContent">
565
+
566
+ <p class="intro">This <a href="http://www.foundmagazine.com/find/719">frog skin</a> found in a used book is served up by Mongrel! I can&#8217;t think of a better payload. And the minute I heard on the Mongrel mailing list that <a href="http://foundmagazine.com/">Found Magazine</a> [<a href="http://en.wikipedia.org/wiki/Found_Magazine">W</a>] had been coded afresh in Ruby, I hit up Brad Pauly, the developer, for some discussion.</p>
567
+
568
+
569
+ <p class="gets">1. So, Found must be a fun site to work on because you&#8217;ve just got this pile of litter (notes, photos, street junk and so on) and you&#8217;re basically interfacing technology with that mound of other folk&#8217;s discarded trash. How do you sort it all out? Or is it best to just leave it disorganized?</p>
570
+
571
+
572
+ <p class="puts">Yeah, I had a ton of fun working on it. The previous version had some organization by way of &#8220;related finds&#8221; that we left out on purpose for this version. People seem to prefer the randomness and it makes sense to me. I think the joy of discovery is diminished when you&#8217;re guided.</p>
573
+
574
+
575
+ <p class="gets">(cont&#8217;d) ...Do you think all the trouble we spend sorting things ever pays off? Sometimes it seems like when things are sorted, everyone ends up seeing the same things, in the same order.</p>
576
+
577
+
578
+ <p class="puts">To the extent that categorizing/tagging makes information more accessible I think it&#8217;s useful. And that&#8217;s about it. I don&#8217;t think it influences the experience much. I&#8217;m wondering how things might look without categories.</p>
579
+
580
+
581
+ <p class="gets">2. It seems like the whole site is artistic in nature. Like: this trash is beautiful when out of context and when it&#8217;s all warped and damaged. Are there any libraries or algorithms that feel artful to you? That go well with art?</p>
582
+
583
+
584
+ <p class="puts">Definitely, but in a different way. I think beauty in code comes from mastery more than context. High levels of skill with a tool allow creativity to flow. So anything that encourages creation&#8230;</p>
585
+
586
+
587
+ <p class="puts">I&#8217;ve been programming for a while but my
588
+ tool belt still has that stiff leather feel. I can&#8217;t decide what goes
589
+ where and I keep swapping the hammer for a pair of pliers, using that
590
+ for a while, then switching back.</p>
591
+
592
+
593
+ <p class="gets">3. You&#8217;re using Mongrel on the site. Wow. Has it been a cinch?</p>
594
+
595
+
596
+ <p class="puts">It&#8217;s been great. The server is a dedicated box that is managed with Plesk and also hosts a couple other sites. I hadn&#8217;t used Plesk before and didn&#8217;t want to mess up the other sites or end up with a config that was overly complex. I was able to add one config file that was no more than ten lines long (a few rewrite rules and ProxyPass stuff), restart Apache, and the site was live &#8211; serving the other sites, the <span class="caps">FOUND</span> blog (WordPress), and handing off to Mongrel for the main site. It&#8217;s been humming along for a couple months now without any problems.</p>
597
+
598
+
599
+ <p class="gets">4. Hey, give us a freaky pic from the Found catalogue. Anything that just totally took you guys off guard or just made you die for hours.</p>
600
+
601
+
602
+ <p class="puts">Hehe. So many, and I&#8217;ve only seen the ones that get published. This one gets a lot of play.. still my favorite though: <a href="http://www.foundmagazine.com/find/558">#558</a></p>
603
+
604
+
605
+ <p class="gets">5. Lastly, and this is just out of curiousity, how do you use <span class="caps">RSS</span>? Do you use a reader regularly? Is it a part of your life or anything like that?</p>
606
+
607
+
608
+ <p class="puts">Nothing fancy. I recently used it to add feeds to a simple forum I built for Rails Day. NetNewsWire is the reader I use and it typically sits next to Mail. When I check email I usually give <span class="caps">NNN</span> a refresh too.</p>
609
+
610
+ </div>
611
+ </div>
612
+ <div class="entryFooter"> <a href="http://redhanded.hobix.com/5.gets/5GetsBradpauly.html">
613
+ <script type="text/javascript" language="JavaScript">
614
+ document.write((new Date(1160672412000)).strftime("%H:%M"));
615
+ </script>
616
+ <noscript>
617
+ 12:00 UTC
618
+ </noscript>
619
+ </a> |
620
+ <a href="http://redhanded.hobix.com/5.gets/5GetsBradpauly.html#comments">Comments (2)</a>
621
+ </div>
622
+
623
+
624
+ <a name="20061009"></a>
625
+ <div class="dayHeader">
626
+ <div class="dayBox">
627
+ <h2>Monday</h2>
628
+ <h3><a href="/2006/">2006</a>.<a href="/2006/10/">10</a>.<a href="/2006/10/09.html">09</a></h3>
629
+ </div>
630
+ </div>
631
+
632
+
633
+ <div class="entry">
634
+ <h2 class="entryTitle">String#chars Blessed by Rails Papacy as Fingertips Work to Dip Ruby's Toes in the UTF-8 Waters
635
+ <span class="entryPermalink"><a href="http://redhanded.hobix.com/cult/stringCharsBlessedByRailsPapacyAsFingertipsWorkToDipRubySToesInTheUtf8Waters.html"
636
+ title="Permanent link to &#8220;String#chars Blessed by Rails Papacy as Fingertips Work to Dip Ruby's Toes in the UTF-8 Waters&#8221;">#</a></span>
637
+ </h2>
638
+
639
+ <div class="entrySection">by <a href="http://whytheluckystiff.net/"
640
+ title="Visit why's homepage">why</a>
641
+ in <a href="/cult" title="List of entries in the &#8220;cult&#8221; category">cult</a>
642
+ </div>
643
+
644
+ <div class="entryContent">
645
+
646
+ <p>Cool, good news, the Fingertips&#8217; <a href="http://www.fngtps.com/2006/10/activesupport-multibyte">ActiveSupport::Multibyte</a> is checked into Rails. This equips every string with a <code>chars</code> method which offers a host of friendly Unicode-aware methods for the string. You know: <code>reverse</code>, <code>length</code>, <code>slice</code> and the like.</p>
647
+
648
+
649
+ <pre>
650
+ name = 'Claus Müller'
651
+ name.reverse #=&gt; "rell??M sualC"
652
+ name.length #=&gt; 13
653
+
654
+ name.chars.reverse.to_s #=&gt; "rellüM sualC"
655
+ name.chars.length #=&gt; 12
656
+ </pre>
657
+
658
+ <p>This is valuable, essential work. Thanks to Thijs, Manfred, Julik and related contributors. Along with <a href="http://git.bitwi.se/?p=ruby-character-encodings.git;a=summary">Nikolai&#8217;s work</a>, we&#8217;re on our way.</p>
659
+
660
+ </div>
661
+ </div>
662
+ <div class="entryFooter"> <a href="http://redhanded.hobix.com/cult/stringCharsBlessedByRailsPapacyAsFingertipsWorkToDipRubySToesInTheUtf8Waters.html">
663
+ <script type="text/javascript" language="JavaScript">
664
+ document.write((new Date(1160424215000)).strftime("%H:%M"));
665
+ </script>
666
+ <noscript>
667
+ 15:03 UTC
668
+ </noscript>
669
+ </a> |
670
+ <a href="http://redhanded.hobix.com/cult/stringCharsBlessedByRailsPapacyAsFingertipsWorkToDipRubySToesInTheUtf8Waters.html#comments">Comments (15)</a>
671
+ </div>
672
+
673
+ <div class="entry">
674
+ <h2 class="entryTitle">Ferret Creator on Judo and Text Indexing
675
+ <span class="entryPermalink"><a href="http://redhanded.hobix.com/cult/ferretCreatorOnJudoAndTextIndexing.html"
676
+ title="Permanent link to &#8220;Ferret Creator on Judo and Text Indexing&#8221;">#</a></span>
677
+ </h2>
678
+
679
+ <div class="entrySection">by <a href="http://whytheluckystiff.net/"
680
+ title="Visit why's homepage">why</a>
681
+ in <a href="/cult" title="List of entries in the &#8220;cult&#8221; category">cult</a>
682
+ </div>
683
+
684
+ <div class="entryContent">
685
+
686
+ <p>Okay, here we go. Pat Eyler has a really long interview with <a href="http://on-ruby.blogspot.com/2006/10/ruby-hacker-interview-dave-balmain.html">Dave Balmain</a>. This is so great, I actually was just searching for interviews with Balmain, but Google hadn&#8217;t indexed Pat&#8217;s yet. Dave is the creator of Ferret, people. I am cuckoo about Ferret. Talk about fast! And turning it on and fiddling with the switches: it&#8217;s just so much fun.</p>
687
+
688
+
689
+ <blockquote>
690
+ <p>After university I worked as a consultant, implementing <span class="caps">J2EE</span> applications. In 2004 I quit my job and moved to Japan to practice Judo. I worked as an English teacher for a year before starting training full-time. This left me a lot of free time to work on whatever I wanted to, leading to the birth of Ferret.</p>
691
+ </blockquote>
692
+
693
+
694
+ <p>Although <a href="http://ferret.davebalmain.com/trac">Ferret</a> is based on Lucene, it&#8217;s recently moved away from Lucene&#8217;s file format, but he mentions using DRb and JRuby to get around that. Some code examples, some talk about Ferret&#8217;s future. Such an exciting project.</p>
695
+
696
+ </div>
697
+ </div>
698
+ <div class="entryFooter"> <a href="http://redhanded.hobix.com/cult/ferretCreatorOnJudoAndTextIndexing.html">
699
+ <script type="text/javascript" language="JavaScript">
700
+ document.write((new Date(1160412295000)).strftime("%H:%M"));
701
+ </script>
702
+ <noscript>
703
+ 11:44 UTC
704
+ </noscript>
705
+ </a> |
706
+ <a href="http://redhanded.hobix.com/cult/ferretCreatorOnJudoAndTextIndexing.html#comments">Comments (7)</a>
707
+ </div>
708
+
709
+
710
+ <a name="20061006"></a>
711
+ <div class="dayHeader">
712
+ <div class="dayBox">
713
+ <h2>Friday</h2>
714
+ <h3><a href="/2006/">2006</a>.<a href="/2006/10/">10</a>.<a href="/2006/10/06.html">06</a></h3>
715
+ </div>
716
+ </div>
717
+
718
+
719
+ <div class="entry">
720
+ <h2 class="entryTitle">Evan's Camping Slides
721
+ <span class="entryPermalink"><a href="http://redhanded.hobix.com/inspect/evanSCampingSlides.html"
722
+ title="Permanent link to &#8220;Evan's Camping Slides&#8221;">#</a></span>
723
+ </h2>
724
+
725
+ <div class="entrySection">by <a href="http://whytheluckystiff.net/"
726
+ title="Visit why's homepage">why</a>
727
+ in <a href="/inspect" title="List of entries in the &#8220;inspect&#8221; category">inspect</a>
728
+ </div>
729
+
730
+ <div class="entryContent">
731
+
732
+ <p style="float:left"><a href="http://blog.evanweaver.com/files/camping%20presentation%208-5-06.swf"><img src="/images/evnspreso.jpg" alt="" /></a></p>
733
+
734
+
735
+ <p>The very campsmart and railswise Evan Weaver has put up his <a href="http://blog.evanweaver.com/articles/2006/10/06/introduction-to-camping-presentation">Camping slides</a> from a Philly gathering. One of the points I like about his slides: he starts by comparing Camping to <span class="caps">CGI</span>. Yes, gus, yes! Gus! The idea is to see if Ruby&#8217;s basic <span class="caps">CGI</span> lib can be inaugurated into modern times as a little morning-after pill.</p>
736
+
737
+
738
+ <p>Evan is often <a href="http://campingchannel.pbwiki.com/">#camping</a> and can be found tripping indian_chief into slime. Hank is a bike. If you&#8217;re looking for more Camping ramp-up, there&#8217;s a video among <a href="http://podcast.sdruby.com/">the San Diego collection</a>.</p>
739
+
740
+ </div>
741
+ </div>
742
+ <div class="entryFooter"> <a href="http://redhanded.hobix.com/inspect/evanSCampingSlides.html">
743
+ <script type="text/javascript" language="JavaScript">
744
+ document.write((new Date(1160153651000)).strftime("%H:%M"));
745
+ </script>
746
+ <noscript>
747
+ 11:54 UTC
748
+ </noscript>
749
+ </a> |
750
+ <a href="http://redhanded.hobix.com/inspect/evanSCampingSlides.html#comments">Comments (5)</a>
751
+ </div>
752
+
753
+
754
+ <a name="20061004"></a>
755
+ <div class="dayHeader">
756
+ <div class="dayBox">
757
+ <h2>Wednesday</h2>
758
+ <h3><a href="/2006/">2006</a>.<a href="/2006/10/">10</a>.<a href="/2006/10/04.html">04</a></h3>
759
+ </div>
760
+ </div>
761
+
762
+
763
+ <div class="entry">
764
+ <h2 class="entryTitle">A Lambda Camcorder
765
+ <span class="entryPermalink"><a href="http://redhanded.hobix.com/inspect/aLambdaCamcorder.html"
766
+ title="Permanent link to &#8220;A Lambda Camcorder&#8221;">#</a></span>
767
+ </h2>
768
+
769
+ <div class="entrySection">by <a href="http://whytheluckystiff.net/"
770
+ title="Visit why's homepage">why</a>
771
+ in <a href="/inspect" title="List of entries in the &#8220;inspect&#8221; category">inspect</a>
772
+ </div>
773
+
774
+ <div class="entryContent">
775
+
776
+ <p>Beware magic-haters, a hack from Mike Williams, wherein you do a bunch of method calls on an anonymous object and the recording can get dup&#8217;d to lambda format.</p>
777
+
778
+
779
+ <pre>
780
+ people.select(&#38;its.name.length &gt; 10)
781
+ </pre>
782
+
783
+ <p>It&#8217;s the <a href="http://www.dogbiscuit.org/mdub/weblog/Tech/Programming/Ruby/MethodMissingMagic">its</a> method that&#8217;s the camcorder, creating a blank MessageBuffer to tape on to.</p>
784
+
785
+ </div>
786
+ </div>
787
+ <div class="entryFooter"> <a href="http://redhanded.hobix.com/inspect/aLambdaCamcorder.html">
788
+ <script type="text/javascript" language="JavaScript">
789
+ document.write((new Date(1159991829000)).strftime("%H:%M"));
790
+ </script>
791
+ <noscript>
792
+ 14:57 UTC
793
+ </noscript>
794
+ </a> |
795
+ <a href="http://redhanded.hobix.com/inspect/aLambdaCamcorder.html#comments">Comments (10)</a>
796
+ </div>
797
+
798
+ <div class="entry">
799
+ <h2 class="entryTitle">Ripping Up Wikipedia, Subjugating It
800
+ <span class="entryPermalink"><a href="http://redhanded.hobix.com/inspect/rippingUpWikipediaSubjugatingIt.html"
801
+ title="Permanent link to &#8220;Ripping Up Wikipedia, Subjugating It&#8221;">#</a></span>
802
+ </h2>
803
+
804
+ <div class="entrySection">by <a href="http://whytheluckystiff.net/"
805
+ title="Visit why's homepage">why</a>
806
+ in <a href="/inspect" title="List of entries in the &#8220;inspect&#8221; category">inspect</a>
807
+ </div>
808
+
809
+ <div class="entryContent">
810
+
811
+ <p>There&#8217;s an article that covers <a href="http://shanesbrain.net/articles/2006/10/02/screen-scraping-wikipedia">taking apart Wikipedia pages</a> with Hpricot on the blog of Shane Vitarana. His commenters also point out the <a href="http://en.wikipedia.org/w/query.php">Wikipedia <span class="caps">API</span></a>, which is a fantastic way of getting at the raw data&#8212;in <span class="caps">YAML</span> even! Still, it gives you the raw Wiki text, untransformed. Hence Hpricot.</p>
812
+
813
+
814
+ <p>Anyway, I just want to make a couple suggestions for his script. These aren&#8217;t a big deal, just some shortcuts in Hpricot, which aren&#8217;t documented yet. Let&#8217;s start getting them known, you know?</p>
815
+
816
+
817
+ <p>First, a simple one: the Element#attributes hash can be used through Element#[].</p>
818
+
819
+
820
+ <pre>
821
+ #change /wiki/ links to point to full wikipedia path
822
+ (content/:a).each do |link|
823
+ unless link['href'].nil?
824
+ if link['href'] =~ %r!^/wiki/!
825
+ link['href'].sub!('/wiki/', 'http://en.wikipedia.org/wiki/')
826
+ end
827
+ end
828
+ end
829
+ </pre>
830
+
831
+ <p>In the section where Shane loops through a bunch of <span class="caps">CSS</span> selector and removes everything that matches, I think it&#8217;s quicker to join the separate <span class="caps">CSS</span> selectors with commas, to form a large selector which Hpricot can find with a single pass.</p>
832
+
833
+
834
+ <pre>
835
+ #remove unnecessary content and edit links
836
+ (content/items_to_remove.join(',')).remove
837
+ </pre>
838
+
839
+ <p>And lastly, I&#8217;ve <a href="http://code.whytheluckystiff.net/hpricot/changeset/54">checked in</a> a new <code>swap</code> method in which replaces an element with an <span class="caps">HTML</span> fragment.</p>
840
+
841
+
842
+ <pre>
843
+ #replace links to create new entries with plain text
844
+ (content/"a.new").each do |link|
845
+ link.swap(link['title'])
846
+ end
847
+ </pre>
848
+
849
+ <p>So, yeah. Little things. Hey, are there any other methods you&#8217;re itching for?</p>
850
+
851
+ </div>
852
+ </div>
853
+ <div class="entryFooter"> <a href="http://redhanded.hobix.com/inspect/rippingUpWikipediaSubjugatingIt.html">
854
+ <script type="text/javascript" language="JavaScript">
855
+ document.write((new Date(1159979042000)).strftime("%H:%M"));
856
+ </script>
857
+ <noscript>
858
+ 11:24 UTC
859
+ </noscript>
860
+ </a> |
861
+ <a href="http://redhanded.hobix.com/inspect/rippingUpWikipediaSubjugatingIt.html#comments">Comments (11)</a>
862
+ </div>
863
+
864
+
865
+ <a name="20061003"></a>
866
+ <div class="dayHeader">
867
+ <div class="dayBox">
868
+ <h2>Tuesday</h2>
869
+ <h3><a href="/2006/">2006</a>.<a href="/2006/10/">10</a>.<a href="/2006/10/03.html">03</a></h3>
870
+ </div>
871
+ </div>
872
+
873
+
874
+ <div class="entry">
875
+ <h2 class="entryTitle">Camping is Still Your 4k Pinkyframework!
876
+ <span class="entryPermalink"><a href="http://redhanded.hobix.com/inspect/campingIsStillYour4kPinkyframework.html"
877
+ title="Permanent link to &#8220;Camping is Still Your 4k Pinkyframework!&#8221;">#</a></span>
878
+ </h2>
879
+
880
+ <div class="entrySection">by <a href="http://whytheluckystiff.net/"
881
+ title="Visit why's homepage">why</a>
882
+ in <a href="/inspect" title="List of entries in the &#8220;inspect&#8221; category">inspect</a>
883
+ </div>
884
+
885
+ <div class="entryContent">
886
+
887
+ <p>See, still just 3909 bytes! And, yet, a sizeworthy <a href="http://camping.rubyforge.org/files/CHANGELOG.html"><span class="caps">CHANGELOG</span></a>!</p>
888
+
889
+
890
+ <pre style="background-color: #efd; font-size: 10px; height:200px; overflow: auto;">
891
+ %w[active_support markaby tempfile uri].map{|l|require l}
892
+ module Camping;Apps=[];C=self;S=IO.read(__FILE__).sub(/S=I.+$/,'')
893
+ P="Cam\ping Problem!";module Helpers;def R c,*g;p=/\(.+?\)/;g.inject(c.
894
+ urls.find{|x|x.scan(p).size==g.size}.dup){|s,a|s.sub p,C.escape((a[
895
+ a.class.primary_key]rescue a))}end;def URL c='/',*a;c=R(c,*a)if c.
896
+ respond_to?:urls;c=self/c;c="//"+@env.HTTP_HOST+c if c[/^\//];URI(c)end;def/p
897
+ p[/^\//]?@root+p : p end;def errors_for o;ul.errors{o.errors.each_full{|x|li x}
898
+ }if o.errors.any?end end;module Base;include Helpers;attr_accessor:input,
899
+ :cookies,:env,:headers,:body,:status,:root;def method_missing*a,&#38;b
900
+ a.shift if a[0]==:render;m=Mab.new({},self);s=m.capture{send(*a,&#38;b)};s=m.layout{s}if
901
+ /^_/!~a[0].to_s and m.respond_to?:layout;s end;def r s,b,h={};@status=s;@headers.
902
+ merge!h;@body=b end;def redirect*a;r 302,'','Location'=&gt;URL(*a)end;Z="\r\n"
903
+ def initialize r,e,m;e=H[e.to_hash];@status,@method,@env,@headers,@root=200,m.
904
+ downcase,e,{'Content-Type'=&gt;"text/html"},e.SCRIPT_NAME.sub(/\/$/,'')
905
+ @k=C.kp e.HTTP_COOKIE;q=C.qs_parse e.QUERY_STRING;@in=r
906
+ if%r|\Amultipart/form-.*boundary=\"?([^\";,]+)|n.match e.CONTENT_TYPE
907
+ b=/(?:\r?\n|\A)#{Regexp::quote("--#$1")}(?:--)?\r$/;until@in.eof?;fh=H[];for l in@in
908
+ case l;when Z;break;when/^Content-D.+?: form-data;/;fh.u H[*$'.
909
+ scan(/(?:\s(\w+)="([^"]+)")/).flatten];when/^Content-Type: (.+?)(\r$|\Z)/m;fh[
910
+ :type]=$1;end;end;fn=fh[:name];o=if fh[:filename];o=fh[:tempfile]=Tempfile.new(:C)
911
+ o.binmode;else;fh=""end;while l=@in.read(16384);if l=~b;o&lt;&lt;$`.chomp;@in.seek(-$'.
912
+ size,IO::SEEK_CUR);break;end;o&lt;&lt;l;end;q[fn]=fh if fn;fh[:tempfile].rewind if
913
+ fh.is_a?H;end;elsif@method=="post";q.u C.qs_parse(@in.read)end;@cookies,@input=
914
+ @k.dup,q.dup end;def service*a;@body=send(@method,*a)if respond_to?@method
915
+ @headers["Set-Cookie"]=@cookies.map{|k,v|"#{k}=#{C.escape(v)}; path=#{self/'/'
916
+ }"if v!=@k[k]}-[nil];self end;def to_s;"Status: #{@status}#{Z+@headers.map{|k,v|
917
+ [*v].map{|x|"#{k}: #{x}"}}*Z+Z*2+@body}"end;end
918
+ X=module Controllers;@r=[];class&lt;&lt;self;def r;@r;end;def R*u;r=@r;Class.new{
919
+ meta_def(:urls){u};meta_def(:inherited){|x|r&lt;&lt;x}}end;def M;def M;end;constants.map{|c|
920
+ k=const_get(c);k.send:include,C,Base,Models;r[0,0]=k if !r.include?k;k.meta_def(
921
+ :urls){["/#{c.downcase}"]}if !k.respond_to?:urls}end;def D p;r.map{|k|k.urls.
922
+ map{|x|return k,$~[1..-1]if p=~/^#{x}\/?$/}};[NotFound,[p]]end end;class
923
+ NotFound&lt;R();def get p;r(404,Mab.new{h1 P;h2 p+" not found"})end end;class
924
+ ServerError&lt;R();def get k,m,e;r(500,Mab.new{h1 P;h2"#{k}.#{m}";h3"#{e.class
925
+ } #{e.message}:";ul{e.backtrace.each{|bt|li(bt)}}}.to_s)end end;self;end;class&lt;&lt;
926
+ self;def goes m;eval S.gsub(/Camping/,m.to_s).gsub("A\pps=[]","Cam\ping::Apps&lt;&lt;\
927
+ self"),TOPLEVEL_BINDING;end;def escape s;s.to_s.gsub(/[^ \w.-]+/n){'%'+($&#38;.
928
+ unpack('H2'*$&#38;.size)*'%').upcase}.tr(' ','+')end;def un s;s.tr('+',' ').gsub(
929
+ /%([\da-f]{2})/in){[$1].pack('H*')}end;def qs_parse q,d='&#38;;';m=proc{|_,o,n|o.u(
930
+ n,&#38;m)rescue([*o]&lt;&lt;n)};q.to_s.split(/[#{d}] */n).inject(H[]){|h,p|k,v=un(p).
931
+ split('=',2);h.u k.split(/[\]\[]+/).reverse.inject(v){|x,i|H[i,x]},&#38;m}end;def
932
+ kp s;c=qs_parse(s,';,')end;def run r=$stdin,e=ENV;X.M;k,a=X.D un("/#{e[
933
+ 'PATH_INFO']}".gsub(/\/+/,'/'));k.new(r,e,(m=e['REQUEST_METHOD']||"GET")).Y.
934
+ service *a;rescue Exception=&gt;x;X::ServerError.new(r,e,'get').service(k,m,x)end
935
+ def method_missing m,c,*a;X.M;k=X.const_get(c).new(StringIO.new,H['HTTP_HOST',
936
+ '','SCRIPT_NAME','','HTTP_COOKIE',''],m.to_s);H.new(a.pop).each{|e,f|k.send(
937
+ "#{e}=",f)}if Hash===a[-1];k.service *a;end;end;module Views;include X,Helpers;end
938
+ module Models;autoload:Base,'camping/db';def Y;self;end;end;class Mab&lt;Markaby::Builder
939
+ include Views;def tag!*g,&amp;b;h=g[-1];[:href,:action,:src].map{|a|(h[a]=self/h[a])rescue
940
+ 0};super end end;H=HashWithIndifferentAccess;class H;def method_missing m,*a
941
+ m.to_s=~/=$/?self[$`]=a[0]:a==[]?self[m]:raise(NoMethodError,"#{m}")end
942
+ alias_method:u,:regular_update;end end
943
+ </pre>
944
+
945
+ <p>Did you know?</p>
946
+
947
+
948
+ <ul>
949
+ <li><a href="http://yurtcms.roberthahn.ca/">Yurt</a>, a new Camping <span class="caps">CMS</span> by Robert Hahn, uses no database?</li>
950
+ <li><a href="http://cheat.errtheblog.com/">Cheat</a>, a social cheatware camplication gets tons of hits almost all the time?</li>
951
+ <li><a href="http://bee.cloudbur.st/">Bee</a>, a personal honeyless bug tracker is jubilantly camping-camping-camping with a noseful of blogs?</li>
952
+ </ul>
953
+
954
+
955
+ <p style="text-align:center;"><img src="/images/camping-archer.png" alt="" /></p>
956
+
957
+
958
+ <p><a href="http://code.whytheluckystiff.net/camping/">Camping 1.5 is out!</a> <code>gem install camping --source code.whytheluckystiff.net</code> so you can see I&#8217;d never lie to you.</p>
959
+
960
+ </div>
961
+ </div>
962
+ <div class="entryFooter"> <a href="http://redhanded.hobix.com/inspect/campingIsStillYour4kPinkyframework.html">
963
+ <script type="text/javascript" language="JavaScript">
964
+ document.write((new Date(1159914054000)).strftime("%H:%M"));
965
+ </script>
966
+ <noscript>
967
+ 17:20 UTC
968
+ </noscript>
969
+ </a> |
970
+ <a href="http://redhanded.hobix.com/inspect/campingIsStillYour4kPinkyframework.html#comments">Comments (14)</a>
971
+ </div>
972
+
973
+
974
+ <a name="20061002"></a>
975
+ <div class="dayHeader">
976
+ <div class="dayBox">
977
+ <h2>Monday</h2>
978
+ <h3><a href="/2006/">2006</a>.<a href="/2006/10/">10</a>.<a href="/2006/10/02.html">02</a></h3>
979
+ </div>
980
+ </div>
981
+
982
+
983
+ <div class="entry">
984
+ <h2 class="entryTitle">These Yelps and Squeals are Totally Valid
985
+ <span class="entryPermalink"><a href="http://redhanded.hobix.com/bits/theseYelpsAndSquealsAreTotallyValid.html"
986
+ title="Permanent link to &#8220;These Yelps and Squeals are Totally Valid&#8221;">#</a></span>
987
+ </h2>
988
+
989
+ <div class="entrySection">by <a href="http://whytheluckystiff.net/"
990
+ title="Visit why's homepage">why</a>
991
+ in <a href="/bits" title="List of entries in the &#8220;bits&#8221; category">bits</a>
992
+ </div>
993
+
994
+ <div class="entryContent">
995
+
996
+ <p>Discovered by Jay Phillips, some syntactically correct interrobangling:</p>
997
+
998
+
999
+ <pre>
1000
+ wazup?!!!?!??1:!!??
1001
+ </pre>
1002
+
1003
+ <p>I love that <code>!!??</code> can be used as <code>true</code>. Jay is also <a href="http://jicksta.com/post/view/learn-ruby-from-me-at-my-free-seminar">teaching</a> a free Ruby class at the University of Texas at Dallas. (Seen among the <a href="http://www.bigbold.com/snippets/posts/show/2600">snips</a>.)</p>
1004
+
1005
+ </div>
1006
+ </div>
1007
+ <div class="entryFooter"> <a href="http://redhanded.hobix.com/bits/theseYelpsAndSquealsAreTotallyValid.html">
1008
+ <script type="text/javascript" language="JavaScript">
1009
+ document.write((new Date(1159806295000)).strftime("%H:%M"));
1010
+ </script>
1011
+ <noscript>
1012
+ 11:24 UTC
1013
+ </noscript>
1014
+ </a> |
1015
+ <a href="http://redhanded.hobix.com/bits/theseYelpsAndSquealsAreTotallyValid.html#comments">Comments (20)</a>
1016
+ </div>
1017
+
1018
+
1019
+ <a name="20060929"></a>
1020
+ <div class="dayHeader">
1021
+ <div class="dayBox">
1022
+ <h2>Friday</h2>
1023
+ <h3><a href="/2006/">2006</a>.<a href="/2006/09/">09</a>.<a href="/2006/09/29.html">29</a></h3>
1024
+ </div>
1025
+ </div>
1026
+
1027
+
1028
+ <div class="entry">
1029
+ <h2 class="entryTitle">Hack This Sign On a Remote Wood Floor
1030
+ <span class="entryPermalink"><a href="http://redhanded.hobix.com/inspect/hackASignOnSomeoneElseSWoodFloors.html"
1031
+ title="Permanent link to &#8220;Hack This Sign On a Remote Wood Floor&#8221;">#</a></span>
1032
+ </h2>
1033
+
1034
+ <div class="entrySection">by <a href="http://whytheluckystiff.net/"
1035
+ title="Visit why's homepage">why</a>
1036
+ in <a href="/inspect" title="List of entries in the &#8220;inspect&#8221; category">inspect</a>
1037
+ </div>
1038
+
1039
+ <div class="entryContent">
1040
+
1041
+ <p style="float:right"><img src="/images/brite-handed.jpg" style="padding-left:8px;" alt="" /></p>
1042
+
1043
+
1044
+ <p>Hey, whoa, Aaron Patterson&#8217;s got a great hack! Check this out: he just put out a library called <a href="http://tenderlovemaking.com/2006/09/28/new-ruby-betabrite-002/">BetaBrite</a>, for programming <span class="caps">LED</span> signs. Well, the kids on Ruby-Talk were like, &#8220;Except, we don&#8217;t have those signs.&#8221; So enterprising Aaron set up a webcam hooked to DRb and&#8230; seriously&#8230; you guessed it!</p>
1045
+
1046
+
1047
+ <pre>
1048
+ require 'drb'
1049
+
1050
+ obj = DRbObject.new_with_uri("druby://eviladmins.org:9000")
1051
+
1052
+ File.open("out.jpg", 'wb') { |a|
1053
+ a &lt;&lt; obj.write_simple(";D thx aaron!")
1054
+ }
1055
+ </pre>
1056
+
1057
+ <p>That&#8217;s can-do spirit, gents. My favorite angle on this: Aaron gets to sit there and watch everybody use his lib in realtime all day. Now I want a marquee for svn checkins.</p>
1058
+
1059
+ </div>
1060
+ </div>
1061
+ <div class="entryFooter"> <a href="http://redhanded.hobix.com/inspect/hackASignOnSomeoneElseSWoodFloors.html">
1062
+ <script type="text/javascript" language="JavaScript">
1063
+ document.write((new Date(1159570459000)).strftime("%H:%M"));
1064
+ </script>
1065
+ <noscript>
1066
+ 17:54 UTC
1067
+ </noscript>
1068
+ </a> |
1069
+ <a href="http://redhanded.hobix.com/inspect/hackASignOnSomeoneElseSWoodFloors.html#comments">Comments (11)</a>
1070
+ </div>
1071
+
1072
+ <div class="entry">
1073
+ <h2 class="entryTitle">(String < Enumerable).nil?
1074
+ <span class="entryPermalink"><a href="http://redhanded.hobix.com/inspect/theNewStringIsnTEnumerable.html"
1075
+ title="Permanent link to &#8220;(String < Enumerable).nil?&#8221;">#</a></span>
1076
+ </h2>
1077
+
1078
+ <div class="entrySection">by <a href="http://whytheluckystiff.net/"
1079
+ title="Visit why's homepage">why</a>
1080
+ in <a href="/inspect" title="List of entries in the &#8220;inspect&#8221; category">inspect</a>
1081
+ </div>
1082
+
1083
+ <div class="entryContent">
1084
+
1085
+ <p>So, it sounds like the 1.9 series will remove <code>Enumerable</code> from <code>String</code>&#8217;s ancestry, in favor of <code>String#lines</code>. All string iteration casts to an Array. Maybe I&#8217;m getting my hopes up, but all these string changes seem like portents of Unicode Times.</p>
1086
+
1087
+
1088
+ <pre>
1089
+ &gt;&gt; str = "pony\nwagon\nstungun\n"
1090
+ =&gt; "pony\nwagon\nstungun\n"
1091
+ &gt;&gt; str.max
1092
+ NoMethodError: undefined method `max' for "pony\nwagon\nstungun\n":String
1093
+ from (irb):2:in `Kernel#binding'
1094
+ &gt;&gt; str.lines.max
1095
+ =&gt; "wagon\n"
1096
+ </pre>
1097
+
1098
+ <p>Makes sense. Anyone else mourning the impotent string splat?</p>
1099
+
1100
+
1101
+ <pre>
1102
+ &gt;&gt; utilities = *str
1103
+ =&gt; ["pony\nwagon\nstungun\n"]
1104
+ </pre>
1105
+
1106
+ <p>Like a little rotary saw whose tooth got stuck. (from <a href="http://www.rubyist.net/~matz/20060921.html#p03">matz</a> and <a href="http://www.ruby-lang.org/cgi-bin/cvsweb.cgi/ruby/string.c?cvsroot=src&#38;r1=1.274&#38;r2=1.275">patch</a>.)</p>
1107
+
1108
+ </div>
1109
+ </div>
1110
+ <div class="entryFooter"> <a href="http://redhanded.hobix.com/inspect/theNewStringIsnTEnumerable.html">
1111
+ <script type="text/javascript" language="JavaScript">
1112
+ document.write((new Date(1159549433000)).strftime("%H:%M"));
1113
+ </script>
1114
+ <noscript>
1115
+ 12:03 UTC
1116
+ </noscript>
1117
+ </a> |
1118
+ <a href="http://redhanded.hobix.com/inspect/theNewStringIsnTEnumerable.html#comments">Comments (7)</a>
1119
+ </div>
1120
+
1121
+
1122
+ <a name="20060928"></a>
1123
+ <div class="dayHeader">
1124
+ <div class="dayBox">
1125
+ <h2>Thursday</h2>
1126
+ <h3><a href="/2006/">2006</a>.<a href="/2006/09/">09</a>.<a href="/2006/09/28.html">28</a></h3>
1127
+ </div>
1128
+ </div>
1129
+
1130
+
1131
+ <div class="entry">
1132
+ <h2 class="entryTitle">Open Up Your Wiki and We'll Finish it For You
1133
+ <span class="entryPermalink"><a href="http://redhanded.hobix.com/inspect/howToLetAnyoneElseFinishYourWiki.html"
1134
+ title="Permanent link to &#8220;Open Up Your Wiki and We'll Finish it For You&#8221;">#</a></span>
1135
+ </h2>
1136
+
1137
+ <div class="entrySection">by <a href="http://whytheluckystiff.net/"
1138
+ title="Visit why's homepage">why</a>
1139
+ in <a href="/inspect" title="List of entries in the &#8220;inspect&#8221; category">inspect</a>
1140
+ </div>
1141
+
1142
+ <div class="entryContent">
1143
+
1144
+ <p>I&#8217;m hoping the Freaky Freaky Sandbox will avail me of having to finish anything ever again. Instead, I can just stop. Whatever it is, leave it unfinished. Gently place a sandboxed wiki on it. And then all of you at home can each add five lines of code and that&#8217;s it!</p>
1145
+
1146
+
1147
+ <p style="text-align:center;"><img src="/images/tippytippytepee-1.png" alt="" /></p>
1148
+
1149
+
1150
+ <p>So, let&#8217;s get started on this sandboxed scriptable wiki. Step one, get some embedded Ruby in there. Here&#8217;s how.</p>
1151
+
1152
+
1153
+ <pre>
1154
+ %w(sandbox rubygems redcloth
1155
+ camping acts_as_versioned).each { |lib| require lib }
1156
+
1157
+ Camping.goes :Tepee
1158
+
1159
+ Tepee::Box = Sandbox.safe
1160
+ Tepee::Box.load "erbl.rb"
1161
+ </pre>
1162
+
1163
+ <p>I&#8217;m using <a href="http://code.whytheluckystiff.net/svn/camping/trunk/examples/tepee.rb">Tepee</a> as the base. Sandbox gets loaded first because if you load RubyGems first, it goes bonkers. So, we&#8217;re going to start up a little barebones sandbox and load the ERbLight library, which is written in pure Ruby. Just to keep it simple.</p>
1164
+
1165
+
1166
+ <p>Now to swap out the markup processor for a sandbox eval.</p>
1167
+
1168
+
1169
+ <pre>
1170
+ def markup str
1171
+ @boxx = nil
1172
+ begin
1173
+ str = Tepee::Box.eval("ERbLight.new(#{str.dump}).result")
1174
+ rescue Sandbox::Exception =&gt; @boxx
1175
+ end
1176
+ RedCloth.new(str, [ :hard_breaks ]).to_html
1177
+ end
1178
+ </pre>
1179
+
1180
+ <p>And that&#8217;s it. If the sandbox throws an exception, it&#8217;ll go in the <code>@boxx</code> ivar. It might be better to check for an exception when the user saves the page instead.</p>
1181
+
1182
+
1183
+ <p>So, this sandbox does <em>nothing</em>. I mean you can do math and string stuff and hashes and whatever, but it&#8217;s not that great. But come back in a few days and I&#8217;ll show you some more tricks for the <a href="http://code.whytheluckystiff.net/svn/sandbox/trunk/examples/tippytippytepee/">Tippy Tippy Tepee</a>.</p>
1184
+
1185
+ </div>
1186
+ </div>
1187
+ <div class="entryFooter"> <a href="http://redhanded.hobix.com/inspect/howToLetAnyoneElseFinishYourWiki.html">
1188
+ <script type="text/javascript" language="JavaScript">
1189
+ document.write((new Date(1159482938000)).strftime("%H:%M"));
1190
+ </script>
1191
+ <noscript>
1192
+ 17:35 UTC
1193
+ </noscript>
1194
+ </a> |
1195
+ <a href="http://redhanded.hobix.com/inspect/howToLetAnyoneElseFinishYourWiki.html#comments">Comments (20)</a>
1196
+ </div>
1197
+
1198
+
1199
+ </div>
1200
+
1201
+ </div>
1202
+
1203
+
1204
+
1205
+ </div>
1206
+
1207
+ </body>
1208
+ </html>