Sun 25 May, 2008

- 说明
- 插件class_inputs的作用在于增加标记input的属性class,以便更好地显示页面。这里介绍这个插件的目的是让大家把它作为学习Rails插件的实例。
- 安装方法
ruby script/plugin install http://svn.jcoglan.com/classyinputs/trunk/classy_inputs
add to del.icio.us. look up in del.icio.us.
add to furl
add to del.icio.us. look up in del.icio.us.
add to furl
“ A design problem is not an optimization problem. ”
Christopher Alexander
add to del.icio.us. look up in del.icio.us.
add to furl
add to del.icio.us. look up in del.icio.us.
add to furlSat 24 May, 2008

add to del.icio.us. look up in del.icio.us.
add to furl
- 说明
- 这个视频网站是圣迭戈Ruby社区创建的。尽管视频的发表间隔不定,但是其内容还是值得一看。在视频学习教程中,能够看到和发现一些文章中不可能学习到的知识和技巧。
add to del.icio.us. look up in del.icio.us.
add to furl
add to del.icio.us. look up in del.icio.us.
add to furl
“ No matter how correct a mathematical theorem may appear to be, one ought never to be satisfied that there was not something imperfect about it until it also gives the impression of being beautiful. ”
George Boole
add to del.icio.us. look up in del.icio.us.
add to furl
Tip Orwell’s Rules for Writers (paraphrased)
1. If it’s possible to cut out a word, cut it out.
2. Never use a long word where a short will do.
3. Never use a passive when you can use an active.
4. Avoid foreign and technical words.
5. Never use a metaphor you’ve seen in print.
6. Break these rules to avoid something outlandish.
add to del.icio.us. look up in del.icio.us.
add to furl
- 说明
- 网站Open Source Rails收集了一些重要的基于Rails框架开发的开源应用软件。
add to del.icio.us. look up in del.icio.us.
add to furlFri 23 May, 2008

add to del.icio.us. look up in del.icio.us.
add to furl
The topic for the next Refactor Phoenix meeting, Wednesday May 28 is git.
Git is a distributed version control system (DVCS) with increasing popularity.
Along with Mercurial, Darcs, and Bazaar, DVCS’s are increasingly winning the hearts and minds of hackers everywhere. Austin Godber of JumpBox will give a presentation on the basics of git installation, local repository setup and basic usage. You’ll also learn how to publicly share, read only, a repo over HTTP to offer public, read-only access.
David and I will relate our experience with gitorious.org and its use for managing open-source projects.
Some worthwhile places to start learning about git and distributed version control systems:
- Distributed Version Control Systems: A Not-So-Quick Guide Through
- Intro to Distributed Version Control
- Git
- Mercurial
- Bazaar
- Darcs
Refactor Phoenix meets on the 4th Wednesday of each month, at Boulders on Broadway in Tempe. See the Web site for more details.
add to del.icio.us. look up in del.icio.us.
add to furl
add to del.icio.us. look up in del.icio.us.
add to furlThu 22 May, 2008

