bridgeutopia-simple-rss 1.2.4
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +429 -0
- data/README +44 -0
- data/Rakefile +212 -0
- data/install.rb +40 -0
- data/lib/simple-rss.rb +164 -0
- data/simple-rss.gemspec +12 -0
- data/test/base/base_test.rb +72 -0
- data/test/data/atom.xml +45 -0
- data/test/data/not-rss.xml +8 -0
- data/test/data/rss09.rdf +79 -0
- data/test/data/rss20.xml +818 -0
- data/test/test_helper.rb +4 -0
- metadata +68 -0
data/test/data/atom.xml
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
2
|
+
<feed xmlns="http://www.w3.org/2005/Atom">
|
3
|
+
<rss:title type="text">dive into mark</title>
|
4
|
+
<subtitle type="html">
|
5
|
+
A <em>lot</em> of effort
|
6
|
+
went into making this effortless
|
7
|
+
</subtitle>
|
8
|
+
<updated>2005-07-31T12:29:29Z</updated>
|
9
|
+
<id>tag:example.org,2003:3</id>
|
10
|
+
<link rel="alternate" type="text/html"
|
11
|
+
hreflang="en" href="http://example.org/"/>
|
12
|
+
<link rel="self" type="application/atom+xml"
|
13
|
+
href="http://example.org/feed.atom"/>
|
14
|
+
<rights>Copyright (c) 2003, Mark Pilgrim</rights>
|
15
|
+
<generator uri="http://www.example.com/" version="1.0">
|
16
|
+
Example Toolkit
|
17
|
+
</generator>
|
18
|
+
<entry>
|
19
|
+
<title>Atom draft-07 snapshot</title>
|
20
|
+
<link rel="alternate" type="text/html"
|
21
|
+
href="http://example.org/2005/04/02/atom"/>
|
22
|
+
<link rel="enclosure" type="audio/mpeg" length="1337"
|
23
|
+
href="http://example.org/audio/ph34r_my_podcast.mp3"/>
|
24
|
+
<id>tag:example.org,2003:3.2397</id>
|
25
|
+
<updated>2005-07-31T12:29:29Z</updated>
|
26
|
+
<published>2003-12-13T08:29:29-04:00</published>
|
27
|
+
<author>
|
28
|
+
<name>Mark Pilgrim</name>
|
29
|
+
<uri>http://example.org/</uri>
|
30
|
+
<email>f8dy@example.com</email>
|
31
|
+
</author>
|
32
|
+
<contributor>
|
33
|
+
<name>Sam Ruby</name>
|
34
|
+
</contributor>
|
35
|
+
<contributor>
|
36
|
+
<name>Joe Gregorio</name>
|
37
|
+
</contributor>
|
38
|
+
<content type="xhtml" xml:lang="en"
|
39
|
+
xml:base="http://diveintomark.org/">
|
40
|
+
<div xmlns="http://www.w3.org/1999/xhtml">
|
41
|
+
<p><i>[Update: The Atom draft is finished.]</i></p>
|
42
|
+
</div>
|
43
|
+
</content>
|
44
|
+
</entry>
|
45
|
+
</feed>
|
data/test/data/rss09.rdf
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
<?xml version="1.0" encoding="ISO-8859-1"?>
|
2
|
+
|
3
|
+
<rdf:RDF
|
4
|
+
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
5
|
+
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
6
|
+
xmlns="http://my.netscape.com/rdf/simple/0.9/">
|
7
|
+
|
8
|
+
<channel>
|
9
|
+
<title>Slashdot</title>
|
10
|
+
<link>http://slashdot.org/</link>
|
11
|
+
<description>News for nerds, stuff that matters</description>
|
12
|
+
<dc:date>2005-09-09T02:52:31-07:00</dc:date>
|
13
|
+
</channel>
|
14
|
+
|
15
|
+
<image>
|
16
|
+
<title>Slashdot</title>
|
17
|
+
<url>http://images.slashdot.org/topics/topicslashdot.gif</url>
|
18
|
+
<link>http://slashdot.org/</link>
|
19
|
+
</image>
|
20
|
+
|
21
|
+
<item>
|
22
|
+
<title>JBoss - A Developer's Notebook</title>
|
23
|
+
<link>http://books.slashdot.org/article.pl?sid=05/08/29/1319236&from=rss</link>
|
24
|
+
<dc:date>2005-09-09T02:52:31-07:00</dc:date>
|
25
|
+
</item>
|
26
|
+
|
27
|
+
<item>
|
28
|
+
<title>Apple Hedges Its Bet on New Intel Chips</title>
|
29
|
+
<link>http://hardware.slashdot.org/article.pl?sid=05/08/29/1314219&from=rss</link>
|
30
|
+
</item>
|
31
|
+
|
32
|
+
<item>
|
33
|
+
<title>Beowulf Pioneer Lured From Cal Tech to LSU</title>
|
34
|
+
<link>http://slashdot.org/article.pl?sid=05/08/29/1035240&from=rss</link>
|
35
|
+
</item>
|
36
|
+
|
37
|
+
<item>
|
38
|
+
<title>Google Talk Claims Openness, Lacks S2S Support</title>
|
39
|
+
<link>http://it.slashdot.org/article.pl?sid=05/08/29/1022242&from=rss</link>
|
40
|
+
</item>
|
41
|
+
|
42
|
+
<item>
|
43
|
+
<title>The End of the Bar Code</title>
|
44
|
+
<link>http://slashdot.org/article.pl?sid=05/08/29/1020220&from=rss</link>
|
45
|
+
</item>
|
46
|
+
|
47
|
+
<item>
|
48
|
+
<title>2.6.13 Linux Kernel Released</title>
|
49
|
+
<link>http://linux.slashdot.org/article.pl?sid=05/08/29/0334205&from=rss</link>
|
50
|
+
</item>
|
51
|
+
|
52
|
+
<item>
|
53
|
+
<title>HOWTO: The Anti-Printer</title>
|
54
|
+
<link>http://hardware.slashdot.org/article.pl?sid=05/08/29/1016204&from=rss</link>
|
55
|
+
</item>
|
56
|
+
|
57
|
+
<item>
|
58
|
+
<title>OSDL Skeptical Of Joint Study with Microsoft</title>
|
59
|
+
<link>http://linux.slashdot.org/article.pl?sid=05/08/29/0625224&from=rss</link>
|
60
|
+
</item>
|
61
|
+
|
62
|
+
<item>
|
63
|
+
<title>New Mad Cow Test on the Horizon?</title>
|
64
|
+
<link>http://science.slashdot.org/article.pl?sid=05/08/29/0619259&from=rss</link>
|
65
|
+
</item>
|
66
|
+
|
67
|
+
<item>
|
68
|
+
<title>Coffee A Health Drink?</title>
|
69
|
+
<link>http://science.slashdot.org/article.pl?sid=05/08/29/0342207&from=rss</link>
|
70
|
+
</item>
|
71
|
+
|
72
|
+
<textinput>
|
73
|
+
<title>Search Slashdot</title>
|
74
|
+
<description>Search Slashdot stories</description>
|
75
|
+
<name>query</name>
|
76
|
+
<link>http://slashdot.org/search.pl</link>
|
77
|
+
</textinput>
|
78
|
+
|
79
|
+
</rdf:RDF>
|
data/test/data/rss20.xml
ADDED
@@ -0,0 +1,818 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/rss2full.xsl" type="text/xsl" media="screen"?>
|
3
|
+
<?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/itemcontent.css" type="text/css" media="screen"?>
|
4
|
+
<!-- generator="wordpress/1.5" -->
|
5
|
+
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
|
6
|
+
<channel>
|
7
|
+
<title>Technoblog</title>
|
8
|
+
<link>http://tech.rufy.com</link>
|
9
|
+
<description>Lucas Carlson's jounal of the technical ramblings. Contains tutorials, howto's, and rants and ravings.</description>
|
10
|
+
<pubDate>Thu, 25 Aug 2005 00:16:16 +0000</pubDate>
|
11
|
+
<generator>http://wordpress.org/?v=1.5</generator>
|
12
|
+
<language>en</language>
|
13
|
+
<atom:link xmlns:atom="http://purl.org/atom/ns#" rel="self" href="http://feeds.feedburner.com/rufytech" type="application/rss+xml" />
|
14
|
+
<feedburner:browserFriendly>This is an XML content feed. It is intended to be viewed in a newsreader or syndicated to another site.</feedburner:browserFriendly>
|
15
|
+
<item>
|
16
|
+
<title>some_string.starts_with? “Foo” || some_string.ends_with? “bar.”</title>
|
17
|
+
<link>http://feeds.feedburner.com/rufytech?m=68</link>
|
18
|
+
<comments>http://tech.rufy.com/entry/82#comments</comments>
|
19
|
+
<pubDate>Wed, 24 Aug 2005 13:33:34 +0000</pubDate>
|
20
|
+
<dc:creator>Lucas Carlson</dc:creator>
|
21
|
+
<category>Programming</category>
|
22
|
+
<category>Ruby</category>
|
23
|
+
<guid isPermaLink="false">http://tech.rufy.com/entry/82</guid>
|
24
|
+
<description><![CDATA[I also liked:
|
25
|
+
|
26
|
+
|
27
|
+
x = s.startswith('Go')
|
28
|
+
x = s.endswith('Go')
|
29
|
+
|
30
|
+
|
31
|
+
So I made:
|
32
|
+
|
33
|
+
|
34
|
+
class String
|
35
|
+
def starts_with?(str)
|
36
|
+
self.index( str ) == 0
|
37
|
+
end
|
38
|
+
|
39
|
+
def ends_with?(str)
|
40
|
+
self.rindex( str ) == self.length - str.length
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
So you can do this:
|
46
|
+
|
47
|
+
|
48
|
+
some_string.starts_with? 'Foo' || some_string.ends_with? 'bar.']]></description>
|
49
|
+
<content:encoded><![CDATA[<p>I also liked:</p>
|
50
|
+
<pre><code>
|
51
|
+
x = s.startswith('Go')
|
52
|
+
x = s.endswith('Go')
|
53
|
+
</code></pre>
|
54
|
+
<p>So I made:</p>
|
55
|
+
<pre><code>
|
56
|
+
class String
|
57
|
+
def starts_with?(str)
|
58
|
+
self.index( str ) == 0
|
59
|
+
end
|
60
|
+
|
61
|
+
def ends_with?(str)
|
62
|
+
self.rindex( str ) == self.length - str.length
|
63
|
+
end
|
64
|
+
end
|
65
|
+
</code></pre>
|
66
|
+
<p>So you can do this:</p>
|
67
|
+
<pre><code>
|
68
|
+
some_string.starts_with? 'Foo' || some_string.ends_with? 'bar.'
|
69
|
+
</code></pre>
|
70
|
+
|
71
|
+
<p><map name="google_ad_map_HjnZmg3KCS4L1EStAbud17sJePk_"><area shape="rect" href="http://imageads.googleadservices.com/pagead/imgclick/HjnZmg3KCS4L1EStAbud17sJePk_?pos=0" coords="1,2,367,28"/><area shape="rect" href="http://services.google.com/feedback/abg" coords="384,10,453,23"/></map><img usemap="#google_ad_map_HjnZmg3KCS4L1EStAbud17sJePk_" border="0" src="http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&client=ca-pub-8531813895929183&channel=2762548411&output=png&cuid=HjnZmg3KCS4L1EStAbud17sJePk_&url=http%3A%2F%2Ftech.rufy.com%2Fentry%2F82"/></p>]]></content:encoded>
|
72
|
+
<wfw:commentRSS>http://tech.rufy.com/entry/82/feed/</wfw:commentRSS>
|
73
|
+
<feedburner:origLink>http://tech.rufy.com/entry/82</feedburner:origLink>
|
74
|
+
</item>
|
75
|
+
<item>
|
76
|
+
<title>if some_object.in? [1, 2, 3]</title>
|
77
|
+
<link>http://feeds.feedburner.com/rufytech?m=67</link>
|
78
|
+
<comments>http://tech.rufy.com/entry/81#comments</comments>
|
79
|
+
<pubDate>Wed, 24 Aug 2005 12:53:46 +0000</pubDate>
|
80
|
+
<dc:creator>Lucas Carlson</dc:creator>
|
81
|
+
<category>Programming</category>
|
82
|
+
<category>Ruby</category>
|
83
|
+
<guid isPermaLink="false">http://tech.rufy.com/entry/81</guid>
|
84
|
+
<description><![CDATA[Looking over some Python code, I really really like the syntax:
|
85
|
+
|
86
|
+
|
87
|
+
if some_object in [1, 2, 3]:
|
88
|
+
do_something
|
89
|
+
|
90
|
+
|
91
|
+
So I wrote this:
|
92
|
+
|
93
|
+
|
94
|
+
class Object
|
95
|
+
def in?(collection)
|
96
|
+
collection.respond_to?(:include?) ? collection.include?(self) : false
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
So you can now do:
|
102
|
+
|
103
|
+
|
104
|
+
if some_object.in? [1, 2, 3]
|
105
|
+
do_something
|
106
|
+
end]]></description>
|
107
|
+
<content:encoded><![CDATA[<p>Looking over some Python code, I really really like the syntax:</p>
|
108
|
+
<pre><code>
|
109
|
+
if some_object in [1, 2, 3]:
|
110
|
+
do_something
|
111
|
+
</code></pre>
|
112
|
+
<p>So I wrote this:</p>
|
113
|
+
<pre><code>
|
114
|
+
class Object
|
115
|
+
def in?(collection)
|
116
|
+
collection.respond_to?(:include?) ? collection.include?(self) : false
|
117
|
+
end
|
118
|
+
end
|
119
|
+
</code></pre>
|
120
|
+
<p>So you can now do:</p>
|
121
|
+
<pre><code>
|
122
|
+
if some_object.in? [1, 2, 3]
|
123
|
+
do_something
|
124
|
+
end
|
125
|
+
</code></pre>
|
126
|
+
|
127
|
+
<p><map name="google_ad_map_xy10iLjEoZMSBVz1x6zAEe-YQvU_"><area shape="rect" href="http://imageads.googleadservices.com/pagead/imgclick/xy10iLjEoZMSBVz1x6zAEe-YQvU_?pos=0" coords="1,2,367,28"/><area shape="rect" href="http://services.google.com/feedback/abg" coords="384,10,453,23"/></map><img usemap="#google_ad_map_xy10iLjEoZMSBVz1x6zAEe-YQvU_" border="0" src="http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&client=ca-pub-8531813895929183&channel=2762548411&output=png&cuid=xy10iLjEoZMSBVz1x6zAEe-YQvU_&url=http%3A%2F%2Ftech.rufy.com%2Fentry%2F81"/></p>]]></content:encoded>
|
128
|
+
<wfw:commentRSS>http://tech.rufy.com/entry/81/feed/</wfw:commentRSS>
|
129
|
+
<feedburner:origLink>http://tech.rufy.com/entry/81</feedburner:origLink>
|
130
|
+
</item>
|
131
|
+
<item>
|
132
|
+
<title>Y Combinator’s 2005 Summer Founders Program: A Complete Dud</title>
|
133
|
+
<link>http://feeds.feedburner.com/rufytech?m=66</link>
|
134
|
+
<comments>http://tech.rufy.com/entry/80#comments</comments>
|
135
|
+
<pubDate>Wed, 10 Aug 2005 18:23:20 +0000</pubDate>
|
136
|
+
<dc:creator>Lucas Carlson</dc:creator>
|
137
|
+
<category>General</category>
|
138
|
+
<guid isPermaLink="false">http://tech.rufy.com/entry/80</guid>
|
139
|
+
<description><![CDATA[I know that by writing this I may well be killing any chances at future funding from Paul Graham and Co. over at Y Combinator, but this was downright atrocious. Let me preface this by saying I am personally disappointed because I applied to the Summer Founders Program and was rejected. From what I can [...]]]></description>
|
140
|
+
<content:encoded><![CDATA[<p>I know that by writing this I may well be killing any chances at future funding from Paul Graham and Co. over at <a href="http://ycombinator.com/">Y Combinator</a>, but this was downright atrocious. Let me preface this by saying I am personally disappointed because I applied to the Summer Founders Program and was rejected. From what I can tell, I can reproduce in a weekend what took these people 3 months to accomplish.</p>
|
141
|
+
<p><b>Background</b></p>
|
142
|
+
<p>Paul Graham started a VC for mini startups called Y Combinator. They gave 9 groups $6,000-10,000 PER PERSON to work on any website they wanted for 3 months. My entry was <a href="http://webcollaborator.com">Web Collaborator</a>. During my summer, I created <a href="http://printpromotion.com/">Print Promotion</a>, worked on a top secret project with Adaptive Path that will soon change the way you feel about blogging, and am now working with O’Reilly on an amazingly innovative project. Quite productive for 3 months.</p>
|
143
|
+
<p><b>Conclusion</b></p>
|
144
|
+
<p>In that same time, 2 of the 9 groups (groups consisted of at least 2-3 people) came up with the following:</p>
|
145
|
+
<ul>
|
146
|
+
<li><a href="http://reddit.com/">Reddit</a>: A rip-off of the ideas behind <a href="http://del.ici.ous/">Del.ici.ous<a /> and </a><a href="http://digg.com/">Digg</a> built in Lisp. (there apparently is more to the application than has been released, but I am not impressed so far)</li>
|
147
|
+
<li><a href="http://www.brainguppy.com/">Brain Guppy</a>: A cheap rip-off of <a href="hotornot.com">Hot or Not</a> for narcissistic geeks built in Ruby on Rails.</li>
|
148
|
+
<li><a href="http://stuffguppy.com/">Stuff Guppy</a>: A cheaper rip-off of Hot or Not where you rate whether “stuff” is cool or crappy, also built in Ruby on Rails. Their best dud ideas include selling crappy Cafepress t-shirts and showing ads. Question someone should have asked them: who wants to look at crap after 8 hours at work?</li>
|
149
|
+
</ul>
|
150
|
+
<p>What do they all have in common?</p>
|
151
|
+
<ul>
|
152
|
+
<li>They are all cheap rip-offs of other people’s ideas</li>
|
153
|
+
<li>They are hardly innovative</li>
|
154
|
+
<li>They have little-to-no technical merit, I can reproduce Stuff Guppy in a weekend. Alone.</li>
|
155
|
+
<li>They are not very popular</li>
|
156
|
+
<li><b>None of these have the potential to be a self-sustaining business</b></li>
|
157
|
+
</ul>
|
158
|
+
<p>What a waste of over $30,000 for the above web sites. Some of the sites made during the 24 hours of <a href="http://railsday.com/">Rails Day</a> were better than what these guys came up with. 24 HOURS! I am sorry Paul Graham and Co, but if this is what you have to show, I am totally unimpressed (though I still want the money to work on some ideas of mine :) ).</p>
|
159
|
+
<p>As a friend pointed out, “the key criterion here seems to be ‘would be fun to code’, not ‘people will want to use’ or ‘will make money’”. Which is terribly ironic since Paul constantly harps on people to focus on the later. Another case of do what I say, not what I do.</p>
|
160
|
+
<p><b>Update</b>: Maybe 3 of 9 isn’t as big a sample as I thought. I just came across another one: <a href="http://www.clickfacts.com/">ClickFacts</a>. It seems that ClickFacts has attempted to assert itself as an expert on ad fraud. To me though, this seems like they were thinking “what would Google buy?”, which is better than the 3 mentioned above but to me it seems cheep and shallow. Just my impression.</p>
|
161
|
+
<p><a href="http://radar.oreilly.com/archives/2005/08/y_combinators_s.html">This account</a> says that “at least half of the startups in the program are seriously cool” so maybe I have just seen the bad half.
|
162
|
+
</p>
|
163
|
+
|
164
|
+
<p><map name="google_ad_map_6KdJ7yKQbjJvQcCka90EEwn44NE_"><area shape="rect" href="http://imageads.googleadservices.com/pagead/imgclick/6KdJ7yKQbjJvQcCka90EEwn44NE_?pos=0" coords="1,2,367,28"/><area shape="rect" href="http://services.google.com/feedback/abg" coords="384,10,453,23"/></map><img usemap="#google_ad_map_6KdJ7yKQbjJvQcCka90EEwn44NE_" border="0" src="http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&client=ca-pub-8531813895929183&channel=2762548411&output=png&cuid=6KdJ7yKQbjJvQcCka90EEwn44NE_&url=http%3A%2F%2Ftech.rufy.com%2Fentry%2F80"/></p>]]></content:encoded>
|
165
|
+
<wfw:commentRSS>http://tech.rufy.com/entry/80/feed/</wfw:commentRSS>
|
166
|
+
<feedburner:origLink>http://tech.rufy.com/entry/80</feedburner:origLink>
|
167
|
+
</item>
|
168
|
+
<item>
|
169
|
+
<title>OSCon 2005: Lucas</title>
|
170
|
+
<link>http://feeds.feedburner.com/rufytech?m=65</link>
|
171
|
+
<comments>http://tech.rufy.com/entry/79#comments</comments>
|
172
|
+
<pubDate>Mon, 08 Aug 2005 11:43:47 +0000</pubDate>
|
173
|
+
<dc:creator>Lucas Carlson</dc:creator>
|
174
|
+
<category>General</category>
|
175
|
+
<guid isPermaLink="false">http://tech.rufy.com/entry/79</guid>
|
176
|
+
<description><![CDATA[OSCon 2005: Lucas
|
177
|
+
|
178
|
+
Originally uploaded by x180.
|
179
|
+
|
180
|
+
|
181
|
+
I was shot at OSCON. Thanks Duncan!]]></description>
|
182
|
+
<content:encoded><![CDATA[<div style="float: right; margin-left: 10px; margin-bottom: 10px;">
|
183
|
+
<a href="http://www.flickr.com/photos/x180/31863860/" title="photo sharing"><img src="http://photos21.flickr.com/31863860_c890933cc7_m.jpg" alt="" style="border: solid 2px #000000;" /></a><br />
|
184
|
+
<br />
|
185
|
+
<span style="font-size: 0.9em; margin-top: 0px;"><br />
|
186
|
+
<a href="http://www.flickr.com/photos/x180/31863860/">OSCon 2005: Lucas</a><br />
|
187
|
+
<br />
|
188
|
+
Originally uploaded by <a href="http://www.flickr.com/people/x180/">x180</a>.<br />
|
189
|
+
</span>
|
190
|
+
</div>
|
191
|
+
<p>I was shot at OSCON. Thanks Duncan!<br />
|
192
|
+
<br clear="all" />
|
193
|
+
</p>
|
194
|
+
|
195
|
+
<p><map name="google_ad_map_qm8OINy9NNnaQGhBVqKLf4oRymQ_"><area shape="rect" href="http://imageads.googleadservices.com/pagead/imgclick/qm8OINy9NNnaQGhBVqKLf4oRymQ_?pos=0" coords="1,2,367,28"/><area shape="rect" href="http://services.google.com/feedback/abg" coords="384,10,453,23"/></map><img usemap="#google_ad_map_qm8OINy9NNnaQGhBVqKLf4oRymQ_" border="0" src="http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&client=ca-pub-8531813895929183&channel=2762548411&output=png&cuid=qm8OINy9NNnaQGhBVqKLf4oRymQ_&url=http%3A%2F%2Ftech.rufy.com%2Fentry%2F79"/></p>]]></content:encoded>
|
196
|
+
<wfw:commentRSS>http://tech.rufy.com/entry/79/feed/</wfw:commentRSS>
|
197
|
+
<feedburner:origLink>http://tech.rufy.com/entry/79</feedburner:origLink>
|
198
|
+
</item>
|
199
|
+
<item>
|
200
|
+
<title>OSCON 2005: Matz Talks about Yielding to the Power of Blocks in Ruby</title>
|
201
|
+
<link>http://feeds.feedburner.com/rufytech?m=64</link>
|
202
|
+
<comments>http://tech.rufy.com/entry/78#comments</comments>
|
203
|
+
<pubDate>Thu, 04 Aug 2005 08:33:42 +0000</pubDate>
|
204
|
+
<dc:creator>Lucas Carlson</dc:creator>
|
205
|
+
<category>General</category>
|
206
|
+
<guid isPermaLink="false">http://tech.rufy.com/entry/78</guid>
|
207
|
+
<description><![CDATA[I am sitting and waiting for Matz to talk about blocks right now. Keep watching, I will post notes as I go.
|
208
|
+
|
209
|
+
The room is packed with people even sitting on the floor to get a peak.
|
210
|
+
|
211
|
+
Unlike many of the other talks, many people are taking pictures of this one... mainly of the audience. I guess [...]]]></description>
|
212
|
+
<content:encoded><![CDATA[<p>I am sitting and waiting for Matz to talk about blocks right now. Keep watching, I will post notes as I go.</p>
|
213
|
+
<p>The room is packed with people even sitting on the floor to get a peak.</p>
|
214
|
+
<p>Unlike many of the other talks, many people are taking pictures of this one… mainly of the audience. I guess they find it as interesting as I do that people are crawling over themselves to get to this talk.<br />
|
215
|
+
<a id="more-78"></a></p>
|
216
|
+
<ul>
|
217
|
+
<li>The secret of Ruby’s attraction is blocks</li>
|
218
|
+
</ul>
|
219
|
+
<ul>
|
220
|
+
<li>Last year: No Ruby Track at <span class="caps">OSCON</span></li>
|
221
|
+
<li>Last year: 65 attendees to RubyConf</li>
|
222
|
+
</ul>
|
223
|
+
<ul>
|
224
|
+
<li>This year: Ruby Track at <span class="caps">OSCON</span></li>
|
225
|
+
<li>This year: Ruby tutorials are most popular</li>
|
226
|
+
<li>This year: More than 250 pre-registered for RubyConf</li>
|
227
|
+
</ul>
|
228
|
+
<h3>But Why?</h3>
|
229
|
+
<ul>
|
230
|
+
<li>Hacker Preference – Paul Graham</li>
|
231
|
+
<li>A Killer Application – Ruby on Rails
|
232
|
+
<ul>
|
233
|
+
<li>Attractive Enough</li>
|
234
|
+
<li>User Bait</li>
|
235
|
+
<li>Gets people used to the language</li>
|
236
|
+
<li>“I am sure that Python people will catch up” (in jest)</li>
|
237
|
+
</ul>
|
238
|
+
</li>
|
239
|
+
</ul>
|
240
|
+
<h3>Ruby on Rails</h3>
|
241
|
+
<ul>
|
242
|
+
<li>Claimed more than 10x productivity than typical Java Web Development</li>
|
243
|
+
<li>Convention over Configuration</li>
|
244
|
+
<li>Following <span class="caps">DRY</span> principles</li>
|
245
|
+
</ul>
|
246
|
+
<h3>DRY: Don’t Repeat Yourself</h3>
|
247
|
+
<ul>
|
248
|
+
<li>One of the most important principles in Programming</li>
|
249
|
+
<li>The source of productivity</li>
|
250
|
+
</ul>
|
251
|
+
<ul>
|
252
|
+
<li>What enables Rails productivity and attracts Alpha Geeks like yourself</li>
|
253
|
+
<li>That something is the dynamic nature inherited from Lisp and Smalltalk</li>
|
254
|
+
<li>In Familiar Syntax</li>
|
255
|
+
</ul>
|
256
|
+
<h3>Block</h3>
|
257
|
+
<ul>
|
258
|
+
<li>Unique and poserful
|
259
|
+
<ul>
|
260
|
+
<li>Makes it very attractive</li>
|
261
|
+
<li>Power of Higher Order Function</li>
|
262
|
+
<li>Closures and Syntax are powerful</li>
|
263
|
+
</ul>
|
264
|
+
</li>
|
265
|
+
<li>CollectionClosureMethod—Read this essay if you can’t stand my poor english</li>
|
266
|
+
</ul>
|
267
|
+
<p><code>
|
268
|
+
<pre>
|
269
|
+
employees.each do |e|
|
270
|
+
e.do_something
|
271
|
+
end
|
272
|
+
|
273
|
+
managers = employees.select {|e| e.manager?}
|
274
|
+
|
275
|
+
offices = employees.collect {|e| e.office}
|
276
|
+
|
277
|
+
sorted_employees = employees.sort_by {|e| e.lastname}
|
278
|
+
</pre>
|
279
|
+
</code></p>
|
280
|
+
<ul>
|
281
|
+
<li>No difference between { } and do … end except precidence</li>
|
282
|
+
<li>A higher order function is a function that takes another function as an argument</li>
|
283
|
+
<li>C’s qsort is an example of a higher order function since the function takes a comparison in its argument</li>
|
284
|
+
</ul>
|
285
|
+
<h3>Closure</h3>
|
286
|
+
<ul>
|
287
|
+
<li>Sharing local variables among functions</li>
|
288
|
+
</ul>
|
289
|
+
<p><code>
|
290
|
+
<pre>
|
291
|
+
def high_paid_employees(employees, limit)
|
292
|
+
employees.collect{|e| e.salary > limit}
|
293
|
+
end
|
294
|
+
</pre>
|
295
|
+
</code></p>
|
296
|
+
<ul>
|
297
|
+
<li>Notice that limit is used <span class="caps">WITHIN</span> the block</li>
|
298
|
+
</ul>
|
299
|
+
<p><code>
|
300
|
+
<pre>
|
301
|
+
def stack_closure
|
302
|
+
stack = []
|
303
|
+
push = lambda {|x| stack.push(x)}
|
304
|
+
pop = lambda {stack.pop}
|
305
|
+
pop = lambda {stack[-1]}
|
306
|
+
return push, pop, top
|
307
|
+
end
|
308
|
+
|
309
|
+
pusher, popper, topper = stack_closures()
|
310
|
+
pusher.call(10)
|
311
|
+
pusher.call(20)
|
312
|
+
popper.call # => 20
|
313
|
+
topper.call # => 10
|
314
|
+
</pre>
|
315
|
+
</code></p>
|
316
|
+
<h3>Syntax</h3>
|
317
|
+
<ul>
|
318
|
+
<li>Every language with closures can do the same thing. What’s the difference? Syntax</li>
|
319
|
+
<li>Lisp and smalltalk’s syntax are more convoluted</li>
|
320
|
+
<li>Python has something but not as easy to read</li>
|
321
|
+
<li>Ruby’s syntax for a block and block invocation is different</li>
|
322
|
+
<li>Just add a block at the end of a method call</li>
|
323
|
+
<li>It’s easy to emulate a new control structure</li>
|
324
|
+
</ul>
|
325
|
+
<h3>Syntax Matters</h3>
|
326
|
+
<p><code>
|
327
|
+
<pre>
|
328
|
+
# C
|
329
|
+
|
330
|
+
for (int i=0; i<3; i++) {
|
331
|
+
do_something();
|
332
|
+
}
|
333
|
+
|
334
|
+
# Ruby
|
335
|
+
|
336
|
+
3.times do
|
337
|
+
do_something
|
338
|
+
end
|
339
|
+
</pre>
|
340
|
+
</code></p>
|
341
|
+
<ul>
|
342
|
+
<li>You might think that the C version is “macho” but it is not</li>
|
343
|
+
<li>Ruby is ultimate simplicity</li>
|
344
|
+
</ul>
|
345
|
+
<p><code>
|
346
|
+
<pre>
|
347
|
+
(setq new-list (mapcar (lambda (e) (do-process e)) list))
|
348
|
+
</pre>
|
349
|
+
</code></p>
|
350
|
+
<ul>
|
351
|
+
<li>Block covers macro useage in Lisp</li>
|
352
|
+
<li>Hates Smalltalk’s mixture of braces and parentheses</li>
|
353
|
+
</ul>
|
354
|
+
<h3>Block invocation</h3>
|
355
|
+
<ul>
|
356
|
+
<li>Either: yield, call, or passing functions</li>
|
357
|
+
<li>Passing a block argument with an <code>&</code> in the argument list</li>
|
358
|
+
<li>Why 3 styles of invocation:
|
359
|
+
<ul>
|
360
|
+
<li>Historical reason: yield comes first from <span class="caps">CLU</span></li>
|
361
|
+
<li>Performance reason: plain yield did not need object creation (more efficient)</li>
|
362
|
+
<li>But the argument is more explicit</li>
|
363
|
+
</ul>
|
364
|
+
</li>
|
365
|
+
</ul>
|
366
|
+
<h3>Block Usuages</h3>
|
367
|
+
<ul>
|
368
|
+
<li>Iteration (<code>each</code>, <code>upto</code>, <code>downto</code>)</li>
|
369
|
+
<li>Sort and comparison (sort_by, sort, max, max_by)</li>
|
370
|
+
<li>Ensuring post process</li>
|
371
|
+
</ul>
|
372
|
+
<p>Bad way:<br />
|
373
|
+
<code>
|
374
|
+
<pre>
|
375
|
+
f = open(path)
|
376
|
+
begin
|
377
|
+
... something with f ...
|
378
|
+
ensure
|
379
|
+
f.close
|
380
|
+
end
|
381
|
+
</pre>
|
382
|
+
</code></p>
|
383
|
+
<p>Good way<br />
|
384
|
+
<code>
|
385
|
+
<pre>
|
386
|
+
open(path) do |f|
|
387
|
+
... something with f ...
|
388
|
+
end
|
389
|
+
</pre>
|
390
|
+
</code></p>
|
391
|
+
<p><strong> Conditionals (select, detect, reject, collect, find_all, find, delete_if)<br />
|
392
|
+
<code>
|
393
|
+
<pre>
|
394
|
+
result = []
|
395
|
+
art.each do |x| if x%2 0; push x; end; end
|
396
|
+
ary.collect{|x| x%2 0}
|
397
|
+
</pre>
|
398
|
+
</code></p>
|
399
|
+
<p></strong> Callbacks<br />
|
400
|
+
<strong> Structure (like <span class="caps">XML</span> generation via builder)<br />
|
401
|
+
</strong> Enumarable<br />
|
402
|
+
** <code>require 'enumerator'; include Enumerable</code> to get several methods for free by defining the each method (18 methods including reject, select, max, etc. for free)<br />
|
403
|
+
<code>
|
404
|
+
<pre>
|
405
|
+
ary = [4,2,1]
|
406
|
+
ary.to_enum(:each_with_index).reject { |x,i| i%2==0 } # => [[4,0], [1,3]]
|
407
|
+
</pre>
|
408
|
+
</code></p>
|
409
|
+
<ul>
|
410
|
+
<li>You can specify what you want more clearly and cleanly than other languages</li>
|
411
|
+
</ul>
|
412
|
+
<h3>Questions</h3>
|
413
|
+
<ul>
|
414
|
+
<li>What is your blog?
|
415
|
+
<ul>
|
416
|
+
<li><a href="http://www.rubyist.net/~matz/">http://www.rubyist.net/<sub>matz/</a></li>
|
417
|
+
</ul>
|
418
|
+
</li>
|
419
|
+
<li>Slides <span class="caps">URL</span>?
|
420
|
+
<ul>
|
421
|
+
<li><a href="http://www.rubyist.net/~matz/slides/oscon2005/">http://www.rubyist.net/</sub>matz/slides/oscon2005/</a></li>
|
422
|
+
</ul>
|
423
|
+
</li>
|
424
|
+
<li>Can you talk about your plans to change blocks in Ruby 2.0?
|
425
|
+
<ul>
|
426
|
+
<li>We have no plans to change blocks, just the lambda definition (using → operator instead of <code>lambda</code> which is too long and clumbsy, being a unicode operator)</li>
|
427
|
+
<li>Take → from Perl 6 since Perl 6 took so much from Ruby ;)</li>
|
428
|
+
</ul>
|
429
|
+
</li>
|
430
|
+
<li>Can you pass multiple blocks into a function?
|
431
|
+
<ul>
|
432
|
+
<li>No, only one. That restriction is not always a bad thing. By restricting to one block it is easier to emulate the control structure. If you want multiple blocks you can pass lambdas as arguments explicitly.</li>
|
433
|
+
</ul>
|
434
|
+
</li>
|
435
|
+
<li>What else is coming up in the near future for Ruby
|
436
|
+
<ul>
|
437
|
+
<li>A faster VM and several changes are planned for real multiple values in Ruby 2</li>
|
438
|
+
</ul>
|
439
|
+
</li>
|
440
|
+
<li>Is there a chance there might be a code browser smalltalk style working with Ruby?
|
441
|
+
<ul>
|
442
|
+
<li>Someone in the community is working on that. There is the Eclipse plugin and FreeRIDE.</li>
|
443
|
+
</ul>
|
444
|
+
</li>
|
445
|
+
<li>Are we going to get any cool new modules in the <span class="caps">STDLIB</span>?
|
446
|
+
<ul>
|
447
|
+
<li>I just don’t remember, but very few just because it is fairly easy to get the new libraries with Rubygems so we don’t need to bundle everything. We are planning to make package management like Rubygems standard.</li>
|
448
|
+
</ul>
|
449
|
+
</li>
|
450
|
+
<li>Ruby allows you to add and alias system methods and classes. This is good and bad because I don’t want other libraries to modify the classes. Anything I can do to protect?
|
451
|
+
<ul>
|
452
|
+
<li>Currently there is no way to prevent that. I have a vague idea to select a namespace that prevents overriding functions and limit it in that file. I haven’t yet figured out the idea to implement it efficiently, but I can tell that there is this potential problem that I want to solve your concern but don’t know how yet.</li>
|
453
|
+
</ul>
|
454
|
+
</li>
|
455
|
+
</ul>
|
456
|
+
<h3>Notes</h3>
|
457
|
+
<ul>
|
458
|
+
<li>Matz uses Emacs and some version of Linux ons small panasonic laptop</li>
|
459
|
+
</ul>
|
460
|
+
|
461
|
+
<p><map name="google_ad_map_gbFcU9elMIp1wtY0qBVzK.qLrJg_"><area shape="rect" href="http://imageads.googleadservices.com/pagead/imgclick/gbFcU9elMIp1wtY0qBVzK.qLrJg_?pos=0" coords="1,2,367,28"/><area shape="rect" href="http://services.google.com/feedback/abg" coords="384,10,453,23"/></map><img usemap="#google_ad_map_gbFcU9elMIp1wtY0qBVzK.qLrJg_" border="0" src="http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&client=ca-pub-8531813895929183&channel=2762548411&output=png&cuid=gbFcU9elMIp1wtY0qBVzK.qLrJg_&url=http%3A%2F%2Ftech.rufy.com%2Fentry%2F78"/></p>]]></content:encoded>
|
462
|
+
<wfw:commentRSS>http://tech.rufy.com/entry/78/feed/</wfw:commentRSS>
|
463
|
+
<feedburner:origLink>http://tech.rufy.com/entry/78</feedburner:origLink>
|
464
|
+
</item>
|
465
|
+
<item>
|
466
|
+
<title>OSCON 2005: Business For Geeks</title>
|
467
|
+
<link>http://feeds.feedburner.com/rufytech?m=63</link>
|
468
|
+
<comments>http://tech.rufy.com/entry/77#comments</comments>
|
469
|
+
<pubDate>Mon, 01 Aug 2005 09:49:53 +0000</pubDate>
|
470
|
+
<dc:creator>Lucas Carlson</dc:creator>
|
471
|
+
<category>General</category>
|
472
|
+
<guid isPermaLink="false">http://tech.rufy.com/entry/77</guid>
|
473
|
+
<description><![CDATA[I am at Business for Geeks right now waiting for Marc Hedlund to teach me fun stuff.
|
474
|
+
|
475
|
+
the ideaDon’t talk about how the product works. Tell them about the market.“I’ve got this idea” Obsess about the need I will fulfillTalk about the needYou will never have an idea where everybody likes the idea/company nameDon’t sit down [...]]]></description>
|
476
|
+
<content:encoded><![CDATA[<p>I am at <a href="http://conferences.oreillynet.com/cs/os2005/view/e_sess/7062">Business for Geeks</a> right now waiting for <a href="http://conferences.oreillynet.com/cs/os2005/view/e_spkr/604">Marc Hedlund</a> to teach me fun stuff.</p>
|
477
|
+
<h2>the idea</h2>
|
478
|
+
<ul>
|
479
|
+
<li>Don’t talk about how the product works. Tell them about the market.</li>
|
480
|
+
<li>“I’ve got this idea” </li>
|
481
|
+
<li>Obsess about the need I will fulfill</li>
|
482
|
+
<li>Talk about the need</li>
|
483
|
+
<li>You will never have an idea where everybody likes the idea/company name</li>
|
484
|
+
<li>Don’t sit down for a day/week/month to come up with ideas to pick the best one</li>
|
485
|
+
<li>“the idea that won’t leave you alone” – the one you can’t talk yourself into but you can’t stop thinking about</li>
|
486
|
+
<li>Doesn’t match with a VC model of idea finding</li>
|
487
|
+
<li>Every VC told Google that their idea was stupid, that they had to put banner ads, Google stuck to their ideals</li>
|
488
|
+
</ul>
|
489
|
+
<p>Idea that failed: “Popular Power” </p>
|
490
|
+
<ul>
|
491
|
+
<li>Like <span class="caps">SETI</span>, screen saver that does large computing tasks</li>
|
492
|
+
<li>Recycling for computing time</li>
|
493
|
+
<li>First commercial company to do this in 2000</li>
|
494
|
+
<li>Idea came from Lucas Films star wars episode 1: wanted to make an applet that would be used to render one frame of episode 1 on each computer</li>
|
495
|
+
<li>Sold to companies who had many computers behind a firewall</li>
|
496
|
+
<li>Grid computing is being talked about but has not become a successful idea</li>
|
497
|
+
<li>Start with the things that matter to you, is there a need, is there a market?</li>
|
498
|
+
</ul>
|
499
|
+
<p>Worked with Flickr, delious, odea, etc.<br />
|
500
|
+
Flickr</p>
|
501
|
+
<ul>
|
502
|
+
<li>Started as an online game site for girls in canada</li>
|
503
|
+
<li>Chat interface in flash and threw in the photo thing</li>
|
504
|
+
<li>People love the photo and hate the chat</li>
|
505
|
+
<li>Started out having nothing to do with photos</li>
|
506
|
+
<li>1 year working on the game, and in 3 months made the chat room which was launched O’Reilly Etech, 2 months later they had another product: photo sharing</li>
|
507
|
+
<li>Kept doing things to see what people like</li>
|
508
|
+
<li>Plan wasn’t to defeat Ofoto</li>
|
509
|
+
<li>Could have chosen to be acquired or VC, sold to Google which was a “Good idea”</li>
|
510
|
+
</ul>
|
511
|
+
<p>Bloglines</p>
|
512
|
+
<ul>
|
513
|
+
<li>Mark Fletcher started it, having sold egroups to yahoo for millions to fund this</li>
|
514
|
+
<li>Wrote some code to manage his own <span class="caps">RSS</span> feeds</li>
|
515
|
+
<li>Sharing with friends</li>
|
516
|
+
<li>Sharing with wider groups</li>
|
517
|
+
</ul>
|
518
|
+
<p>37signals</p>
|
519
|
+
<ul>
|
520
|
+
<li>Consulting and web site design</li>
|
521
|
+
<li>Let’s build a tool to communicate with clients better: Enter Basecamp</li>
|
522
|
+
</ul>
|
523
|
+
<p>Odeo and Delicious</p>
|
524
|
+
<ul>
|
525
|
+
<li>what’s the business? I don’t know, but I think it might be big</li>
|
526
|
+
<li>anything you can come up with can be a feature of yahoo’s site</li>
|
527
|
+
<li>what went wrong with Delicious is they took money: when you take VC the company sets a very high bar</li>
|
528
|
+
<li>when no plan of money coming in and a high acquisition price due to taking VC, this is a bad idea</li>
|
529
|
+
</ul>
|
530
|
+
<p>Provisional Patent ~ $900</p>
|
531
|
+
<h2>the format</h2>
|
532
|
+
<ul>
|
533
|
+
<li>project in your current company</li>
|
534
|
+
<li>sideline, nighttime</li>
|
535
|
+
<li>patents</li>
|
536
|
+
<li>see what happens</li>
|
537
|
+
<li>small/bootstrapped startup company</li>
|
538
|
+
<li>funded startup</li>
|
539
|
+
</ul>
|
540
|
+
<h2>the “business” view</h2>
|
541
|
+
<h2>market research</h2>
|
542
|
+
<ul>
|
543
|
+
<li>How to validate an idea, how to come up with information about it</li>
|
544
|
+
</ul>
|
545
|
+
<h2>taking the plunge</h2>
|
546
|
+
<ul>
|
547
|
+
<li>decision to start a company</li>
|
548
|
+
</ul>
|
549
|
+
<h2>team</h2>
|
550
|
+
<ul>
|
551
|
+
<li>often get wrong</li>
|
552
|
+
</ul>
|
553
|
+
<h2>fundraising</h2>
|
554
|
+
<ul>
|
555
|
+
<li>VC process</li>
|
556
|
+
<li>You become a salesperson to sell your company’s stock</li>
|
557
|
+
<li>VC’s do not start new companies</li>
|
558
|
+
<li>Customers, a customer, consulting, angel investors, bank loans, government grants, yourself</li>
|
559
|
+
<li>Flickr got a government grant</li>
|
560
|
+
<li>Focus on the business first, not the funding</li>
|
561
|
+
<li>Get good press</li>
|
562
|
+
<li>build the product, get users, make money, don’t spend it, get to break-even: then and only then do you think about growth plan/vc</li>
|
563
|
+
<li>What does VC get you? money, for a while. credibility (maybe). guidance and review. some introductions. advocates for the company.</li>
|
564
|
+
<li>You are no longer the boss.</li>
|
565
|
+
<li><span class="caps">TRICK</span>: the best way to get vc is not to need it</li>
|
566
|
+
<li>vc-backed competitors (sometimes) need big partners</li>
|
567
|
+
<li>no means maybe, yes means maybe</li>
|
568
|
+
<li>term sheet is a page or two about investing. 3/5 term sheets ended up in a no. After a long while of improvements they turned around and said yes.</li>
|
569
|
+
<li>keep at it, can take 8+ rejections to get a yes</li>
|
570
|
+
<li>5 yes’es from VC but didn’t get anything but lunch</li>
|
571
|
+
<li>If there are a group of people that offer VC, close as fast as you can as long as you like the people. Close, close, close. Don’t wait for the perfect one.</li>
|
572
|
+
<li>Go with someone who is honest but might scare you rather than someone who is always saying great things and will probably fire you when they own the company</li>
|
573
|
+
<li>!!! Funding is more than a full time job</li>
|
574
|
+
<li>Bad idea to do marketing, bizdev, sales yourself</li>
|
575
|
+
<li>10 ftf = 1 term sheeet</li>
|
576
|
+
<li>3 term sheets = 1 financing</li>
|
577
|
+
<li>from pitch to term sheet: 2 months (may be 10 or more meetings)</li>
|
578
|
+
<li>from term sheet to money: 1 month</li>
|
579
|
+
<li>total time to get money: 4-12 months</li>
|
580
|
+
<li>vc is a business, too</li>
|
581
|
+
<li>Tim Oren’s blog is good: “No Exit: When VC isn’t right” </li>
|
582
|
+
<li>funders != founder && investors != inventors</li>
|
583
|
+
<li>august and december – Many of the investors are on vacation and nothing gets done</li>
|
584
|
+
<li>June is a good time for investments, September/October is a great time to get meetings</li>
|
585
|
+
<li>ppt: 10-15 slides</li>
|
586
|
+
<li>executive summary, 2-3 pages</li>
|
587
|
+
<li>an intro to a vc</li>
|
588
|
+
</ul>
|
589
|
+
<h2>the first release</h2>
|
590
|
+
<ul>
|
591
|
+
<li>build the simplest thing that could possibly work</li>
|
592
|
+
</ul>
|
593
|
+
<h2>“marketing”</h2>
|
594
|
+
<ul>
|
595
|
+
<li>the geek view: “google doesn’t buy ads, so can I, the product is so great that marketing isn’t needed” </li>
|
596
|
+
<li>the “product marketing handbook for software”</li>
|
597
|
+
</ul>
|
598
|
+
<h2>success or failure</h2>
|
599
|
+
<ul>
|
600
|
+
<li>(acquisition and <span class="caps">IPO </span>|| sustainable business)</li>
|
601
|
+
<li>failing at a startup is extremely hard: laying people off, financial peril, home stress, loss of investor’s money</li>
|
602
|
+
</ul>
|
603
|
+
<h2>a case study: GripeJuice</h2>
|
604
|
+
<ul>
|
605
|
+
<li>create a collective bargaining site for consumers hit with bad customer service</li>
|
606
|
+
<li>a way to keep track of complaints and share experiences</li>
|
607
|
+
<li>very high manual effort for consumer</li>
|
608
|
+
<li>frustration and willingness to pay are disjointed (on the 8th call)</li>
|
609
|
+
<li>tested price point very low</li>
|
610
|
+
<li>probably doesn’t solve the problem for people</li>
|
611
|
+
<li>“all the biggest complainers will be your biggest customers” so you have to deal with the big complainers</li>
|
612
|
+
<li>pursuing it as a free site to attract attention to a company he wants to persue</li>
|
613
|
+
</ul>
|
614
|
+
<h2>learning more</h2>
|
615
|
+
<ul>
|
616
|
+
<li>on pitches: Brad Feld: The torturous world of PowerPoint: http://feld.com/blog/</li>
|
617
|
+
<li>VentureBlog: Presenting Your Company – http://www.ventureblog.com/</li>
|
618
|
+
<li>Joel on Software – http://joelonsoftware.com/</li>
|
619
|
+
<li>Eric Sink: the Business of Software – http://software.ericsink.com/bos/Business_of_Software.html</li>
|
620
|
+
<li>Book: What the Numbers Say</li>
|
621
|
+
<li>Book: Art of the Start – http://garage.com/</li>
|
622
|
+
</ul>
|
623
|
+
|
624
|
+
<p><map name="google_ad_map_5740EPipvYfjFzcmyiYa3R3sHj4_"><area shape="rect" href="http://imageads.googleadservices.com/pagead/imgclick/5740EPipvYfjFzcmyiYa3R3sHj4_?pos=0" coords="1,2,367,28"/><area shape="rect" href="http://services.google.com/feedback/abg" coords="384,10,453,23"/></map><img usemap="#google_ad_map_5740EPipvYfjFzcmyiYa3R3sHj4_" border="0" src="http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&client=ca-pub-8531813895929183&channel=2762548411&output=png&cuid=5740EPipvYfjFzcmyiYa3R3sHj4_&url=http%3A%2F%2Ftech.rufy.com%2Fentry%2F77"/></p>]]></content:encoded>
|
625
|
+
<wfw:commentRSS>http://tech.rufy.com/entry/77/feed/</wfw:commentRSS>
|
626
|
+
<feedburner:origLink>http://tech.rufy.com/entry/77</feedburner:origLink>
|
627
|
+
</item>
|
628
|
+
<item>
|
629
|
+
<title>Does Ruby on Rails scale? A clear and definitive answer</title>
|
630
|
+
<link>http://feeds.feedburner.com/rufytech?m=62</link>
|
631
|
+
<comments>http://tech.rufy.com/entry/76#comments</comments>
|
632
|
+
<pubDate>Thu, 28 Jul 2005 23:25:36 +0000</pubDate>
|
633
|
+
<dc:creator>Lucas Carlson</dc:creator>
|
634
|
+
<category>Programming</category>
|
635
|
+
<category>Ruby</category>
|
636
|
+
<guid isPermaLink="false">http://tech.rufy.com/entry/76</guid>
|
637
|
+
<description><![CDATA[The last post on this page ends with "I'll just have to do the damn tests myself". What tests? I never knew there was a set of tests that could be done against any framework or programming language to definitively say it "scales". If I am wrong, please correct me.
|
638
|
+
|
639
|
+
I don't think anyone would argue [...]]]></description>
|
640
|
+
<content:encoded><![CDATA[<p>The last post on <a href="http://discuss.joelonsoftware.com/default.asp?joel.3.159134">this page</a> ends with “I’ll just have to do the damn tests myself”. What tests? I never knew there was a set of tests that could be done against any framework or programming language to definitively say it “scales”. If I am wrong, please correct me.</p>
|
641
|
+
<p>I don’t think anyone would argue that the following languages couldn’t be used to scale a website since they have all been used in commercial web applications: C, C++, Java, PHP, Perl, Python, Lisp. If all of those languages have been used to build “scalable” websites, then why would anyone think that Ruby couldn’t scale? What would have to be so fundamentally wrong with Ruby that make people so hesitant? Is it because it is interpreted? So are PHP, Perl, and Python. Is it because there are no extremely high traffic sites built with Ruby to date? It was just the other day that no extremely high traffic sites were built in PHP or Python either.</p>
|
642
|
+
<p>No, <i>scalability is not about the language</i>. To ask if a programming language can scale or not is equivalent to asking if a certain written language can be used to write an epic novel. Very very few mature modern languages can’t scale for web sites (I concede that BASIC might be one of them). Similar discussion has <a href="http://www.loudthinking.com/arc/000485.html">happened here</a>.</p>
|
643
|
+
<p>Scalability (with regard to web sites) is a set of design patterns and practices, a set of ideas used to implement robustness which include: statelessness, share-nothingness, and horizontal distribution. If you want to know whether a given website will scale to millions of users, check to see if it uses these foundations. Almost all the giant websites these days use these them: Google, Amazon, Ebay, Livejournal etc.</p>
|
644
|
+
<p>Given this information, one might restate the vague and senseless question of “Does Ruby on Rails scale?” into more tangible questions:</p>
|
645
|
+
<ul>
|
646
|
+
<li>Is Rails stateless?</li>
|
647
|
+
<li>Does Rails share nothing?</li>
|
648
|
+
<li>Does Rails scale horizontally?</li>
|
649
|
+
<li>etc.</li>
|
650
|
+
</ul>
|
651
|
+
<p>As soon as you ask this more refined subset of questions however, you quickly realize that you’ve been heading down the wrong path by asking if a web framework “scales”. These questions simply don’t have one clear answer. <i>Is Rails stateless?</i> You can make a Rails app statefull or stateless. <i>Does Rails scale horizontally?</i> You can make it scale horizontally if you know what you are doing.</p>
|
652
|
+
<p>Realizing that the question was phrased incorrectly, let’s attempt it once again:</p>
|
653
|
+
<ul>
|
654
|
+
<li>Does Rails prevent statelessness?</li>
|
655
|
+
<li>Does Rails prevent sharing nothing?</li>
|
656
|
+
<li>Does Rails prevent scaling horizontally?</li>
|
657
|
+
<li>etc.</li>
|
658
|
+
</ul>
|
659
|
+
<p>The answer to all of these is a resounding no. Abstracting out the root of these questions, we finally arrive at a single question with a single answer:</p>
|
660
|
+
<p><strong>Question: Does anything in Rails prevent you from implementing the design patterns used to scale websites for many users?</strong><strong>Answer: No.</strong></p>
|
661
|
+
<p>This is exactly what David Hansson means by saying <a href="http://www.loudthinking.com/arc/000479.html">it’s boring to scale with Ruby on Rails</a>. This is also why I can’t imagine a test you can do against a framework to see if it can scale. You can’t do any test that looks for a positive outcome because the scalability of a website is highly dependent on how the site was implemented. You can however look for any roadblocks to the common design patterns, and approached this way you can even ask people familiar with the framework your questions and get back reasonable answers.
|
662
|
+
</p>
|
663
|
+
|
664
|
+
<p><map name="google_ad_map_Vq.QktKEYCGpb6iP.ZpM512K2sE_"><area shape="rect" href="http://imageads.googleadservices.com/pagead/imgclick/Vq.QktKEYCGpb6iP.ZpM512K2sE_?pos=0" coords="1,2,367,28"/><area shape="rect" href="http://services.google.com/feedback/abg" coords="384,10,453,23"/></map><img usemap="#google_ad_map_Vq.QktKEYCGpb6iP.ZpM512K2sE_" border="0" src="http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&client=ca-pub-8531813895929183&channel=2762548411&output=png&cuid=Vq.QktKEYCGpb6iP.ZpM512K2sE_&url=http%3A%2F%2Ftech.rufy.com%2Fentry%2F76"/></p>]]></content:encoded>
|
665
|
+
<wfw:commentRSS>http://tech.rufy.com/entry/76/feed/</wfw:commentRSS>
|
666
|
+
<feedburner:origLink>http://tech.rufy.com/entry/76</feedburner:origLink>
|
667
|
+
</item>
|
668
|
+
<item>
|
669
|
+
<title>Executing interactive system commands in Ruby</title>
|
670
|
+
<link>http://feeds.feedburner.com/rufytech?m=61</link>
|
671
|
+
<comments>http://tech.rufy.com/entry/75#comments</comments>
|
672
|
+
<pubDate>Sun, 24 Jul 2005 01:26:29 +0000</pubDate>
|
673
|
+
<dc:creator>Lucas Carlson</dc:creator>
|
674
|
+
<category>Programming</category>
|
675
|
+
<category>Ruby</category>
|
676
|
+
<guid isPermaLink="false">http://tech.rufy.com/entry/75</guid>
|
677
|
+
<description><![CDATA[Following a Ruby Talk thread about how to interactively run shell commands, I think I've finally got it. Let's say you want to run a command, answer the first question it gives you, and get the output.
|
678
|
+
|
679
|
+
|
680
|
+
def run(command, answer='')
|
681
|
+
IO.popen('-', 'r+') do |io|
|
682
|
+
if io.nil?
|
683
|
+
Process.setsid
|
684
|
+
exec command
|
685
|
+
else
|
686
|
+
io.puts answer
|
687
|
+
return io.readlines
|
688
|
+
end
|
689
|
+
end
|
690
|
+
end
|
691
|
+
|
692
|
+
|
693
|
+
Hope this helps anybody looking for the answer. An example [...]]]></description>
|
694
|
+
<content:encoded><![CDATA[<p>Following a <a href="http://www.ruby-talk.org/cgi-bin/scat.rb/ruby/ruby-talk/64127">Ruby Talk thread</a> about how to interactively run shell commands, I think I’ve finally got it. Let’s say you want to run a command, answer the first question it gives you, and get the output.</p>
|
695
|
+
<p><code>
|
696
|
+
<pre>
|
697
|
+
def run(command, answer='')
|
698
|
+
IO.popen('-', 'r+') do |io|
|
699
|
+
if io.nil?
|
700
|
+
Process.setsid
|
701
|
+
exec command
|
702
|
+
else
|
703
|
+
io.puts answer
|
704
|
+
return io.readlines
|
705
|
+
end
|
706
|
+
end
|
707
|
+
end
|
708
|
+
</pre>
|
709
|
+
</code></p>
|
710
|
+
<p>Hope this helps anybody looking for the answer. An example of how to use this code:</p>
|
711
|
+
<p><code>
|
712
|
+
<pre>run('sudo whoami', user_password) # returns 'root'</pre>
|
713
|
+
</code>
|
714
|
+
</p>
|
715
|
+
|
716
|
+
<p><map name="google_ad_map_ZG0mRqFW.wmHUwexoDgjtHr.cHI_"><area shape="rect" href="http://imageads.googleadservices.com/pagead/imgclick/ZG0mRqFW.wmHUwexoDgjtHr.cHI_?pos=0" coords="1,2,367,28"/><area shape="rect" href="http://services.google.com/feedback/abg" coords="384,10,453,23"/></map><img usemap="#google_ad_map_ZG0mRqFW.wmHUwexoDgjtHr.cHI_" border="0" src="http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&client=ca-pub-8531813895929183&channel=2762548411&output=png&cuid=ZG0mRqFW.wmHUwexoDgjtHr.cHI_&url=http%3A%2F%2Ftech.rufy.com%2Fentry%2F75"/></p>]]></content:encoded>
|
717
|
+
<wfw:commentRSS>http://tech.rufy.com/entry/75/feed/</wfw:commentRSS>
|
718
|
+
<feedburner:origLink>http://tech.rufy.com/entry/75</feedburner:origLink>
|
719
|
+
</item>
|
720
|
+
<item>
|
721
|
+
<title>Lisp on Rails</title>
|
722
|
+
<link>http://feeds.feedburner.com/rufytech?m=60</link>
|
723
|
+
<comments>http://tech.rufy.com/entry/74#comments</comments>
|
724
|
+
<pubDate>Tue, 19 Jul 2005 12:32:21 +0000</pubDate>
|
725
|
+
<dc:creator>Lucas Carlson</dc:creator>
|
726
|
+
<category>Programming</category>
|
727
|
+
<guid isPermaLink="false">http://tech.rufy.com/entry/74</guid>
|
728
|
+
<description><![CDATA[I know there is is some toying around with Lisp on Rails like stuff (lisp-on-lines), but that is a little too Lispy for me just yet. Rather, what do you think of this? Worth exploring more? Should I light up the midnight flame to get a proof-of-concept version on Lisp on Rails working (/me *drools* [...]]]></description>
|
729
|
+
<content:encoded><![CDATA[<p>I know there is is some toying around with Lisp on Rails like stuff (<a href="http://paste.lisp.org/display/8912">lisp-on-lines</a>), but that is a little too Lispy for me just yet. Rather, what do you think of this? Worth exploring more? Should I light up the midnight flame to get a proof-of-concept version on Lisp on Rails working (/me *drools* at the thought of machine code with the flexibility of Ruby).</p>
|
730
|
+
<p>Some ideas that would be great include adding continuations and being able to have a self-containted file (as in the example that follows) for those times when you really only want a couple controllers and a couple actions.</p>
|
731
|
+
<p><code>
|
732
|
+
<pre>
|
733
|
+
(load 'lisp-on-rails')
|
734
|
+
|
735
|
+
(model Person
|
736
|
+
(has-many :employees)
|
737
|
+
(belongs-to :company)
|
738
|
+
)
|
739
|
+
|
740
|
+
(model Teenager (Person)
|
741
|
+
(has-many :skateboards)
|
742
|
+
)
|
743
|
+
|
744
|
+
(controller people
|
745
|
+
(scaffold :people)
|
746
|
+
)
|
747
|
+
|
748
|
+
(controller foo
|
749
|
+
(action bar
|
750
|
+
(set 'person (Person find :first by :id (params :id)))
|
751
|
+
|
752
|
+
(redirect-to :action you :id (person :name))
|
753
|
+
)
|
754
|
+
|
755
|
+
(action you
|
756
|
+
(render :text (params :id))
|
757
|
+
)
|
758
|
+
|
759
|
+
(continuation registration
|
760
|
+
(set 'person (Person new
|
761
|
+
:name (get :name)
|
762
|
+
:email (get :email))
|
763
|
+
)
|
764
|
+
(redirect-to :action bar :id (person :id))
|
765
|
+
)
|
766
|
+
)
|
767
|
+
|
768
|
+
(start-server)
|
769
|
+
</pre>
|
770
|
+
</code>
|
771
|
+
</p>
|
772
|
+
|
773
|
+
<p><map name="google_ad_map_edkIGtXYgjEEhHpaDVbHEQQiu9k_"><area shape="rect" href="http://imageads.googleadservices.com/pagead/imgclick/edkIGtXYgjEEhHpaDVbHEQQiu9k_?pos=0" coords="1,2,367,28"/><area shape="rect" href="http://services.google.com/feedback/abg" coords="384,10,453,23"/></map><img usemap="#google_ad_map_edkIGtXYgjEEhHpaDVbHEQQiu9k_" border="0" src="http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&client=ca-pub-8531813895929183&channel=2762548411&output=png&cuid=edkIGtXYgjEEhHpaDVbHEQQiu9k_&url=http%3A%2F%2Ftech.rufy.com%2Fentry%2F74"/></p>]]></content:encoded>
|
774
|
+
<wfw:commentRSS>http://tech.rufy.com/entry/74/feed/</wfw:commentRSS>
|
775
|
+
<feedburner:origLink>http://tech.rufy.com/entry/74</feedburner:origLink>
|
776
|
+
</item>
|
777
|
+
<item>
|
778
|
+
<title>A wish: Abolition of passing data with flags and symbol-like options when calling Unix programs</title>
|
779
|
+
<link>http://feeds.feedburner.com/rufytech?m=59</link>
|
780
|
+
<comments>http://tech.rufy.com/entry/73#comments</comments>
|
781
|
+
<pubDate>Tue, 19 Jul 2005 00:16:03 +0000</pubDate>
|
782
|
+
<dc:creator>Lucas Carlson</dc:creator>
|
783
|
+
<category>General</category>
|
784
|
+
<guid isPermaLink="false">http://tech.rufy.com/entry/73</guid>
|
785
|
+
<description><![CDATA[I wish I could call every program on the command line like this:
|
786
|
+
|
787
|
+
mysql -v :user foo :password bar :host rufy.com :port 3306
|
788
|
+
|
789
|
+
For me, this is much easier to type than what I would currently need to do:
|
790
|
+
|
791
|
+
mysql -v --user foo --password bar --host rufy.com --port 3306
|
792
|
+
|
793
|
+
The difference between -- and : is huge for me [...]]]></description>
|
794
|
+
<content:encoded><![CDATA[<p>I wish I could call every program on the command line like this:</p>
|
795
|
+
<pre>mysql -v :user foo :password bar :host rufy.com :port 3306</pre>
|
796
|
+
<p>For me, this is much easier to type than what I would currently need to do:</p>
|
797
|
+
<pre>mysql -v --user foo --password bar --host rufy.com --port 3306</pre>
|
798
|
+
<p>The difference between — and : is huge for me for two reasons:</p>
|
799
|
+
<ol>
|
800
|
+
<li>One character is much easier to type than two characters which makes a big difference given the number of times I run commands on the command line</li>
|
801
|
+
<li>Colons are much more accessible in my usual range of typing than two dashes</li>
|
802
|
+
</ol>
|
803
|
+
<p>Plus, if everyone used colons like this it would be a lot easier to explain symbols in Ruby and Lisp to the uninitiated.</p>
|
804
|
+
<p>I hate it that -pPassword specifies the password and -P 3306 specifies the port. I hate that -h specifies the host and –help calls help. I like flags without data (ps -aux for example). Flags with data are inconsistent, cumbersome and a steep learning curve for Unix beginners. I think they should be abolished. If flags with data were abolished, there would be no reason for -h to return anything but help, since if it wanted data you would use :h.</p>
|
805
|
+
<p>Along with smart auto-completion that getopt_long() currently provides, you could do this:</p>
|
806
|
+
<pre>mysql -v :u foo :pa bar :h rufy.com :po 3306</pre>
|
807
|
+
<p>Which is a couple characters longer, yet light-years easier to explain and remember than the way you have to do it now:</p>
|
808
|
+
<pre>mysql -v -u foo -pbar -h rufy.com -P 3306</pre>
|
809
|
+
<p>Anyone know how I can alias a colon to work along side the double-dash in getopt_long()?
|
810
|
+
</p>
|
811
|
+
|
812
|
+
<p><map name="google_ad_map_yYGQe48WBMTnJpP7WEECe6fRYDM_"><area shape="rect" href="http://imageads.googleadservices.com/pagead/imgclick/yYGQe48WBMTnJpP7WEECe6fRYDM_?pos=0" coords="1,2,367,28"/><area shape="rect" href="http://services.google.com/feedback/abg" coords="384,10,453,23"/></map><img usemap="#google_ad_map_yYGQe48WBMTnJpP7WEECe6fRYDM_" border="0" src="http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&client=ca-pub-8531813895929183&channel=2762548411&output=png&cuid=yYGQe48WBMTnJpP7WEECe6fRYDM_&url=http%3A%2F%2Ftech.rufy.com%2Fentry%2F73"/></p>]]></content:encoded>
|
813
|
+
<wfw:commentRSS>http://tech.rufy.com/entry/73/feed/</wfw:commentRSS>
|
814
|
+
<feedburner:origLink>http://tech.rufy.com/entry/73</feedburner:origLink>
|
815
|
+
</item>
|
816
|
+
</channel>
|
817
|
+
</rss>
|
818
|
+
|