6561 items (6561 unread) in 32 feeds
Chinese
(5287 unread)
Japanese
(1160 unread)
English
(94 unread)
即可完成將 Rails 原始碼,Gems 原始碼包入到 Rails app folder 裡面,這樣 deploy 超方便呀。
$ rake rails:freeze:edge
$ vi config/environment.rb
$ rake gems:unpack
$ rake gems:build
Rails::Initializer.run do |config|
# Require the latest version of haml
config.gem "haml"
# Require a specific version of chronic
config.gem "chronic", :version => '0.2.3'
# Require a gem from a non-standard repo
config.gem "hpricot", :source => "http://code.whytheluckystiff.net"
# Require a gem that needs to require a file different than the gem's name
# I.e. if you normally load the gem with require 'aws/s3' instead of
# require 'aws-s3' then you would need to specify the :lib option
config.gem "aws-s3", :lib => "aws/s3"
end
NoMethodError (undefined method `file_exists?' for #):
require 'gettext/rails'
module ActionView
class Base
delegate :file_exists?, :to => :finder unless respond_to?(:file_exists?)
end
end
pwd = `pwd`.chop
all_files = `find app -type f -not -regex ".*.svn.*"`
all_files.each do |file|
old_file = pwd+"/"+file.chop
new_file = pwd+"/big5/"+file.chop
`iconv -f utf-8 -t big5 #{old_file} > #{new_file}`
end

LoadModule passenger_module passenger_module的預設目錄
RailsSpawnServer SpawnServer路徑
RailsRuby ruby路徑

<VirtualHost *:80>
ServerName www.yourhost.com
DocumentRoot /rails目錄/public
</VirtualHost>




lambda { |env| [200, {}, 'Hello World!' }
前陣子需要一個 IDE 來教課,需求如下
就選了 Netbeans 6 來試試看,結果發現真的還蠻不錯的,因為都是 Sun 的東西,所以直接跟 jruby 有很好的整合
最重要的是,他可以直接把 Model 對應到 attribute 給取出來

Product Model 裡面有 description,image_url ... title 等 table column ,Netbeans 6 可以直接取出來放到 code hint 裡面去。這樣就省了點找 db column 的時間了。不過這個功能必須使用 migration ,或是將 db schema dump 到 schema.rb 才可以用,也就是說不是 live db connection 去取 schema 啦。
Netbeans 6 最大的缺點就是速度太慢了.......,不過 6.1 Beta 已經改善了不少。大家可以試試看。
不過我的話,還是 vim 無敵呀。Navigation 用 gf 可以直接跳來跳去,Find Usage 可以用 grep -r --color Patern dir 來取代, 取出 db schema 可以直接用 mysql client + explain db schema 來做到。鍵盤還是真正的王道。
def index
end
def send_data
render :juggernaut do |page|
page.insert_html :top, 'chat_data', "
html>這樣聊天室就完成啦,可以試試看玩玩看。
head>
%= javascript_include_tag :defaults, :juggernaut %>
juggernaut %>
head>
body>
%= form_remote_tag( :url => { :action => :send_data }, :complete => "$('chat_input').value = ''" ) %>
%= text_field_tag( 'chat_input', '', { :size => 20, :id => 'chat_input'} ) %>
%= submit_tag "Add" %>
"chat_data" style="list-style:none"> ul>
body>
html>
這年頭發展 Application Server 好像很有搞頭,也或許是 Rails 社群對 Zed Shaw 的高調離去的反撲。總之,2008 年一月出了 Thin,二月出了SwitchPipe和Swiftiply,現在又有一個 Rails App Server Ebb 出了,而且好像真的很有料。

上面這張圖是 ebb 跟 Mongrel ,和 Event-Driven Mongrel,Thin 的負載程度 benckmark。我們可以發現 ebb 跟其他的 Rails App Server 根本就是不同等級的負載程度。他的 Design 架構上面比較像 Event-Driven Mongrel,差別比較大的就是他很多地方用 c 寫成。
安裝方式
gem i ebb
記得先安裝 glib2。
跑的方式
ebb_rails start
很熟悉的指令。
測試一下好了。

Friends for Sale 是一個在 FaceBook 上面排行前十的 Facebook App,最近他公佈他的資料,他是 Ruby on Rails 寫的。他上面有 60萬個會員,一個月 3億個 PV,並且以每個月 300%繼續成長。上個月流量是 3T,不過大部份都是圖片的支出。
架構是標準的 Rails Cluster,Front end 是 Nginx,Application Server 是 Mongrel。
他們學到課程如下
他們使用
使用硬體
從 JavaEye 看到的東西, Adobe CTO Kevin Lynch在 Adobe Engage 上面講說,他們預計將其他 language 帶入 Flash ,使得 Flash 不只是可以用 ActionScript,還可以使用其他的 Language。最後也只是將 Language Compile成 Flash 的 swf Bytecode。
感覺又是一個 VM 的即將誕生。
int main(){
using Rice::Hash;
using Rice::protect;
ruby_init(); // 使用 ruby 前一定要呼叫
// 設定 load path, 否則 load path 會是 []
rb_eval_string("$LOAD_PATH << '/opt/local/lib/ruby/1.8'");
rb_eval_string("$LOAD_PATH << '/opt/local/lib/ruby/1.8/i686-darwin9.1.0'");
// require yaml 進來。當然也可以用上面的方式 require. 不過之所以會這樣寫,
// 是因為我不知道 load path 要怎麼直接從 rb_ function 中設定?
// 否則我是覺得能用 rb_ 去跑盡量用,evil eval 不是叫假的...
rb_require("yaml");
// protect 我猜是把所有的錯誤都轉成 rice 本身的 exception.
// Hash, 則是 ruby 的 hash 在 C++ 裡的 wrapper,
// 所以我是把 YAML 的讀取結果存入這份 C++ Hash 中。
Hash h(protect(rb_eval_string, "YAML.load(File.read('database.yml'))"));
// 這邊,我要做的事只是展現如何使用這份 hash.
Extractor e;
e.extract(h);
std::cout << std::endl;
}#include <ruby.h>
#include <rice/Hash.hpp>
#include <rice/Array.hpp>
#include <iostream>
using Rice::Object;
using Rice::Class;
using Rice::Hash;
using Rice::Array;
using Rice::String;
// 排版算空格用的
std::string spacer(int depth){
std::string result;
for(int i=0; i<depth; ++i)
result += " ";
return result;
}
class Extractor{
public:
// 他 class 判斷法有點麻煩,所以我先把這三個 class instance cache 起來
Extractor(): hash_class_(Hash().class_of()),
array_class_(Array().class_of()),
string_class_(String().class_of())
{}
void extract(Object const& obj, int depth = 0) const{
if(obj.is_instance_of(hash_class_))
extract_hash(obj, depth);
else if(obj.is_instance_of(array_class_))
extract_array(obj, depth);
else if(obj.is_instance_of(string_class_))
std::cout << spacer(depth) << obj << "n";
else // 這表示他是 Fixnum or Float?
std::cout << spacer(depth) << obj << "n";
}
private:
void extract_array(Array const& obj, int depth) const{
for(Array::const_iterator i=obj.begin(), iend=obj.end(); i!=iend; ++i)
extract(*i, depth);
}
void extract_hash(Hash const& obj, int depth) const{
for(Hash::const_iterator i=obj.begin(), iend=obj.end(); i!=iend; ++i){
std::cout << spacer(depth) << i->key << ":";
// i->value 結果會是 ruby 上 C 的 VALUE, 所以要 cast 成 Rice::Object
if(static_cast<Object>(i->value).is_instance_of(hash_class_))
std::cout << "n", extract(i->value, depth+1);
else // 單純的值
std::cout << " ", extract(i->value, 0);
}
}
private:
Class hash_class_, array_class_, string_class_;
};

JavaEye 網友的測試也發現,不論是 Ruby 1.8 ,Ruby 1.9,Thin 的速度也是超越 Mongrel 。Ruby 1.9 裡面 req/s 居然是 4154 : 1313 的可怕差距Mongrel 1000 100 1313.19 0
Thin 1000 100 4154.67 0
要執行 thin ,就是在 Rails 的根目錄下執行gem i thin
可惜沒有 Cluster 版本,不過,對岸網友已經寫了一個應急的 rake file,只可惜沒有指定 Port 的 command,所以我稍微修改一下成為這樣thin start
將這個東西貼在 Rails 根目錄的 Rakefile ,將它貼在最後面,然後執行下面指令啟動namespace :thin do
namespace :cluster do
desc 'Start thin cluster'
task :start => :environment do
`cd #{RAILS_ROOT}`
(ENV['SIZE'] ? ENV['SIZE'].to_i : 4).times do |i|
Thread.new do
port = ENV['PORT'].to_i + 1
str = "thin start -d -p#{port} -Ptmp/pids/thin-#{port}.pid"
str += " -e#{RAILS_ENV}"
puts "Starting server on port #{port}..."
`#{str}`
end
end
end
desc 'Stop thin cluster'
task :stop => :environment do
`cd #{RAILS_ROOT}`
Dir.new("#{RAILS_ROOT}/tmp/pids").each do |file|
Thread.new do
if file.starts_with?("thin-#{port_range}")
str = "thin stop -Ptmp/pids/#{file}"
puts "Stopping server on port #{file[/d+/]}..."
`#{str}`
end
end
end
end
end
end
灰色的代表可以自己填寫的選項,包含 Rails 啟動的 enviroment,執行幾個 thin ,還有從哪個 Port 開始 listen。有用過 mongrel_cluster 應該都很清楚。停止就是rake thin:cluster:start RAILS_ENV=production SIZE=10 PORT=4000
他會砍掉 tmp/pids/thin- 開頭的 pid file。rake thin:cluster:stop
所以他們決定使用更快的 Regular Expression Engine 來徹底解決 JRuby on Rails 的效能問題。他們選中了 Oniguruma 這個 Ruby 的 regular expression Engine,這是 Ruby 1.9 內建的新 Regular Expression Engine。And I found that there was one in particular that had really interesting performance when comparing MRI to JRuby. In fact, it was between 200 and a 1000 times slower. What's worse, the performance wasn't linear.
真的好記很多。Oniguruma 支援多個 charset 的 regular expression,已經是一個成熟的 regular expression engine。所以 JRuby Team 選擇了 Oniguruma 當作新的目標,將他 Porting 成 JRuby 版本,並且將他改名為 Juni。後來發現 Juni 相對於 JRegex ,的確對於 JRuby 帶來了顯著的效能上升。O ni guru ma
哦 , 你 咕噜 吗?
然後他又提到一個很有趣的分類,Ruby 是魔幻語言,Python 是簡約語言。Robbin 老大也出來講了Ruby为什么会受程序员的欢迎?。一整篇看下來,實在是很過癮。有人认为,这下子不得了了,Ruby要称霸动态语言了。你想想,Ruby已经几乎拥有了所有梦幻般的语言特性,神奇的动态能力,强大的支持库,内置的跟Perl可以比肩的正则表达式,Smalltalk级别的纯而又纯的面向对象特征,简洁明快的风格,跨语言整合也非常容易,唯一的缺点就是速度慢。现在连这个缺点都被弥补了,Ruby还能挡得住吗?其他的动态语言都该歇菜了。
看不懂的話,用更白話的方式來解釋,The Zen of Python 裡面有提到Explicit is better than implicit.
也就是,Python 有意的限制語言的表示方式,使得不好的 coding 習慣都不能 Compile 過,有意的強制使用者養成良好的習慣。There should be one-- and preferably only one --obvious way to do it.
魔幻語言的擁護者思考的東西,這位孟岩老大也描寫的很傳神There's More Than One Way To Do It.
但是,請不要輕易的把 Ruby 歸於「華而不實」這一派。Robbin 老大也在這裡講到他们写的代码是一种谜语般的艺术,出谜语和猜谜语的人们都能从中获得巨大的精神满足
Ruby 奇妙的手法,以及 DSL 的技巧,都是為了達到跟 Python 同樣的 Promise Land ,那就是「code 可讀性」。只是兩者作法不同而已。C++的魔幻语法会导致代码的可读性变差,而Ruby的魔幻语法会导致代码的可读性大大提高。
不论是matz本人,还是整个Ruby社区,Rails社区诸多开源项目的作者,抑或整个Ruby和Rails开发者社区,在一个编程哲学问题上是高度统一的,这就是:
强调程序员的快乐编程,追求人性化编程,在代码的可读性上面有偏执的追求,拒绝难以阅读的代码和难用的API。也就是所谓的coding for fun!
高手果然是高手,好露骨的講法。Python 人對於「語言的魔幻面」,或是你要稱為「奇技淫巧」有種本質上的厭惡感,很多 Ruby 人引以為傲的東西,都會被視為「惡魔」。儘管 Python 也可以玩出些好玩的把戲,但是他們的中心思想讓他們「選擇不去作」。回到开头的话题,Ruby是一个典型的魔幻语言,而Python则是简约派的代表。两个语言的支持人群在审美观念和开发风格方面差距非常大。初学Ruby和Python的人,都会感受到一种欣喜和兴奋,但是原因却不太一样。Ruby的学习者会惊喜于很多新的表达方式,比如 :attr_accessor 之类的魔幻特性,而Python学习者则会惊喜于实现具体功能的简洁性。可以说从一开始他们追求的就是不同的东西。随着学习的深入,Python开发者当然也会发现Python中的不少深入的特性,不过却并不倾向于滥用它们。长次以往,Python人群对任何语言的魔幻面都会产生一种厌恶感。我认识的一个Django开发者,就明确表示,就算RoR比Django开发效率高一点,也绝不使用Ruby,因为Ruby这个语言充满了“不必要的小聪明”。
大家想看去看原文吧 :) 。你不用去期待裡面有啥技術,Performance ,語言架構的比較。裡面只罵人跟公司(ThoughtWork)。我很不喜歡這篇文章,因為語氣不只是差,還有許多人身攻擊"This is that rant. It is part of my grand exit strategy from the Ruby and Rails community. I don't want to be a 'Ruby guy' anymore, and will probably start getting into more Python, Factor, and Lua in the coming months. I've got about three or four more projects in the works that will use all of those and not much Ruby planned. This rant is full of stories about companies and people who've either pissed in my cheerios somehow or screwed over friends. I can back all of them up from emails, IRC chat logs, or with witnesses. Nothing in here is a lie unless it's really obviously a lie through exaggeration, and there's a lot of my opinion as well."
之類的話語。更讓我覺得 Zed Shaw 的 EQ 似乎不是很好。Dave Thomas Ain’t No Sammy Sosa (He’s Just Fat)
祝你在新的社群有好的發展,還有 Ruby 社群沒有加蓋,你在外面受到不好的遭遇可以游回來呀。Goodbye My Love,我的愛人再見