Numeric#percent
class Percentage attr_reader :amount def initialize(amount) @amount = amount end def of(number) number * (amount / 100.0) end end class Numeric def percent Percentage.new(self) end end 25.percent.of 16 # => 4.0 18.percent.of 321 # => 57.78
add to del.icio.us. look up in del.icio.us.
add to furl
“ It’s the defeat of death. ”
Marvin Minsky on the goal of AI
add to del.icio.us. look up in del.icio.us.
add to furl
Drop your productivity as fast as the tetrominoes fall!
If you think Tetris is a simple game, let me refer you to TetrisConcept, a wiki which aims “to compile every Tetris detail known to mankind.” Due to tricks like t-spins and other tactical rotations, the game becomes rather delicate.
Reading Tetris the Grand Master: A gameplay essay is a good way to learn about this.
Heboris Unofficial expansion is the best and most flexible version of Tetris I ever saw. It supports nine different rotation systems and a magnitude of different modes (especially really fast ones), while almost everything can be configured.
It was a bit tricky to get running on OS X, so here are the instructions:
Acquire hebo0019.zip. This version works fine on Windows.
Acquire the OS X binary.
From MacPorts, install libsdl-framework, libsdl_mixer-framework, and libsdl_image-framework.
Copy Heboris.app from the latter .zip into the former’s exe/ directory.
Edit heboris.ini and change it to “english = 1;” to replace most of the japanese.
Run Heboris.app and enjoy! By default, the cursor keys move and Z/Y, X, C are the action buttons (No idea where Hold is, rebind it to V maybe).
If you want to play against CPU, you need to define key bindings, enable the CPU for the second player in the Option menu and then configure the second player using his keys—the CPU will just play for it.
NP: Liars—Plaster Casts of Everything
add to del.icio.us. look up in del.icio.us.
add to furl
I just released PersistJS, a client-side JavaScript persistent storage library. Features include:
- Small (9.3k minified, 3k gzipped)
- Standalone: Does not need any additional browser plugins or JavaScript libraries to work on the vast majority of current browsers.
- Consistent: Provides a consistent, opaque API, regardless of the browser.
- Extensible: Custom backends can be added easily.
- Backwards Compatible: Can fall back to flash or cookies if no client-side storage solution for the given browser is available.
- Forwards Compatible: Supports the upcoming versions of Internet Explorer, Firefox, and Safari (Opera too, if you have Flash).
- Unobtrusive: Capability testing rather than browser detection, so newer standards-compliant browsers will automatically be supported.
If you already know why this is awesome, then you can skip straight to the download. If you're scratching your head, then read on...
Why This is Awesome
Why use PersistJS? What's the problem with using cookies directly or simply requiring Flash?
Currently the only reliable cross-platform and cross-browser mechanism for storing data on the client side are cookies. Unfortunately, using cookies to store persistent data has several problems:
- Size: Cookies are limited to about 4 kilobytes in size.
- Bandwidth: Cookies are sent along with every HTTP transaction.
- Complexity: Cookies are difficult to manipulate correctly.
Modern web browsers have addressed these issues by adding non-Cookie mechanisms for saving client-side persistent data. Each of these solutions are simpler to use than cookies, can store far more data, and are not transmitted along with HTTP requests. Unfortunately, each browser has addressed the problem in a different and incompatible way. There are currently 4 different client side persistent data solutions:
- globalStorage: Firefox 2.0+, Internet Explorer 8
- localStorage: development WebKit
- openDatabase: Safari 3.1+
- userdata behavior: Internet Explorer 5.5+
Some developers have attempted to address the client side storage issue with the following browser plugins:
- Adobe Flash
- Google Gears
The problem with relying on plugins, of course, is that users without the plugin installed miss out on the feature in question, and your application is dependent on software from a particular vendor. Google Gears, for example, is not widely deployed. Flash is, but it has problems of its own:
- Many users block Flash or require a click in order to enable flash content; this makes Flash unsuitable as a transparent, client-side data store.
- Flash is notoriously unreliable on newer 64-bit machines.
- Some businesses block Flash content as a security measure.
Anyway, if we include Gears and Flash, that means there are no less than 6 incompatible solutions for storing client-side persistent data.
The most notable attempt at addressing this problem is probably Dojo Storage. Unfortunately, Dojo Storage does not support Internet Explorer without Flash, and it does not support Safari or other WebKit-based browsers at all (at least, not without Flash). Also, Dojo Storage is not standalone; it requires a several other Dojo components in order to operate.
PersistJS addresses all of the issues above. It currently supports persistent client-side storage through the following backends:
- flash: Flash 8 persistent storage.
- gears: Google Gears-based persistent storage.
- localstorage: HTML5 draft storage.
- whatwg_db: HTML5 draft database storage.
- globalstorage: HTML5 draft storage (old spec).
- ie: Internet Explorer userdata behaviors.
- cookie: Cookie-based persistent storage.
Each backend exploses the exact same interface, which means you don't have to know or care which backend is being used.
Examples
Here are some simple examples of PersistJS in use:
// create a new client-side persistent data store
var store = new Persist.Store('My Data Store');
// pretend data
var data = "pretend this is really long data that won't fit in a cookie";
// save data in store
store.set('saved_data', data);
That's all there is to creating a persistent store and adding some data to it. Fetching data back from the store uses a callback function (to support asyncronous backends), but it's still pretty simple to use:
// get data back from store, and prompt user with it
store.get('saved_data', function(ok, val) {
if (ok)
alert('saved data = ' + val);
});
Removing data is pretty easy too:
// remove data from store
store.remove('saved_data');
Although it isn't necessary, you can also get some information about the
detected backend using the Persist.type and Persist.size attributes:
// build alert message
var info = [
'Backend: ',
Persist.type || 'none',
', ',
'Approximate Size Limit: ',
(Persist.size < 0) ? 'unknown' : Persist.size
].join('');
// prompt user with information
alert(info);
Finally, if you don't want a particular backend used under any
circumstances, you can disable it using the Persist.remove() function:
// never use cookies for persistent storage
Persist.remove('cookie');
Download
This is the initial release, so there are bound to be some bugs. PersistJS has been tested with FireFox 2.0, FireFox 3.0rc1, IE7, and Safari 3.1. The Gears and Flash backends work where Gears and Flash 8 are supported.
The most notable omission here is IE6; it should work, but I don't have IE6 handy at the moment (MultipleIEs is temporarily busted).
Commenting is still busted around here, so any comments should sent via email or posted on the Reddit thread.
add to del.icio.us. look up in del.icio.us.
add to furl
add to del.icio.us. look up in del.icio.us.
add to furl
- 说明:
- 电子工业出版社已经发布了《JRuby语言实战技术》样章,该样章已经在Google cnRails论坛上(需要注册)可以下载了。
add to del.icio.us. look up in del.icio.us.
add to furl
add to del.icio.us. look up in del.icio.us.
add to furl
“ Programs must be written for people to read, and only incidentally for machines to execute. ”
Abelson & Sussman, SICP, preface to the first edition
add to del.icio.us. look up in del.icio.us.
add to furl
Date#at_some_point
class Date def at_some_point (at_midnight..tomorrow.at_midnight).to_a.rand end end Date.today.at_some_point # => Tue May 21 10:23:00 -0500 2008 Date.today.at_some_point # => Tue May 21 02:10:00 -0500 2008 Date.today.at_some_point # => Tue May 21 18:28:00 -0500 2008 Date.today.at_some_point # => Tue May 21 07:25:00 -0500 2008
add to del.icio.us. look up in del.icio.us.
add to furlWed 21 May, 2008

