scrapes 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +22 -0
- data/README +123 -0
- data/demo/demo.rb +33 -0
- data/demo/pages/about.rb +32 -0
- data/demo/pages/main.rb +32 -0
- data/lib/scrapes.rb +41 -0
- data/lib/scrapes/cache.rb +110 -0
- data/lib/scrapes/cookbook.rb +53 -0
- data/lib/scrapes/cookies.rb +45 -0
- data/lib/scrapes/crawler.rb +97 -0
- data/lib/scrapes/hpricot.rb +110 -0
- data/lib/scrapes/initializer.rb +86 -0
- data/lib/scrapes/page.rb +319 -0
- data/lib/scrapes/rule_parser.rb +327 -0
- data/lib/scrapes/session.rb +155 -0
- data/lib/scrapes/to_proxy.rb +50 -0
- data/test/cache.rb +75 -0
- data/test/cookies.rb +34 -0
- data/test/crawler.rb +69 -0
- data/test/hpricot.rb +55 -0
- data/test/initializer.rb +54 -0
- data/test/lib/server.rb +63 -0
- data/test/page.rb +77 -0
- data/test/pages/foils.rb +61 -0
- data/test/pages/foils2.rb +38 -0
- data/test/pages/redhanded_entries.rb +36 -0
- data/test/pages/redhanded_main.rb +58 -0
- data/test/pages/rule_parser.rb +81 -0
- data/test/pages/simple.rb +21 -0
- data/test/public/foil72.html +10 -0
- data/test/public/foil73.html +9 -0
- data/test/public/foil74.html +11 -0
- data/test/public/foo.txt +1 -0
- data/test/public/index.html +20 -0
- data/test/public/redhanded.html +1208 -0
- data/test/public/rule_parser.html +21 -0
- data/test/public/simple.html +8 -0
- data/test/rule_parser.rb +151 -0
- data/test/session.rb +45 -0
- data/test/textcontent.rb +71 -0
- metadata +123 -0
data/test/pages/foils.rb
ADDED
@@ -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
|
data/test/public/foo.txt
ADDED
@@ -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> | <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> <a class=q href="/imghp?hl=en&ie=UTF-8&tab=wi">Images</a> <a class=q href="http://video.google.com/?hl=en&ie=UTF-8&tab=wv">Video</a> <a class=q href="http://news.google.com/nwshp?hl=en&ie=UTF-8&tab=wn">News</a> <a class=q href="/maps?hl=en&ie=UTF-8&tab=wl">Maps</a> <b><a href="/intl/en/options/" class=q onclick="this.blur();return togDisp(event);">more »</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 »</b></a></span></font></td></tr></table><table cellspacing=0 cellpadding=0><tr><td width=25%> </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> <a href=/advanced_search?hl=en>Advanced Search</a><br> <a href=/preferences?hl=en>Preferences</a><br> <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 Programs</a> - <a href=/services/>Business Solutions</a> - <a href=/intl/en/about.html>About Google</a></font><p><font size=-2>©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 » 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/">-> docs</a><br />
|
109
|
+
<a href="http://rubyforge.org/">-> wares</a><br />
|
110
|
+
<a href="http://rubygarden.org/ruby/">-> wiki</a><br />
|
111
|
+
<a href="http://www.sitepoint.com/forums/forumdisplay.php?f=227">-> forum</a><br />
|
112
|
+
<a href="http://www.rubyquiz.com/">-> quizzes</a><br />
|
113
|
+
<a href="http://planetruby.0x42.net/">-> planet</a><br />
|
114
|
+
<a href="http://meme.b9.com/cdates.html?channel=ruby-lang">-> 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/">-> wiki</a><br />
|
118
|
+
<a href="http://www.planetrubyonrails.org/">-> planet</a><br />
|
119
|
+
<a href="http://thesaq.com/rubyonrails/">-> 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&wl_glossary=gl1&wl_fl=3&wl_rurl=http%3A%2F%2Fwww.rubyist.net%2F%7Ematz%2F&wl_url=http%3A%2F%2Fwww.rubyist.net%2F%7Ematz%2F&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%3A%2F%2Fredhanded.hobix.com'><br />
|
160
|
+
<img src='/images/bubble_icon.gif' height='20' width='24' alt='Get Conversations about RedHanded » 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 “Denver Accord”">#</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 “inspect” 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’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 “Nic.d Gets Punct”">#</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 “cult” 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>—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—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 “He Paid to Go and Type”">#</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 “cult” 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’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 “The Soda Languages”">#</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 “cult” 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’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->v__dpy,
|
330
|
+
DefaultRootWindow((Display *)self->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’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 “Running Pugs Across Your Browser”">#</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 “cult” 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’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’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 “Stop-Motion Hacking and a Bit of Celebratory Flag Waving”">#</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 “cult” 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 “Yay, Matz is on the Cusp of Unveiling Ruby's Unicode Support!”">#</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 “cult” 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. ;-<</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 “The Least Surprised #13: Those Are Stars In Our Eyes”">#</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 “cult” 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 “Manfred Smacks Open a Camping Piñata”">#</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 “cult” 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 “5.gets BradPauly”">#</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 “5.gets” 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’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’ve just got this pile of litter (notes, photos, street junk and so on) and you’re basically interfacing technology with that mound of other folk’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 “related finds” 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’re guided.</p>
|
573
|
+
|
574
|
+
|
575
|
+
<p class="gets">(cont’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’s useful. And that’s about it. I don’t think it influences the experience much. I’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’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…</p>
|
585
|
+
|
586
|
+
|
587
|
+
<p class="puts">I’ve been programming for a while but my
|
588
|
+
tool belt still has that stiff leather feel. I can’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’re using Mongrel on the site. Wow. Has it been a cinch?</p>
|
594
|
+
|
595
|
+
|
596
|
+
<p class="puts">It’s been great. The server is a dedicated box that is managed with Plesk and also hosts a couple other sites. I hadn’t used Plesk before and didn’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 – serving the other sites, the <span class="caps">FOUND</span> blog (WordPress), and handing off to Mongrel for the main site. It’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’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 “String#chars Blessed by Rails Papacy as Fingertips Work to Dip Ruby's Toes in the UTF-8 Waters”">#</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 “cult” category">cult</a>
|
642
|
+
</div>
|
643
|
+
|
644
|
+
<div class="entryContent">
|
645
|
+
|
646
|
+
<p>Cool, good news, the Fingertips’ <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 #=> "rell??M sualC"
|
652
|
+
name.length #=> 13
|
653
|
+
|
654
|
+
name.chars.reverse.to_s #=> "rellüM sualC"
|
655
|
+
name.chars.length #=> 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’s work</a>, we’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 “Ferret Creator on Judo and Text Indexing”">#</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 “cult” 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’t indexed Pat’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’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’s recently moved away from Lucene’s file format, but he mentions using DRb and JRuby to get around that. Some code examples, some talk about Ferret’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 “Evan's Camping Slides”">#</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 “inspect” 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’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’re looking for more Camping ramp-up, there’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 “A Lambda Camcorder”">#</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 “inspect” 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’d to lambda format.</p>
|
777
|
+
|
778
|
+
|
779
|
+
<pre>
|
780
|
+
people.select(&its.name.length > 10)
|
781
|
+
</pre>
|
782
|
+
|
783
|
+
<p>It’s the <a href="http://www.dogbiscuit.org/mdub/weblog/Tech/Programming/Ruby/MethodMissingMagic">its</a> method that’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 “Ripping Up Wikipedia, Subjugating It”">#</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 “inspect” category">inspect</a>
|
807
|
+
</div>
|
808
|
+
|
809
|
+
<div class="entryContent">
|
810
|
+
|
811
|
+
<p>There’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—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’t a big deal, just some shortcuts in Hpricot, which aren’t documented yet. Let’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’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’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’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 “Camping is Still Your 4k Pinkyframework!”">#</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 “inspect” 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,&b
|
900
|
+
a.shift if a[0]==:render;m=Mab.new({},self);s=m.capture{send(*a,&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'=>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'=>"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<<$`.chomp;@in.seek(-$'.
|
912
|
+
size,IO::SEEK_CUR);break;end;o<<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<<self;def r;@r;end;def R*u;r=@r;Class.new{
|
919
|
+
meta_def(:urls){u};meta_def(:inherited){|x|r<<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<R();def get p;r(404,Mab.new{h1 P;h2 p+" not found"})end end;class
|
924
|
+
ServerError<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<<
|
926
|
+
self;def goes m;eval S.gsub(/Camping/,m.to_s).gsub("A\pps=[]","Cam\ping::Apps<<\
|
927
|
+
self"),TOPLEVEL_BINDING;end;def escape s;s.to_s.gsub(/[^ \w.-]+/n){'%'+($&.
|
928
|
+
unpack('H2'*$&.size)*'%').upcase}.tr(' ','+')end;def un s;s.tr('+',' ').gsub(
|
929
|
+
/%([\da-f]{2})/in){[$1].pack('H*')}end;def qs_parse q,d='&;';m=proc{|_,o,n|o.u(
|
930
|
+
n,&m)rescue([*o]<<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]},&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=>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<Markaby::Builder
|
939
|
+
include Views;def tag!*g,&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’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 “These Yelps and Squeals are Totally Valid”">#</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 “bits” 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 “Hack This Sign On a Remote Wood Floor”">#</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 “inspect” 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’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, “Except, we don’t have those signs.” So enterprising Aaron set up a webcam hooked to DRb and… seriously… 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 << obj.write_simple(";D thx aaron!")
|
1054
|
+
}
|
1055
|
+
</pre>
|
1056
|
+
|
1057
|
+
<p>That’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 “(String < Enumerable).nil?”">#</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 “inspect” 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>’s ancestry, in favor of <code>String#lines</code>. All string iteration casts to an Array. Maybe I’m getting my hopes up, but all these string changes seem like portents of Unicode Times.</p>
|
1086
|
+
|
1087
|
+
|
1088
|
+
<pre>
|
1089
|
+
>> str = "pony\nwagon\nstungun\n"
|
1090
|
+
=> "pony\nwagon\nstungun\n"
|
1091
|
+
>> str.max
|
1092
|
+
NoMethodError: undefined method `max' for "pony\nwagon\nstungun\n":String
|
1093
|
+
from (irb):2:in `Kernel#binding'
|
1094
|
+
>> str.lines.max
|
1095
|
+
=> "wagon\n"
|
1096
|
+
</pre>
|
1097
|
+
|
1098
|
+
<p>Makes sense. Anyone else mourning the impotent string splat?</p>
|
1099
|
+
|
1100
|
+
|
1101
|
+
<pre>
|
1102
|
+
>> utilities = *str
|
1103
|
+
=> ["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&r1=1.274&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 “Open Up Your Wiki and We'll Finish it For You”">#</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 “inspect” category">inspect</a>
|
1140
|
+
</div>
|
1141
|
+
|
1142
|
+
<div class="entryContent">
|
1143
|
+
|
1144
|
+
<p>I’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’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’s get started on this sandboxed scriptable wiki. Step one, get some embedded Ruby in there. Here’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’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’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 => @boxx
|
1175
|
+
end
|
1176
|
+
RedCloth.new(str, [ :hard_breaks ]).to_html
|
1177
|
+
end
|
1178
|
+
</pre>
|
1179
|
+
|
1180
|
+
<p>And that’s it. If the sandbox throws an exception, it’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’s not that great. But come back in a few days and I’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>
|