Practical REST on Rails 2 Projects
by Ben Scofield.
Apress, Berkeley 2008.
284 pages.
[Full disclosure: I have received a copy of the book in exchange for this review.]
The book, targeted at intermediate and advanced Rails users, starts with a chapter “Why REST?” that tries to explain how REST helps interconnect applications and reflects the structure of the web. As examples for such connectivity a few mashups are presented. The author states that APIs can make web applications much more useful and interesting, but costly to develop. He contrasts REST with XML-RPC and SOAP. Finally, the basics of REST are outlined: It is a client/server architecture based on stateless requests that describe and transform resource representations. The author argues that REST makes it easier to develop clients and servers and extend these applications in the future, last but not the least because REST is implemented well in Rails 2.
After demonstrating the use of (deprecated) ActiveWebService, the author shows how these ideas are expressed nowadays in Rails 2, outlining the history of simply_restful. He continues by explaining the new styles of URI routing that also dispatch on the HTTP method like map.resources/map.resource/nesting and map.namespace. The author also addresses Rails’ support for multiple output formats and new helpers related to routing. Scaffolding is discussed and will be used in the book. At last, there is a mention of ActiveResource to use RESTful Rails applications together.
The third chapter develops the main application of the book dubbed MovieList. It is used throughout the rest of the book. MovieList, a site that informs about movies and their releases, lets users express their interests and displays when new movies with the same actors are released. The code is not developed test-first, but the downloadable code contains a test suite. Occasionally the code is pretty weird, for example it defines setters that are merely called for their side-effects using #update_attributes. In some places, explicit iteration over ActiveRecords would have been solved better by doing it in the database. Also, the generated HTML is partly unsemantic and hard to scrape (which is not that bad if the data can be reached by the API, you may argue). The author explicitly defines notifications and interests for the movies to belong to the logged-in singleton user (they reside at /user/interests, not /users/:id/interests), supposedly so one cannot see other people’s interests. In later chapters, he decides however to at least revert this for notifications—it would have been better to properly design it in first place, as it actually is a nice feature and more RESTful anyway (can you speak of “current users” in a stateless request, really?) and show how to protect the page for users that don’t want to allow it to be seen. The author mentions at the end of the chapter that a “great deal of planning, testing and other work has gone undescribed”; wouldn’t it have been useful to have these parts in the book as well? The actual architectural concerns of REST applications are not really mentioned in the book.
The next four chapters deal with accessing the MovieList applications from other technology. Chapter 4 uses JavaScript to provide a widget users can embed on their homepage and shows how to do full-fledged access to the application using AJAX after extending it to support JSON. Chapter 5 shows how to access the site using the PHP framework Squidoo. During this, a feature is added to allow users to display the movie releases within a time frame. This is the code used to parse the relative time, and I’m not kidding:
raw_time = params[:time] || '1 month'
time = eval("#{raw_time.sub(/ /, '.')}.from_now")
How this gaping remote code injection hole passed any kind of technical review is a miracle to me. Ironically, the next section is called “Injection Flaws”, and addresses SQL injection and so-called “HTML injection”, which actually is passing anything you want as parameters. The author then decides to “fix” it by checking the time parameter in the PHP script calling the Rails application. Duh.
Chapter 6 builds an client for the iPhone, optimized to its interface constraints: a small screen, popup keyboard and lower bandwidth. It uses the commonly used approach of defining a new Rails format that is triggered by a special subdomain or by user agent sniffing. The chapter shows how to use iUI to make the interface look native, too.
Chapter 7 shows how to embed the application to Facebook either by using iframes or the FBML. I have no idea how the contents of this chapter are related to REST, especially since the FBML approach actually calls everything using POST.
Chapter 8 is called “Dealing with success” and is about making the application faster and more robust. Apart from the classic caching approaches (which work very well in REST due to the idempotency of GET, but see below) and foreshadows of denormalization, it contains a few general hints on Rails and database performance. It also addresses throttling access to the API by using API keys and setting up auditing to monitor the site.
Finally, Chapter 9 tries to place “Rails in the enterprise” and explains the chances, but also the problems of REST and Rails in the enterprise. It contains a small example of how to create a RESTful interface for a SOAP backend.
Conclusion: Generally, I found the book lacking. Instead of shifting focus to the design and architecture of real-world REST applications and showing up the patterns that can be used to help development, the book shows how to combine a simple CRUD application with half a dozen of buzzword loaded Web 2.0 stuff. The semantics of REST are only half-heartedly addressed (a third of page 13 discusses what the HTTP methods mean), the idempotency of GET merely assumed (it’s actually in a parenthesized half-sentence on page 72), and the actual means of applying REST (proper status codes, correct/multiple content types) are not made explicit. Instead of wasting over 15 pages on screenshots unrelated(!) to the application and another 2 pages on showing a WSDL that is very much useless, the reader would have had more benefit from a table of HTTP status codes and content types. Also, writing a REST client in Ruby is not addressed by means other than (the limited, non-general) ActiveResource.
I think this sounded too negative, please bear with me: The book is okay. It’s well written, and if you like a whirlwind tour of Web 2.0 things one can do it’s a good read. It’s just not really about REST, or at least not what I’d expect of a book about REST.Rating: 3.5 of 5 points.
NP: Dandi Wind—Hostages
add to del.icio.us. look up in del.icio.us.
add to furl
add to del.icio.us. look up in del.icio.us.
add to furl
add to del.icio.us. look up in del.icio.us.
add to furl
Enumerable#some
module Enumerable def some map do |element| maybe do element end end.compact end end
add to del.icio.us. look up in del.icio.us.
add to furlTue 20 May, 2008

add to del.icio.us. look up in del.icio.us.
add to furl
add to del.icio.us. look up in del.icio.us.
add to furl
May 31 is Desert Code Camp
It’s held at UAT in Tempe:
University of Advancing Technology
2625 W. Baseline Road
Tempe, Arizona 85283
Well worth checking out, though there seems to be a heavier slant towards Microsoft tech than in than past.
Also, a word on the Ruby presentations: David will not be available that day because of prior commitments; his Ruby talks might be canceled, though Logan will probably be covering at least one of them.
I will likely be attending, but prefer to play spectator this time.
add to del.icio.us. look up in del.icio.us.
add to furlMon 19 May, 2008

关于地震,我一直想写点什么,又不知从何下手,因为我着实不是一个愿意记录悲伤的人。但我还是决定写一些东西,让思绪飘散一下。
这注定不是一个平静的年景:雪灾,火车相撞,地震。国难让中国人空前的团结起来。
对我而言,今天也是姥姥过世三周年的纪念日。我是姥姥一手带大的,对姥姥有着深厚的感情。所以,我深知亲人离开的痛苦。地震让那么多人失去了亲人,对于活着的人,那是一种折磨,无论你怎样的坚强。
和老妈通电话,她对于地震的记忆要比我深刻,因为75年的海城地震和76年的唐山地震,对于家里都是有影响的。因为曾经离地震很近,所以,她更知道今天的地震意味着什么。
地震时,我以为自己眩晕,后来,才意识到不对,但也并没有往心里去,因为念高中时,学校离矿区很近,矿里放炮的时候,就会感到楼在晃。当我得知地震发生在四川,北京可以感到明显的震动,我知道这会是一场灾难。
其实,最近一段时间,我有意无意在回避关于地震的消息,因为我知道,那些消息会让自己心痛。
有人以为,有些公司或个人捐款是在作秀。如果真是这样,我希望这样的秀越多越好,只要是对灾区有益的。
默哀那一刻,站在办公室里,耳边是响亮的喇叭声和警报声,思绪是混乱的。
自然面前,人很渺小。这是我写在自己饭否上的一句话。渺小的一方,价值何在?在抗震救灾的过程中,一个个感人的故事给了我们答案:人性的光辉。
add to del.icio.us. look up in del.icio.us.
add to furlSun 18 May, 2008

add to del.icio.us. look up in del.icio.us.
add to furl



