mysql,Linux,HighPerformance,ruby on Rails

2010年12月24日星期五

authlogic with rails3,遇到问题,找到方法,解决之路

authlogic是认证gem,是当前最普遍使用的一款工具包,对rails3集成还不是很完美。(特对rails3.0.3+ruby1.9.2p0)
这里特意把相关的参考资料索引在这里,方便你来使用:

http://asciicasts.com/episodes/160-authlogic
这里思路和代码都比较完整。

https://github.com/binarylogic/authlogic
authlogic的codebase

http://www.dixis.com/?p=352
这个提到了使用rails3_generators

http://techoctave.com/c7/posts/37-authlogic-and-rails-3-0-solution
这个提到了问题的根源和解决方法

--
tommy xiao
E-mail: xiaods(AT)gmail.com

2010年12月5日星期日

2010年11月21日星期日

rails3 Nested Forms blah blah

Rails3 UJS and nested form, I have searched more sample like,eg: this.
I found all reference's source is Ryan Bates nested form exmaple,based in github. but in rails3,i came crome this view [1]. it's all sucks.
the cause reason is the hidden temple default value is false.when sumit action,the hidden values will not discard,and continue update this params.
i see the log,i think maybe some validation is wrong. oh,i found the original accepts_nested_attributes_for is
reject_if => lamda {|a| a.values.all?(&:blank?)}
this is blocker question.
i change the evalution assert to :
reject_if => proc {|a| a[:name].blank? }
attention,the:name is task's attribute name.
this is indicate original code is not working on rails3.
this is all.done.for your convinent test,i have attached my sample deme.have a try.

1.see attached project-nestform.png
2.nestform4rails3.zip

--
tommy xiao
E-mail: xiaods(AT)gmail.com

2010年10月18日星期一

SSH With PublicKey issue:SSH Error: Permission denied (publickey,gssapi-with-mic) resolve way.

今天给一个服务器加public key认证。出错:
Permission denied (publickey,gssapi-with-mic)
sshd_config配置是以前的备份,不会有错,就是过不去。网上一大堆出招的,但均无效果。
回到问题报错提示,这个应该是权限,但哪里呢?
最后还是这里给了提示
make sure that the *right* permissions are set up

drwx------ 2 virender virender 4096 May 7 04:51 .ssh
-rw------- 1 virender virender 393 May 7 03:41 .ssh/authorized_key

还有不少人遇到我这个问题,但都没人解决.

其实就是.ssh目录权限如果太大,sshd是不让使用公钥认证的。
所以,在你配置完之后,这样处理:
$ chmod go-w ~/
$ chmod 700 ~/.ssh
$ chmod go-rwx ~/.ssh/*
OpenSSH may also refuse to support public key authentication if the file permissions are too open.
OpenSSH在文件权限属性太开放,还是会拒绝支持公钥认证。

Done.


--
tommy xiao
E-mail: xiaods(AT)gmail.com

2010年10月12日星期二

OpenOffice 3.2.1 On Fedora 13 Installation log

在Fedora 13上,安装OpenOffice 3.2.1总是不顺利,Shit!记录下来

想删除:
rpm -qa | grep ooo > rmlist
rpm -qa | grep openoffice >> rmlist
rpm -e `cat rmlist`

想安装:
dxiao ~/Downloads/src $ tar zxvf OOo_3.2.1_Linux_x86_install-rpm-wJRE_en-US.tar.gz
dxiao ~/Downloads/src $ cd OOO320_m18_native_packed-1_en-US.9502/
dxiao ~/Downloads/src/OOO320_m18_native_packed-1_en-US.9502 $ sudo ./setup
Done!



--
tommy xiao
E-mail: xiaods(AT)gmail.com

2010年10月9日星期六

遇到的Rails3 动向记录

1.adding "-j" parameter for "rails new" command

这个patch意在把jquery集成,改进集成的复杂度。+1, Rails Core Team还在review中,激烈啊

2.rails3下想使用thin,gem install thin,然后加到Gemfile,使用rails s thin启动。

3.读到Santiago Pastorino的rails学习过程,心得和上一博文中得到的经验一样,从lighthouse入手。当然最重要的还是坚持。

4.Phusion Passenger 3.0.0 RC1发布啦,老用户可以测试一把。

5.学东西例子最重要,把别人的代码拉下来跑一跑,理解起来快多了。当然这种方式适合进阶,新手莫入。Rails 3 example of jQuery UJS



--
tommy xiao
E-mail: xiaods(AT)gmail.com

2010年10月8日星期五

Rails3 Contribute workaround

1.是要看这个地址:
http://guides.rubyonrails.org/contribute.html
这里详细介绍了review Rails代码需要的过程。

2.订阅maillist: Rails-core,如果你有gmail,可以使用标签+过滤很方便的管理邮件列表。

3.到github.com Fork一个rails工程,然后在本地:
cd rails
bundle install
更新一下本地依赖包。

4.关注Rails-core邮件列表的每一个帖子。把别人的patch下载后在本地测试。把测试结果可以贴到lighthouse,这就是你社区贡献的开始。虽然没大牛写程序那么直接,但等你熟悉代码后也是可以贡献patch的。


--
tommy xiao
E-mail: xiaods(AT)gmail.com

2010年9月15日星期三

JasperETL遇到org.eclipse.swt.SWTError: XPCOM error -2147467259说明

我下载的JasperETL-All-r35442-V3.2.3,起来后想import demo发现报如下错误:
[xds2000@localhost jasperetl]$ org.eclipse.swt.SWTError: XPCOM error -2147467259
    at org.eclipse.swt.browser.Mozilla.error(Mozilla.java:1597)
    at org.eclipse.swt.browser.Mozilla.create(Mozilla.java:285)
    at org.eclipse.swt.browser.Browser.<init>(Browser.java:118)
    at org.talend.repository.ui.actions.importproject.ImportDemoProjectPage.createDescriptionIn(Unknown Source)
    at org.talend.repository.ui.actions.importproject.ImportDemoProjectPage.createControl(Unknown Source)
    at org.eclipse.jface.wizard.Wizard.createPageControls(Wizard.java:170)
    at org.eclipse.jface.wizard.WizardDialog.createPageControls(WizardDialog.java:669)
...略

原因大家说的都不清楚。我这里调查了一下,原因是JasperETL使用的Eclipse 是3.4版本的。现在eclipse 3.4 line已经不再维护了,你可想而知多么的烂。
开源软件的烂就是磨练我的意志。。。:-)

--
tommy xiao
E-mail: xiaods(AT)gmail.com

2010年9月14日星期二

开源就是南泥湾-解决JasperETLv3.2.3不能正常启动问题。

下载JasperETL-All-r35442-V3.2.3安装包。解压到本地。
cd JasperETL-All-r35442-V3.2.3
chown +x JasperETL-linux-gtk-x86
./JasperETL-linux-gtk-x86
抱如下错误:
ERROR: Exception during Initialization
java.lang.NullPointerException
    at org.talend.designer.codegen.config.JetBean.getUri(Unknown Source)
    at org.talend.designer.codegen.config.JetBean.getTemplateFullUri(Unknown Source)
    at org.talend.designer.codegen.model.CodeGeneratorEmittersPoolFactory.initializeEmittersPool(Unknown Source)
    at org.talend.designer.codegen.model.CodeGeneratorEmittersPoolFactory.access$7(Unknown Source)
    at org.talend.designer.codegen.model.CodeGeneratorEmittersPoolFactory$JobRunnable.doRun(Unknown Source)
    at org.talend.designer.codegen.model.CodeGeneratorEmittersPoolFactory$JobRunnable.run(Unknown Source)
log4j:ERROR Plugin: org.talend.libraries not found in TOSAppender.
Exception in thread "Code generation background thread" java.lang.IllegalStateException: Workspace is closed.
    at org.eclipse.core.resources.ResourcesPlugin.getWorkspace(ResourcesPlugin.java:339)
    at org.talend.designer.codegen.model.CodeGeneratorEmittersPoolFactory$JobRunnable.doRun(Unknown Source)
    at org.talend.designer.codegen.model.CodeGeneratorEmittersPoolFactory$JobRunnable.run(Unknown Source)

问题的关键就是xulrunner版本在捣鬼。先确认eclipse里xulrunner的版本:
在菜单[help]->[about eclipse]
再点击弹出面板中的installation Details按钮,然后显示的eclipse所有插件列表。
找到xulrunner插件为:  XULRunner    1.9.1.2_v201003050540R    org.jboss.tools.xulrunner.feature.feature.group
然后在系统中确认你的nulrunner版本是否和此插件一致。
如果不一致,就会抱错。解决方法是指定xulrunner版本

下载包:
http://releases.mozilla.org/pub/mozilla.org/xulrunner/releases/
选择你需要的版本。
如1.9.1runtimes
http://releases.mozilla.org/pub/mozilla.org/xulrunner/releases/1.9.1.11/runtimes/
解压放在/usr/local/lib/xulrunner
然后在JasperETL启动配置文件:类如JasperETL-linux-gtk-x86.ini加上一行就可以解决你的问题。
-Dorg.eclipse.swt.browser.XULRunnerPath=/usr/local/lib/xulrunner/

Done!
--
tommy xiao
E-mail: xiaods(AT)gmail.com

2010年8月11日星期三

读gem sourcecode or doc的工具

阅读别人的代码,估计是最好的学习方式了。但遥想之前,不管是java获得C++,要求阅读者具备的积累都不是"一天"就能搞定的。
Ruby语法简单,有点不优雅,但让我能快速学习上手。
tip:
gem install open_gem

安装此插件后,
gem open rails 就可以读原码。
gem read rails 就可以看文档。

当然操作系统也要提个好的,fedora是我的推荐。


--
tommy xiao
E-mail: xiaods(AT)gmail.com

2010年8月9日星期一

git pull config question

I think this very useful for git user, just notice this url

Under [branch "master"], try adding:

[branch "master"]
    remote
= origin
    merge
= refs/heads/master

This tells Git 2 things:

  1. When you're on the master branch, the default remote is origin.
  2. When using git pull on the master branch, with no remote and branch specified, use the default remote (origin) and merge in the changes from the master branch.


ref:
http://stackoverflow.com/questions/658885/how-do-you-get-git-to-always-pull-from-a-specific-branch

WEB基本功,HTML优化

今天看了一篇文章,HTML优化,很实用。
http://perfectionkills.com/optimizing-html/
中文版也不缺乏:
http://younglab.blog.51cto.com/416652/294670

--
tommy xiao
E-mail: xiaods(AT)gmail.com

2010年8月3日星期二

Rails3使用jquery rjs,可能需要注意的地方。mark

这里假设你使用rails3, jquery rails.js

你想实现ajax loading效果,却发现rails的tag里只使用:remote => true
并没有rails2里使用的loading函数。
我看了rails.js,看到

The UJS drivers trigger six events on every AJAX call:

  • ajax:before
  • ajax:loading
  • ajax:success
  • ajax:failure
  • ajax:complete
  • ajax:after
但是怎么使用是个问题。
看了这个ticket,就知道并不是所有人了解:
https://rails.lighthouseapp.com/projects/8994/tickets/4486-new-ujs-helpers-do-not-have-a-way-to-render-a-loading-text-icon
his can easily be accomplished each driver has a custom callback that fires before the request is sent, here is an example using the jQuery driver.
  $('#new_resource').live('ajax:loading', function() {
// code to display loading div
});


refs:
https://rails.lighthouseapp.com/projects/8994/tickets/4486-new-ujs-helpers-do-not-have-a-way-to-render-a-loading-text-icon
http://www.slideshare.net/adamlogic/jquery-and-rails-sitting-in-a-tree
http://code.alexreisner.com/articles/link-to-remote-with-ujs.html

2010年7月24日星期六

Rails3beta4使用Ajax的一些参考

update: prototype更新有点误解,现在已经更正。

Rails3Beta4的Ajax参考文档目前不是很多,因为版本更新很快,参考的内容很多都已经过期.完整可参考的文档少之又少.经过近期项目的经验,我想总结一下:
1, Rails3Beta4已经快接进RC,想使用ajax,直接在link_to,form_tag,form_for加上remote=> true,就能产生ajax request, Controller里加不加respond_to都会去找rjs,或js.erb.两个后缀没有什么差别,关键在于使用js.erb感觉和.html.erb统一了后缀名而以.(今天跑个demo,才知道使用js.rjs就可以调用prototype了,方法可以在ActionView::Helpers::PrototypeHelper::JavaScriptGenerator::GeneratorMethods里找到。你可以使用railsapi.com生成的文档查看到 )
2.我在使用form_tag里加上select_tag,想使用select_tag的onchange加上submit事件来请求form_tag中的ajax,不能成功.感觉是我的思路的问题,直接使用select_tag没有remote属性,不过直接使用ujs的onchange事件里加上ajax就能控制.通过这样的体会,你会发现使用UJS确实比Rails之前的RJS更简单,更方便,实现的效果和原来的是一样的.一样可以调用contorller里的方法及js.erb.
JQuery的UJS调用参考文档多,所以大家才想办法在Rails里去掉prototype使用jquery.不然如果直接prototype,怎么使用还需要去看prototype,有点让新人不知手措.(教程是没更新的,但查文档是有helper函数,生成项目试用就可以上手。)
总结,Rails3里,ajax的使用更开放,也就是说,其实你在rails3中使用哪个框架都可以,只需要修改一个rails.js就可以了.
参考:

--
tommy xiao
E-mail: xiaods(AT)gmail.com

2010年7月16日星期五

RVM,标准配置Ruby环境的首选

rvm,快速,高效,简洁,所以你需要的优化,它全部具备。只要你有一台Linux/Mac系统,就可以在5分钟内完成安装(限制仅在你的网速)。
第一步:
$ bash < <( curl http://rvm.beginrescueend.com/releases/rvm-install-head )

第二步:
在你的.bash_profile,把这段放在最后一行,保证PATH里有它就可以.贴上后,新开一个terminal,然后source ~/.bash_profile就可以了。

[[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm"
第三步:
安装你可爱的Ruby环境吧
$ rvm install 1.8.7
可选,第四步:
想使用就这样操作:
 $ rvm 1.8.7

想知道更多,运行这句:

$ rvm list
或者:
$ rvm help


第五步:
想把整个ruby版本作为自己默认的环境,运行这句:
$ rvm 1.8.7 --default

收工。去玩Ruby& rails吧

参考这里:
http://everydayrails.com/2010/06/28/rvm-gemsets-rails3.html
--
tommy xiao
E-mail: xiaods(AT)gmail.com

2010年7月11日星期日

ruby1.9.1对String的处理有细微差别,注意

今天在ruby1.9.2-dev环境下起Oria,报了个错:
/Users/xiaodeshi/.rvm/gems/ruby-1.9.2-head@rails3beta/gems/oria-0.1.1/lib/oria.rb:57:in `+': String can't be coerced into Fixnum (TypeError)
        from /Users/xiaodeshi/.rvm/gems/ruby-1.9.2-head@rails3beta/gems/oria-0.1.1/lib/oria.rb:57:in `block in port'
        from /Users/xiaodeshi/.rvm/gems/ruby-1.9.2-head@rails3beta/gems/oria-0.1.1/lib/oria.rb:57:in `each'
        from /Users/xiaodeshi/.rvm/gems/ruby-1.9.2-head@rails3beta/gems/oria-0.1.1/lib/oria.rb:57:in `inject'
        from /Users/xiaodeshi/.rvm/gems/ruby-1.9.2-head@rails3beta/gems/oria-0.1.1/lib/oria.rb:57:in `port'
        from /Users/xiaodeshi/.rvm/gems/ruby-1.9.2-head@rails3beta/gems/oria-0.1.1/bin/oria:43:in `parse_options'
        from /Users/xiaodeshi/.rvm/gems/ruby-1.9.2-head@rails3beta/gems/oria-0.1.1/bin/oria:49:in `start'
        from /Users/xiaodeshi/.rvm/gems/ruby-1.9.2-head@rails3beta/gems/oria-0.1.1/bin/oria:11:in `go'
        from /Users/xiaodeshi/.rvm/gems/ruby-1.9.2-head@rails3beta/gems/oria-0.1.1/bin/oria:76:in `<top (required)>'
        from /Users/xiaodeshi/.rvm/gems/ruby-1.9.2-head@rails3beta/bin/oria:19:in `load'
        from /Users/xiaodeshi/.rvm/gems/ruby-1.9.2-head@rails3beta/bin/oria:19:in `<main>'

心中奇怪,这昨天才用了一下没这问题啊。找开对应文件定位到:
  def self.port
    @@port ||= "Oria is easily the coolest in-memory, super-simple KVS. Cool people use it.".split("").inject(0) {|total, char| total += (char[0].class == String ? char[0].ord : char[0])}
  end

直接去irb下跑,原来作者是使用charcode加出来的一个端口,但1.9.2修正了1.8.7字符串的显示不一致问题。
原来在1.8.7下,'a'[0]出来的是ascii code,但在1.9.2下'a'[0]还是返回'a',这代码就跑不动了。
ok,了解原因后,改一行就ok了。
@@port ||= "Oria is easily the coolest in-memory, super-simple KVS. Cool people use it.".split("").inject(0) {|total, char|  total += (char[0].class == String ? char[0].ord : char[0])}

兼容1.8.7.


--
tommy xiao
E-mail: xiaods(AT)gmail.com

mac下删除ports,使用homebrew

homebrew是为rubist准备的安装管理器,所以port删除是当务之急。
search并当了一回小白鼠,成功! http://guide.macports.org/chunked/installing.macports.uninstalling.html
第一步:
% sudo port -f uninstall installed
第二步:
% sudo rm -rf \
/opt/local \
/Applications/DarwinPorts \
/Applications/MacPorts \
/Library/LaunchDaemons/org.macports.* \
/Library/Receipts/DarwinPorts*.pkg \
/Library/Receipts/MacPorts*.pkg \
/Library/StartupItems/DarwinPortsStartup \
/Library/Tcl/darwinports1.0 \
/Library/Tcl/macports1.0 \
~/.macports


--
tommy xiao
E-mail: xiaods(AT)gmail.com

2010年6月27日星期日

28字节ruby代码带来的乐趣!

是的。你没有看错,这是我今天看到的代码:
def p.method_missing*_;p;end

第一次看,还是没有看的全明白。然后咱们来个格式化后的版本:
class NilClass
def method_missing *_
nil
end
end

别钻牛脚尖,非要一个字符字符对,看中间精华部分。此代码的作用是针对实例对象类如@some_hash,是个hash,
你想得到key=>value值时,出现nil时,提供的解决办法。

你可能希望这样的代码:
if @some_hash[:some_key] # good looking version
# do something with @some_hash[:some_key]
end


但如果@some_hash是nil,上面的代码就会出exception了。
你不得不这么写:
if @some_hash && @some_hash[:some_key] # correct version
# do something with @some_hash[:some_key]
end

再来一个完整的代码实例:

# Egocentric nil
# code by Yohan, slightly edited and comments by me

# start ego mode block, usage:
# catch_nil do
# if @some_hash[:some_key].to_formatted_array[3]
# # do something
# end
# end
def catch_nil(&block)
# grip methods
ori_method_missing = NilClass.instance_method(:method_missing)
catch_method_missing = NilClass.instance_method(:catch_method_missing)
# activate ego mode
NilClass.send :define_method, :method_missing, catch_method_missing
# run code
yield
ensure
# no matter what happens: restore default nil behaviour
NilClass.send :define_method, :method_missing, ori_method_missing
end
#alias :egonil :catch_nil # ;)

# this is the ego nil
class NilClass
def catch_method_missing(m, *args, &block)
nil
end
end
不管怎么说,真的很优雅。ruby is awesome!

详细看这里:

The 28 Bytes of Ruby Joy!

--
tommy xiao
E-mail: xiaods(AT)gmail.com

2010年6月14日星期一

use jruby+sinatra+jfreechart build StackedBar graph! - Series 1

FYI,jruby is now 1.5.1, i want to build gpaph service.so i want to familiar with jruby and jfreechart api. this is blow doc is my practice notes.any feedback welcome.

first step:
use jruby+jetty+sinatra stack:


only git clone done.you will have done this stack in local

second step:

create your rb file:

charting.rb
==========
require 'rubygems'
require 'sinatra'
require 'java'

import 'org.jfree.data.category.DefaultCategoryDataset'


class DefaultCategoryDataset
  class Inner
    def initialize(dataset, row)
      @dataset, @row = dataset, row.to_s
    end

    # a value of nil can call 'removeValue'
    def []=(column, value)
      @dataset.addValue value.to_java(:int), @row, column.to_s
    end

    def populate(hash)
      hash.each_pair do |column, value|
        @dataset.addValue value.to_java(:int), @row, column.to_s
      end
    end
  end

  def [](row)
    Inner.new self, row
  end
end


module Graph
  class StackedBar
    include_class 'java.io.File'
    include_class 'org.jfree.chart.ChartUtilities'
    include_class 'org.jfree.chart.JFreeChart'
    include_class 'org.jfree.data.category.DefaultCategoryDataset'
    include_class 'org.jfree.chart.ChartFactory'
    include_class 'org.jfree.chart.plot.PlotOrientation'

    def initialize(width=600, height=400, data=[])
      @width = width
      @height = height
      dataset = create_sample_data() if data.empty?
      @chart = create_chart(dataset)
    end

    def render_to_file(filename, format="png")
      puts "Rendering graph to #{filename}"
      javafile = java.io.File.new(filename)
      ChartUtilities.saveChartAsPNG(javafile, @chart, @width, @height)
    end

    private
    def create_sample_data
      # This also allows symbols as well as strings
      dataset = DefaultCategoryDataset.new
      dataset[:Submitted].populate(:A => 1, :B => 2, :C => 3)
      dataset[:Assigned].populate(:A => 1, :C => 1)
      dataset["In-work"].populate(:A => 3, :C => 3)
      dataset[:InVerfication][:A] = 1
      dataset[:Delivered][:A] = 2
      dataset[:Rejected][:B] = 1
      dataset[:Closed][:B] = 1
      dataset["On-hold"][:C] = 2
      dataset
    end

    def create_chart(dataset)
      chart = ChartFactory.createStackedBarChart("XYZ's Development Projects",
                                                 "Project Name", 
                                                 "Hours", 
                                                 dataset, 
                                                 PlotOrientation::VERTICAL, 
                                                 true, 
                                                 true, 
                                                 false)
      return chart    
    end
  end # class StackedBar  
end # class Graph

get '/' do
  sb = Graph::StackedBar.new
  @pp = "stacked_bar.png"
  img_pub = "public/images/"
  sb.render_to_file(img_pub+@pp)
  erb :graph
end




--
tommy xiao
E-mail: xiaods(AT)gmail.com

2010年5月18日星期二

CGI和FASTCGI协议认知心得

前段时间去面试,被问到关于什么是CGI协议,懵了不会。因为使用ruby总需要与CGI打交道,我还是今天把功课补上,毕竟是手上的事。读了一下CGI的RFC3875,如果用一句来说,它是一个纯文本的协议。
通过Meta关键字=VALUE形式组成一个数组,与上端的Web
Server和下连的Script互相交流。从我们web程序员的角度来说,是透明的。但它针对每个Request都会起一个进程,所以之后引进了FastCGI,改良的地方就是针对客户端的Request,FCGI只开一个主进程,内部使用分组复用的技术(有点像CDMA时分复用的技术,如果你有通信方面的背景的话,对这个肯定能有所了解。)加快处理并返回Response。
另外,RFC里有一个表达式:巴科斯范式,也顺便学了一下,你也不妨学一招吧.

参考:
http://www.ietf.org/rfc/rfc3875.txt
http://en.wikipedia.org/wiki/FastCGI

2010年5月9日星期日

使用Vagrant快速部署测试环境,给Rails3打Patch简单到小儿科!

今天看一文章,rails社区竟然有人作了一个Vagrant gem调用Oracle's VirtualBox快速虚拟出ubuntu下的rails开发环境。
我看了一下gist安装指令,已经进化到一键完成的地步,犹如当年GhostXP操作一般,这哪有什么技术含量啊,呵呵。
这样的环境对于社区开发来说,绝对是一记强行针,学会这招之后,你也可以参考Rails开发者指南,你就会了解到,想给Rails写Patch之前,第一步都是去LightHouse看看感兴趣的问题,如果有人贴了patch,就需要快速有个环境来测试了,所以之前的工具就是为这种场景下的需求准备的。但这个gem的产出,带来了一种全新的,简单的开发流程模式,相信一定会给其它开源社区的开发者带出更多灵感!赞!

参考链接徘徊于墙外:

2010年4月24日星期六

Fat Free CRM on Heroku,可扩展的CRM套件

如果在Rails关注一年以上的朋友,都可能听说过这个套件Fat Free Crm,这个套件基于Rails 2.3.5,功能写的不多不少。非常方便定制。
我也是近期需要一个可扩展的框架才回过头来找到它的。对于前期实践,我想着如果放到heroku上作实验更方便,就试着搜索了一下,
还真有解决方案:
$ git clone git://github.com/ryanwood/fat_free_crm.git
$ heroku create
$ git push heroku master
$ heroku rake crm:setup USERNAME=myusername PASSWORD=mypass EMAIL=my@email.com
Cool!

ref: http://ryanwood.com/past/2010/1/21/fat-free-crm-on-heroku/

--
tommy xiao
E-mail: xiaods(AT)gmail.com

2010年4月22日星期四

拥抱Rails3-学会用bundler

Bundler是什么,它是在Rails3下管理gem的工具。就这些。
你生成Rails3框架后,在标准目录下就会生成一个Gemfile文件。

你要管理维护你的应用的gem就靠它了。
可以指定Git源
gem 'savon', :git => 'git://github.com/hoopla/savon.git'
gem 'arel', :git => 'git@github.com:hoopla/arel.git'

也可以指定本地路径:

gem 'mygem', :path => '/path/to/my/gem'

指本地的好处是,你如果使用一个频繁更新的gem可以测试有没有问题。如果有个gem出了问题,你也可以下载下来打个patch
在本地build出gem测试。非常方便。

安装步骤更简单:

rails2时代,咱们要安装运rake gems:install

现在rails3时代,咱们使用bundle install
简单高效管理,这就是新时代的web开发工具
参考:
http://matschaffer.com/2010/04/things-i-love-about-bundler/

--
tommy xiao
E-mail: xiaods(AT)gmail.com

2010年4月20日星期二

Phusion Passenger性能调优及监控实践,

使用Rails的朋友们,肯定对Passenger熟悉了。性能调优看文档啊。不过今天发现一个汇总与大家共享:

Performance Tuning for Phusion Passenger


另一篇是监控。使用Munin实现。

我想需要部署的朋友,有了这两篇文章垫垫底,应该信心实足吧。
如果有什么心得想与我分享,请twitter上DM我。@xds2000
决对的水贴,鄙视一下自己脆弱的心灵。:-)
--
tommy xiao
E-mail: xiaods(AT)gmail.com

2010年4月12日星期一

Camping,轻量级Web框架 For Ruby世界


一般人的思维要推荐一个东西,都会把其祖上所有的荣耀都列出来。但技术上推荐并不遵循此规则,例如今天有用的东西明天有可能就是过时的。有的东西需要的人有用,不需要的人再推也没有用。Camping就是这样的东西。

Camping,web框架,小到一直保持4KB的文件大小。你可以Rails的MVC风格把所有需要的代码写在一个rb文件里。

http://camping.rubyforge.org/index.html

参考书,指南全部上面这个地址上。你不用太操劳去收集资料。当然首先你的英文要过关。不过关的请自修再来。

我的理解里,这是一个玩具,足够好的玩具。并不只有你一个人在玩它。
加入邮件列表,即可看到志同道合者:
http://rubyforge.org/mailman/listinfo/camping-list

--
tommy xiao
E-mail: xiaods(AT)gmail.com

2010年4月6日星期二

我的互联网从业的一些心得,以示明鉴!

      多年以前在我刚刚踏入互联网从业时,一直是有些问题不得期解!也曾试着和同事、朋友聊过天,我们应该怎么做才能成功,但始终没有满意的结果。近来,我重新整理了一些思绪写在这里,以示明鉴。
      首先的问题,就是做什么工作才能适合自己。这些年里我发现成倍的年青人投入到互联网行业,不管是大学毕业专业就是计算机,还是改行做计算机,大家都是试图想把自己锤炼成计算机专家。目的呢,也就是想在计算机领域能谋得一份薪水丰厚的好工作。其实我当初踏入互联网行业时的直接目的就是这样的,我相信大部分的从业者也是希望如此。但这个想法呢,在职场里总是在这样那样的条条框框中变的不那么透明,路不好走啊。但坚持下来之后,还是没有领悟生活的真谛的话,还是会很迷茫,那请你和我一样,认真的去整理自己的思绪,规划一下发展。总结下来,就是要定期的反省,规划自己的职场之路。
     第二,大家一进互联网行业,那是身不由己地从事着多种职位,这些职位对计算机的要求那真是五花八门,什么都有。大家看多了,就会发现大部分的公司并不会关心你的职场发展方向,只找够用的,价格便宜的。靠,这个社会真黑啊。嘿嘿。所以说,什么事情还是自己积极努力规划好自己的路子,不要东一榔头西一棒子,到处积累经验。所以当hr给你打电话,认为你合适他们,你一定要坚持原则,做自己擅长的领域。只有这样,你学到的知识才会用上。
     第三,我遇到一些年青的朋友,同事,自己手艺不精,所以机会也不多,之前的职场求职当然也不顺利。学技术嘛,是一个漫长的过程。其实这个道理呢,大家都明白。但还是要在这里说一句,那就是大家学习过程中一遇到困难就猜,就想。总是不喜欢动手去做做。当然实践只可能是局部的事实,不要把规则当成死条条,用事实去说话。这是很有用的,按照党的思想发展来看,实践出真知啊,实事求事啊都是说的这个道理。
     第四,很多事情说一万遍都是表象,不管是打工,还是做生意,都一定会遇到困难。所以在做事之处,是一定要想法,你想做什么。我这么说,有些会说,那我想一个别人想不到的方法,开发一套最先进的框架,架构一个最牛的网络架构,这样我不就牛了吗?不是的,你走错路了。说白了,你想到的,别人有可能
早就想出来过了,你是不是觉的别人知道你的想法后会有一点点沮丧。但为什么有那么多做同样事情的公司
都成功了。这里面是一定玄机的,我这里点一点我发现的一些,打个具体的比方,比如商城网站,那么多的应用,为什么大家还要一遍一遍的去做呢,并且有很多家。说白了,商业成功的密秘并不是卖的产品,而是卖的你理解的产品理念。你理解中的产品是什么样子你就做成什么样子。这样如果消费者认可你,他是一定会买单的。所以之前大部分的模仿根本就是假像。这样一个商业的秘密,之前一直在作用,现在还在起作用,我相信未来也必将作用之互联网。


--
tommy xiao
E-mail: xiaods(AT)gmail.com

2010年3月22日星期一

相当完美的使用AppEngine的Email服务,中小企业的福音!

之前实践过AppEngine的邮件服务,支持中文,每天2千的邮件量。对于中小企业想提供邮件服务,这是完全可行的。在用过jruby和python开发appEngine
程序的过程中,体会到这"锤子"还是要因地制宜的使用,python在AppEngine上真的很好使用,这不能怪Ruby,只是Google对Python支持的完整。即然
用别人的场地练活,还是do it simple为妙!
下载使用过这个,并且还顺手给它打了一个utf-i的patch.
http://github.com/benjaminpearson/gae-web-services
提供了图片服务和邮件服务。
今天又看到有一个新库,对google appengine email提供了另一个单独的库,值得推荐:
http://github.com/maccman/remail-engine
再配合rmail,你就可以在你的rails项目里使用此mail服务了。

一步一步的指导看这里:
http://leadthinking.com/233-sending-or-receiving-emails-with-rails

请多实践,以此纪念Google退出大陆的壮举!


--
tommy xiao
E-mail: xiaods(AT)gmail.com

2010年3月15日星期一

A rigorous approach to high performance

这是读Thinking-Clearly paper的心得笔记,有点零碎,乱,见谅。可twitter@xds2000与我交流
规避试错的“苯”方法,学习使用可让人信服的科学方法是本Paper的主旨。
respone time,throughput它们是相关联的,还需要分场景分而制之
解决之道:
第一步,what is the goal state that you want to archieve?
第二步,profile

另外,阿姆达尔定律(Amdahl's law )需要考虑:
阿姆达定律表明:通过改进某模式得到的整体性能提高,受限于该改进模式所占的运行时间比例。
引入M/M/m公式,其中m就是你的CPU核数
想说明一个问题就是就的系统即使是可完美的,也会有阀值,超过它就会
降低性能,遵从阿姆达尔定律。
(15.relevance  of the knee)
总结:
假如你有一个伴随随机请求访问的系统:
1,你的系统的每个资源都有阀值点
2. 你的系统的阀值必定小于“默认”的阀值(作者统计了一个系统默认阀值)
3.假如你无限制持续的访问系统任一资源势必导致触发性能阀值,随之
你就会遇到性能问题。

16.capacity planning (关键精华!)(注意:这里提的是随机访问的系统,例如数据库)
知道前述的性能阀值原理可以消除很多运量容量规划过程中的复杂度。
1.你的目标容量是在系统高峰时你能满意运行任务的性能数值而不是无限制的使用资源
2.假如你持续保证系统资源的使用小于性能阀值,那你系统的性能表现就会是线性的。不会
出现指数异常。
3.无论你怎样让系统超过性能阀值访问系统资源,必定会遇到性能问题(不管你想还是不想)
4.假如你遇到性能问题,你并不需要花时间放在数学模型上;你需要花时间在重新定义负载或
消除负载或增加容量来解决问题
这就是在性能管理过程中的容量规划。




参考:
1.[Paper]Thinking-Clearly paper
http://method-r.com/downloads/doc_details/44-thinking-clearly-about-performance

如何理解javascript Closures

首先,我非Javascript专家也非Web开发的高手,仅仅是想掌握Javascript,所以遇到了这个
Closures,对我来说,如何用最质朴的语言描述快速理解掌握它是这篇博文写下去的动力。

以下就是我的理解,欢迎交流twitter: @xds2000
Javascript场景:
这里指的是ECMA 262第三版,对于Javascript来说,万物都是对象,function也是。

起步:
一个对象肯定有属性,对于javascript来说,对象除了属性,还有prototype,是什么,也是
对象,这个prototype也会有prototype,这样就形成一个属性链。两类,一类是属性,一类是
prototype。英文中叫prototype chain,这个chain的搜索路径会按父子关系向上查找,一直
到发现null prototype才会结束。那么在javascript中谁有null prototype呢,对,Object.prototype的
prototype,再细下来就是
Object -> prototype -> null prototype
也就是说Object的prototype非null,而是Object的prototype的prototype是一个null prototype.
语言描述起来会很傻,但就是这样。我是感觉这样理解更清晰多了。
对于对象属性,我们只关心赋值和读取两个操作。
对于赋值,没什么需要注意的。主要还是看读取。读取一个值,它(javascript interpreter)的行为
是先从对象实例找属性,没有再找其prototype chain,注意返回值是第一个找到的,即最近的
属性。因为对象是可以继承的,你别忘了。
下一步说scope
说起来我感觉挺麻烦,来段代码分析让你更清楚:
var y = {x:5}; // 创建了一个对象y,全局
function exampleFuncWith(){
    var z;

    with(y){

        z = function(){
            ... // inner function expression body;
        }
    }
    ...
}

//外面执行
exampleFuncWith();


上面这段怎么理解,这样,y是全局对象,exampleFuncWith是函数对象,被创建的时间,会
创建一个[[scope]]属性,是一个list或者link。干嘛用的,当然是把其对应的上下文中的对象都
创建引用,这样就形成一个chain了。
这里z = function() {...}是一个内部的function,它的scope是在with这段里,但关键是有一个y,
所以函数体被执行后会在y这个对象的[[scope]](是属性,你在程序界面是访问不了的,可理解为list和link)中创建一个内部函数引用。

铺垫那么多,这回说重点,什么是Closures呢,看这里:
function exampleClosureForm(arg1, arg2){
    var localVar = 8;
    function exampleReturned(innerArg){
        return ((arg1 + arg2)/(innerArg + localVar));
    }
    /* return a reference to the inner function defined as -
       exampleReturned -:-
    */
    return exampleReturned;
}

var globalVar = exampleClosureForm(2, 4);
javascript closures就是说返回一个函数和它的函数体上下文,也就是让另外的变量当内部函数的引用,也可以把这个引用赋值给另一个函数。这样形成一个环。你如果还是没有理解,可这样看外面变量或函数->外函数体->内函数体->外面变量或函数,这样不就是一个循环体嘛。但这些表面的不是关键,关键是我们如何理解内部函数是如何被调用的。我现在不说你肯定还是不能理解Closure的用处何在。还要看上面的代码,这段代码我们如何调用呢,这样走 globalVar(2),在解释到这个,首先看它的[[scope]] chain,这个chain中头一个就是exampleRetruned,为什么,因为是return的。别理解从 exampleClosureForm(2,4)了。这才是javascript的执行关键。因为我这里有一个2,所以内部函数的引用globalVar就是exampleReturned,你赋值一个2,相当于赋值给了exampleReturned的innerArg参数了。这就是Clores的关键精华。那最后你肯定会问Closures能干什么?可能我说你想怎么干就怎么干,你会鄙视我的无知态度。但事实上你只能在实践中就好比拿着锤子你不打几个钉子还是不会知道这锤子好不好用一样。就这样,以上理解是对参考1链接的读后心得,如有差错还请各位斧正不正确之处。

参考:
1. http://www.jibbering.com/faq/faq_notes/closures.html
2. JavaScript语言精粹

2010年3月9日星期二

Code reading:Auth:Clearance

Authentication is a common pattern in Rails apps基本上每个网站都会应用这个模块,所以练熟它是非常必要的。

rails里认证是一个经典的案例,每个开发者应该都会有自己的心得,作为web开发者,
通过实践熟悉这块必不可少。

我先选了Clearance,一个thoughtbot公司产出的代码整理些资料以备后用。
其代码最有特色的地方是使用shoulda和cucumber建立起来的测试流程,很是受用。
测试不是口头的,需要练,但没有代码练好像也不是那么容易,这份代码就是完整的
学习资料。
另外,注意,测试工具没有好坏,rspec,test/unit(shoulda)没有最优的,如果不学用,
它们都是废铁。

实现功能:

   * Register

   * Email confirmation

   * Encrypted password

   * Password recovery



thoughtbot通过项目经验总结出可重用的功能为:

  1. Sign up
  2. Confirm email
  3. Sign in
  4. Sign out
  5. Reset password


操作步骤:
在envirenment.rb加入:
  config.gem "clearance"
在命令行下输入:
script/generate clearance

通过override方法来实现自定义

参考:
1. http://wiki.rubyonrails.org/howtos/authentication-authorization/clearance
2. http://www.slideshare.net/jmorrison/clearance-simple-complete-ruby-web-app-authentication-presentation
3.http://robots.thoughtbot.com/post/159805955/clearance-rails-authentication-for-developers-who
4. http://wiki.rubyonrails.org/howtos/authentication-authorization
5.http://robots.thoughtbot.com/post/159805881/mixing-cucumber-with-test-unit-shoulda
6.http://wiki.github.com/thoughtbot/clearance/organization
7.http://robots.thoughtbot.com/post/159805560/tips-for-writing-your-own-rails-engine

2010年2月27日星期六

小写金额转换为大写金额(Ruby实现)

这个题目已经被无数人写过,网上有Ruby版,有Javascript版,有Python版,有JAVA版。但我看到的即没有测试也没有图例,能看的清晰的不多。
这不,我也凑凑热闹,写一版,方便大家对比指正。

我从网上整理的条件:
一、中文大写金额数字应用正楷或行书填写,如壹、贰、叁、肆、伍、陆、柒、捌、玖、拾、佰、仟、万、亿、元、角、分、零、整等字样。
二、 中文大写金额数字到"元"为止的,在"元"之后,应写"整"字,在"角"之后可以不写"整"字。数字有"分"的,"分"后面不写"整"字。
三、阿拉伯小写金额数字中有"0"时,中文大写应按照汉语语言规律、金额数字构成和防止涂改的要求进行书写。举例如下:
    (一)阿拉伯数字中间有"0"时,中文大写金额要写"零"字。如¥1,409.50,应写成人民币壹仟肆佰零玖元伍角。
    (二)阿拉伯数字中间连续有几个"0"时,中文大写金额中间可以只写一个"零"字。如¥6,007.14,应写成人民币陆仟零柒元壹角肆分。
    (三)阿拉伯金额数字万位或元位是"0",或者数字中间连续有几个"0",万位、元位也是"0",但千位、角位不是"0"时,中文大写金额中可以只写一个零字,也可以不写"零"字。如¥1,680.32,应写成人民币壹仟陆佰捌拾元零叁角贰分,或者写成人民币壹仟陆佰捌拾元叁角贰分;又如¥107,000.53,应写成人民币壹拾万柒仟元零伍角叁分,或者写成人民币壹拾万零柒仟元伍角叁分。
    (四)阿拉伯金额数字角位是"0",而分位不是"0"时,中文大写金额"元"后面应写"零"字。如¥16,409.02,应写成人民币壹万陆仟肆佰零玖元零贰分;又如¥325.04,应写成人民币叁佰贰拾伍元零肆分。

 写的图例在上面,你可以看。

代码在这里:两个文件:
chinesedecimal.rb
http://gist.github.com/316775

testhelpers.rb
http://gist.github.com/316780

你只要把上面两个文件贴到你的记事件成为对应的文件名,在命令行下键入ruby chinesedecimal.rb即可跑出结果。
因为有测试,所以我很放心这样的结果。即使有错误,我也可以通过测试样例去解决。这就是最简单的unit test过程了。

__DONE__

--
tommy xiao
E-mail: xiaods(AT)gmail.com

2010年2月25日星期四

使用rvm体验rails3-pre版

作为rails爱好者,现在rails3呼之欲出。但总归没有出来。想玩一玩,怎么搞呢。看下面:

1. Install Ruby Version Manager
 $ sudo gem install rvm $ rvm-install
2. Install Ruby 1.9.2 HEAD
 $ rvm install 1.9.2-head -C --enable-shared,--with-readline-dir=/opt/local
注意:readline目录你需要自己指定

$ rvm list rubies (执行此命令知道有哪些可以跑。)
 
rvm Rubies

=> ruby-1.9.2-head [ i386 ]

System Ruby

   system [ i386 ]

这行就是指定确认ruby runtime
$ rvm  ruby-1.9.2-head --default
最后验证一下:
 $ ruby -v ruby 1.9.2dev (2010-02-25 trunk 26759) [x86_64-darwin10.2.0]
3. 给gem当然创建一个集合,把这个beta版的所有依赖gem安装在这里,不合其它ruby runtime混在一起:
 $ rvm gems create rails3beta $ rvm 1.9.2-head%rails3beta
 $ gem install sqlite3-ruby
$ gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config
$ gem install --no-rdoc --no-ri tzinfo builder memcache-client rack rack-test rack-mount erubis mail text-format thor bundler i18n
$ gem install --no-rdoc --no-ri rails --pre
注意mysql_config的路径要配置成自己的。
最后成果如下:
 $ ruby -v   ruby 1.9.2dev (2010-02-25 trunk 26759) [x86_64-darwin10.2.0] $ rails --version   Rails 3.0.0.beta $ gem list   *** LOCAL GEMS ***  	abstract (1.0.0) 	actionmailer (3.0.0.beta) 	actionpack (3.0.0.beta) 	activemodel (3.0.0.beta) 	activerecord (3.0.0.beta) 	activeresource (3.0.0.beta) 	activesupport (3.0.0.beta, 2.3.5) 	arel (0.2.1) 	builder (2.1.2) 	bundler (0.9.7) 	erubis (2.6.5) 	i18n (0.3.3) 	mail (2.1.3) 	memcache-client (1.7.8) 	mime-types (1.16) 	mysql (2.8.1) 	rack (1.1.0) 	rack-mount (0.6.0, 0.4.7) 	rack-test (0.5.3) 	rails (3.0.0.beta) 	railties (3.0.0.beta) 	rake (0.8.7) 	sqlite3-ruby (1.2.5) 	text-format (1.0.0) 	text-hyphen (1.0.0) 	thor (0.13.3) 	tzinfo (0.3.16)
最后注意:
之后想使用这个rails3+1.9.2dev的完整环境,应该使用这个命令:
rvm 1.9.2-head%rails3beta
如果想返回系统本身的ruby
rvm system

这些都在rvm的手册有详细说明,不过想掌握,还是需要花时间看一会的。记住上面两条就已经可以应付90%情况。

最后你就可以创建一个rails3-pre
$ rails blog; cd blog
$ rails server

会出错:
 
Your bundle is complete!
run rails generate rspec:install from "."
/usr/lib/ruby19/gems/1.9.1/gems/bundler-0.9.8/lib/bundler/rubygems_ext.rb:20:in `alias_method': undefined method `dependencies' for class `Gem::Specification' (NameError)
from /usr/lib/ruby19/gems/1.9.1/gems/bundler-0.9.8/lib/bundler/rubygems_ext.rb:20:in `<class:Specification>'
from /usr/lib/ruby19/gems/1.9.1/gems/bundler-0.9.8/lib/bundler/rubygems_ext.rb:9:in `<module:Gem>'
from /usr/lib/ruby19/gems/1.9.1/gems/bundler-0.9.8/lib/bundler/rubygems_ext.rb:6:in `<top (required)>'
from /usr/lib/ruby19/gems/1.9.1/gems/bundler-0.9.8/lib/bundler.rb:4:in `require'
from /usr/lib/ruby19/gems/1.9.1/gems/bundler-0.9.8/lib/bundler.rb:4:in `<top (required)>'
from /home/hal/dm_rails3_app/config/boot.rb:6:in `require'
from /home/hal/dm_rails3_app/config/boot.rb:6:in `rescue in <top (required)>'
from /home/hal/dm_rails3_app/config/boot.rb:2:in `<top (required)>'
from /home/hal/dm_rails3_app/script/rails:9:in `require'
from /home/hal/dm_rails3_app/script/rails:9:in `<main>'

 郁闷吧。搞到这时就郁闷了.没关系,只要注释这行代码:
 
/rubygems_ext.rb:20
运行一切OK。

__DONE__

--
tommy xiao
E-mail: xiaods(AT)gmail.com

2010年2月23日星期二

我对AppEngine的理解及JrubyOnAppEngine入门最精简版

用Ruby一年了,让自己感触深处的是自己的成长。所以私底下里暗想,多去理解一门语言对于开发者还是有必要的。在ChinaonRails社区我正好发起一次线上Ruby聚会讨论Jruby on GAE,使用Google Wave来缩短Ruby爱好者的距离和时空。有不少朋友在Wave上Ping我,参加我发起的聚会,因为之前我们并不认识,也不了解对方,但我们就是通过Ruby话题能产生线上聚会的能力。用Google Wave来解决实用操作问题,这也是我突发奇想,因为我之前一直找不准用Wave能干嘛。所以试试吧。

言归正传,Google AppEngine对于开发者来说,它的价值在哪里。实际上我在按它的教程中一步走下来后,我认为那就是简化了开发流程,让开发者只要有网络,就可以发布自已的应用(有限制,但可以付费解决。实际情况是作中小行应用产生的流量还不是很差,对我们来说起步是没有问题的)。它可以存储数据,可以处理图片,邮件,还能Cron。在这样一个有限的空间里,目前我看到已经有的应用有Blog,Email及image Services.如果你是SOA的架构,你完全可以使用它来处理一个小功能模块。

上手时我使用了Python,可以说我对Python的学习就是1天的时间,我并没有想掌握这门语言,我就是去在线教程看了一下安装,helloword就可以了。你这时就可以去看Google Appengine的手册了,按着它的要求一步一步走下去作一遍。具体在哪里呢,这里的《使用入门》有Python,Java两块,全中文,只要是中国人就能去写。我当然直接Python直接去跑了一遍。理解到了WSGI和Ruby对应的就是Rack,对于什么是Rack可看这里,在Python中使用GAE的入门文档,不会有任何未之错误,一路走下来很快就能掌握。

当然为了明天(2-24星期三下午1点到2点)的聚会当主持,不至于什么都不清楚,我特意去找了JRuby的资料,很显然这块并不是很热,所以大部分单独使用Jruby结合GAE for JAVA SDK的文章,只会增加难度,让我也是很受伤。不过最后还是发现了金子:appengine-jruby,跟进了一下文档,实作了一把。明白它这个项目就是我们需要的,完全是一路顺风就能用上ruby On Engine。意义在于你会Ruby,那么你就可以直接无痛的实作在GAE上。
如果我理解没有错误的话,对于GData层,它使用DataMapper解决,Sinatra对应Google的webapps框架,这很重要,template也被HAML替换。也就是说你编码使用的是纯ruby。所以你完全透明使用它,不必考虑它的兼容性语法问题。Awesome!

那么如果你也想使用上JRuby On GAE的话,怎么整呢,入门手册你看多了也不会消化,我给你最直接的方式:
第一步:安装JAVA,5,6都可以,6当然好,性能取胜。
第二步:安装appengine-jruby gem,
 $ sudo gem install google-appengine
可能会出现问题,不要急,很有可能是gem兼容性问题,不用急着翻阅资料,看看错误性能再找找。为什么我这里强调就是因为我出现问题就去找了好大一会,其实是多虑了。
第三步:先跑hello应用:这里:

$ mkdir hello
$ cd hello
新建config.ru放在hello下,输入如下代码

run lambda { |env| Rack::Response.new('Hello World!').finish }

然后跑吧
hello $ dev_appserver.rb .
浏览验证它:
http://localhost:8080/

第四步:来个真实的sinatra版的helloWorld。 按这里走

以上就是全部,更多看这里

其实看多了也没有意义,就是Request,Respone这个模式。

总结下来,我们掌握了Jruby就可以作与twitter,Google..Service交互的web应用。
如果你想不出来,可以去github下去看看代码去部署一个Blog

参考:
appengine-jruby代码库:
http://code.google.com/p/appengine-jruby/

Yoko Harada
http://yokolet.blogspot.com/

Rake for jruby
http://github.com/nicksieger/jruby-rack

sinatra framework
http://www.nicecabbage.com/tag/sinatra/


__END__

2010年2月21日星期日

看Facebook是如何作网站优化的,即推荐OReilly的《Even Faster Websites》

update: 加一个Facebook的华人工程师作报告用的Slide

首先,鉴于Facebook需要翻墙才能浏览,上面的好友一只手就能数清楚,所以再次上去浏览新版的界面,并没有感觉有快的意思。但前几天,看到@Fenng推的链接,才点了链接看了Facebook的engineer's Notes的精彩技术分享:
Making Facebook 2x Faster 写的技术上的内容真是可以成为极致优化的精典案例了。用2009年差不多半年的时间就让浏览速度翻番,绝对的工程性创举,并且对我们来说,参考价值或者说可参考的点非常多。从思路到实作我感觉比它发布的PHP-Hithop更具实用价值。如果你的互联网工程师,绝对可以一读,长长见识遇到哪位大虾再乱喷也能作个心理有数。

第二,我要推荐的Facebook华人工程师作的报告,内容更是具体。小视频托管在youtube上,品质保证,地址是http://www.youtube.com/watch?v=51JGykHrwZA。当然要想从这个视频里获得点,我估计你需要能完全听懂英文。
都是中国人发音,你考虑下。:-),这里我说一下听到的心得,
1、我们做任何优化时都需要有参考数据,也就是Metrics。想起以前领导要求我作这样的分析,我能想到的就是去别的网站看看,再找一些历史数据分析分析。说白了我根本就没有数据可参考。杯具啊,硬着头皮去写一些优化性能报告。在看完Facebook的之后,我那思路其实就是扯淡,一点工程师的风格都没有。还好,现在听完之后起码不会乱搞。
2、Facebook的这次优化是极致优化,所以并不是国内工程师在搭建新系统的时候才想到的优化,所以这对性能及实施都是极度的挑战。所以他们想到了针对海量的Static Resource作管理,从技术上讲,这个技术根本就不是技术,但我斗胆相信国内根本就不会这种管理策略。懂的就想想别人的思路,不明白的您请绕道看下一段。
3、Quickling,Ajaxify的框架,细节不会透露,但真是汗颜的地方是他们对技术的娴熟程度给我一个新的启示,那就是要对技术的本质掌握。作互联网的工程师,你不对本质的东西来来回回的在心里面揣摩,肯定成不了专家。警示自己别去看什么JQuery的手册,看源代码。从本质入手。总想着作专职的"Javascript"专家。记住,专家的称号是别人给你的,如果没有本质的掌握,别人随时可能再给你拿走这个专家头衔。看好了,这后半句才是精华。

上面就是我这一天来的感受,当然言词中对Facebook技术的兴奋或更可说成是一种崇拜。但细想下来,人不可能一日成精,如果能赶上它们的步伐呢。是的,我找到一本书,其实也很知名,什么心得啊体会啊根本就不用写,你只需要知道两点,OReilly出版,书名《Even Faster Websites》.再送一句话,国内买不到,国内要刷Visa卡。当然喽,对于资本主义的糟糠,我们还是可以从垃圾桶里捡到.

http://i192.photobucket.com/albums/z18/virtualzin/eB/Eveastebsites.jpg


--
tommy xiao
E-mail: xiaods(AT)gmail.com

2010年2月19日星期五

第一章体会,About Driving Code Through Tests

http://covers.oreilly.com/images/9780596523015/cat.gif
《Ruby Best Practices》是一本很棒的Ruby技术提升书籍。有了它,成为Ruby"大牛"只日可待啊。呵呵。
首先第一章(Driving Code Through Tests)就从测试开始,足以显示测试技巧的重要性。那个咱们扪心自问,你在写最近的代码中是否有使用过Test?你有哪些不爽的地方想解决?不管怎么说,我是带着这些问题去看的这章。

第一步,Designing for Testability,书中讲的就是如何测试,是不是遵循"Red, Green, Refactor",按此法来跑测试会有什么误解,书中有一个论断:how much work needs to be done between each phase of this cycle.实际上这是在遵循TDD开发过程中遇到的比较实际的,并且是程序员需要面对的问题。所以这才是最重要的,这是一本写给Coder的书,它不是"教条课本",对咱们大白话来说,实用主义,拿来用先看看吧。因为书中代码使用的是Ruby Core Library,Test::Unit,所以有通用性,大家直接可以上手。事实上,在新手阶段,使用好Unit已经是很好的开始,而使用RSpec这种更为人性化的"复杂"的多的Test FrameWork来说,你应该在Testing学习中使用UnitTest.

第二步,Testing Fundamentals,测试基础,没有人天生就会写测试代码。别看那些牛人发布在github上的代码,上来就有test代码(当然也有垃圾代码,小心),让我等除了膜拜之外,无从下手。那么TDD中测试的关系点在哪几点呢,书中给了详细解释。

第三步,Testing Exceptions,测试异常,这是我之前没有注意到的,就是一个知识点,就是要会使用assert_raises,assert_nothing_raised,个中体会这是行为测试里面的东西吧,细节啊,要注意。

第四步,Run the Whole Suite at Once,把多个Test打包,怎么实现的。这里有技巧。

第五步,高级测试技术,Using Mocks and Stubs,(题外话:这个术语翻译起来我感觉特别绕口,还不好理解。因为从原理上来说,这英文术语和它本来的原意是有一个联系的,不然人家用它干什么。但如果翻译成中文,那就煞笔了,从此诀别原来的本意了。建议还是背英文单词都比翻译从中文强。说白了,有些技术,你就看这关键的词,把自己的心得记下来,慢慢体会这也是一种积累。)那么什么是Mocks,Stubs?实话实说,我说不清楚,但Martin大叔有论断:Mocks Aren't Stubs,一大陀英文看着说来挺费事,更推荐台湾友人的中文心得Slide。反正说来说去,有一点我是明白的,Mocks多用,Stubs是老Test风格,仅此而以。但限于开源软件的多样性,不管别人的代码是使用什么风格,我认为只要管用就可以,因为有test,总是能读懂的,你说是吧。这种提到的问题是测试的可用性及覆盖率的问题,是属于高阶测试技术,一定要注意。详细的可看书中的观点。

第六点,高级测试技术,Testing Complex Output,我不认为这有多高阶,不过在开发OpenTaobao的Client代码时,确实遇到这个问题,并且我不知所措,最后情急之下,直接跑代码用肉眼来分析返回值,有点傻。:-(,看完这段内容后我终于知道问题出在哪里,以后我知道怎么作了。
在Testing Complex Output结尾的段落里有一小段高级测试技术的总结,都是精华。一定要关注。

第七点,Keeping Things Organized,管理测试代码,经验之谈,很好很实用。

That's All.

参考:
1. http://oreilly.com/catalog/9780596523015
2. http://blog.rubybestpractices.com/posts/gregory/015-rbp-ch1.html
3. http://www.martinfowler.com/articles/mocksArentStubs.html
4. http://www.slideshare.net/weijenlu/mock-arent-stub


--
tommy xiao
E-mail: xiaods(AT)gmail.com

2010年2月17日星期三

使用Python和AppEngine制作发送中文邮件DEMO应用

在twitter上看过livid年前就说过2010年Google AppEngine是一个方向。我开始没有什么感觉。不过今天的投入开发让我多少有些信心,最起码对于初创的应用来说,AppEgnine是一个合适的平台。所以我想到使用mail api接口来试一下。最后在http://mail4china1.appspot.com/上架起了AppMail的应用。支持中文。
附件是python代码,client端使用php+PHPUnit可以快速测试。



python tools :
1. appcfg.py
2. dev_appserver.py

1. helloworld练习,
包括: 工程目录名,同名py, app.ymal

*其中ymal格式参考:http://code.google.com/intl/en/appengine/docs/python/config/appconfig.html

2.App Engine的自有webapp框架
参考: http://code.google.com/intl/zh-CN/appengine/docs/python/tools/webapp/

3.app engine处理中文通用解法

4.Google App engine Slides , http://www.slideboom.com/people/cyrilwang



参考:
Install Python PIL module in Mac OS X
http://blog.bracewell.org/2009/08/11/install-python-pil-module-in-mac-os-x/

--
tommy xiao
E-mail: xiaods(AT)gmail.com

2010年2月15日星期一

免费的远程图片处理服务,仅使用Heroku和Imagery

先看例子:
http://lucidcode.co.nz/assets/4b70dca0dabe9d5d3700003e/harmony-app.png
可以远程转换:
http://images.lucidcode.co.nz/assets/4b70dca0dabe9d5d3700003e/harmony-app_medium.png

实现方法:
这里fork一份代码,注意这是一份Rack版本的应用。(什么是rack?
使用heroku直接创建一个目录,上传此代码就马上可以运行。

想在你的应用中使用这个缩略图处理服务需要一个小技巧:
你需要使用一个子域名绑定到heroku。免费,但需要你输入一次信用卡帐号信息。

为什么呢?因为核心代码是这个处理的:

run Imagery::Server.new

-------------挖掘深层代码分割线-----------------
[SvgGenerator, ImageVariantGenerator].each do |generator|
if image = generator.from_url(env['SERVER_NAME'].split('.')[1..-1].join('.'), env['PATH_INFO'] + (env['QUERY_STRING'].empty? ? '' : "?#{env['QUERY_STRING']}"))
return send_file(image)
end
end
标红的代码的作用就是把
'images.lucidcode.co.nz'换成'lucidcode.co.nz'
-------------挖掘深层代码分割线-----------------
def self.variant_parser
@variant_parser ||= /(.*)\_(#{Transformations.list.join('|')})(#{SupportedImageTypes.join('|')})/i
end

def self.from_url(server, path)
return nil unless path =~ variant_parser

remote_path = "#{$1}#{$3}"

file = Image.new(server, remote_path)
if file.found?
transform_content(file, $2)
file
else
nil
end
end
标红的代码就是拿到regex中的第一处匹配和第三处匹配。再看例子你就能明白:
irb(main):020:0* path = 'http://images.lucidcode.co.nz/assets/4b70dca0dabe9d5d3700003e/harmony-app_medium.png'
=> "http://images.lucidcode.co.nz/assets/4b70dca0dabe9d5d3700003e/harmony-app_medium.png"
irb(main):022:0* path =~ /(.*)_(medium|large|)(.png|.gif)/
=> 0
irb(main):023:0> $1
=> "http://images.lucidcode.co.nz/assets/4b70dca0dabe9d5d3700003e/harmony-app"
irb(main):024:0> $2
=> "medium"
irb(main):025:0> $3
=> ".png"
标红的地方就是精华,实际上就是拼字符串。把中间的_medium这个变量给去掉。得到实际的图片地址。

这个好东西有什么用处呢?
有,可以帮你节约一些图片存储空间。heroku一个应用可以有20M的免费空间。对于小图片来说,就能存储不少了。
好好利用,给你的免费用户使用这样的空间,应该可以帮你节约流量。

所有技术全部归于老外,我就是转转。

参考:
http://lucidcode.co.nz/blog/archives/2010/02/09/remote-thumbnails-with-heroku-and-imagery/
--
tommy xiao
E-mail: xiaods(AT)gmail.com

2010年2月5日星期五

LinkedLn的新贡献->LinkedIn Search: A Look Beneath the Hood

今天有幸看了LinkedIn Search: A Look Beneath the Hood中的ppt,LinkedLn的工程师又给我们带来的完全
开源的搜索框架解决方案,基于Aapche Lucene的Zoie搜索框架。

这是这项搜索技术的领域:
Faceted search
, also called faceted navigation or faceted browsing, is a technique for accessing a collection of information represented using a faceted classification, allowing users to explore by filtering available information. A faceted classification system allows the assignment of multiple classifications to an object, enabling the classifications to be ordered in multiple ways, rather than in a single, pre-determined, taxonomic order. Each facet typically corresponds to the possible values of a property common to a set of digital objects.

另,Rails 3 Beta已经出来,相信今年早些时间,我们就可以用上新的Rails3。期待。


--
tommy xiao
E-mail: xiaods(AT)gmail.com

2010年1月27日星期三

wget工具学习心得--Linux guru必会

 今天看到有分享railscasts下载script,太棒了。但再细看,他使用的是bash script,可我还是对一些参数理解的不透彻,所以很郁闷。细细分析,读man,读别人的分享。把一些思绪记下来,方便大家鞭策!

代码如下:
wget -q -O - http://feeds.feedburner.com/railscasts | awk -F \” ‘/media:content/ {print $4}’ | head -n 2 | wget -i - -c

其中q是沉默模式,实际就是不让wget输出自已的提示格式。在输出到屏幕时,可以只显示目标文件的内容,但wget的统计及分析输出就没有了。

-O是输出到文件,后面要跟参数,但这里后面只跟着一个"-",对,百思不得其解,man中也没有说,幸好有别人的提示,这里"-"表示standard input. 就是输出到屏幕。

-q -O -,这里完全可以重写成-qO-,其中大O跟着的"-",合法。如果你这样写,一定会让你显的更牛!

话说转到awk

-F是表示分断行标识,后面的\"就是,加\是为了不让转义。
'/media:content/ {print $4}' 正则内容。这里很简单,就是直接的字符match,

再转一行==================>到这中间使用|管道可以顺序处理指令,Linux上的,不知道windows下有没有这种特性?

wget -i - -c,-c代表继续执行匹配的,

-i -表示从标准输出端读取链接,实际就是下载喽。

OK.我都感觉太牛了,你认为呢?Linux Guru从你开始!


参考:
http://www.editcorp.com/Personal/Lars_Appel/wget/wget_7.html
man wget
man awk
--
tommy xiao
E-mail: xiaods(AT)gmail.com

剩菜剩饭精彩总结--转的,不得不转!


原文是繁体,仅供翻墙来看的朋友分享! :-)


做饭的人都知道,若是做的刚好,准备有人事事儿的说没吃饱;倘若稍微多做一点点,哪怕是多放三粒米,多切一根葱,这顿饭注定是要
被剩下来──而且就剩一口,倒掉可惜,不倒可气。所以在节俭的厨师那里,剩饭成了脑筋急转弯。通过长年累月和剩饭的交流,我慢慢总结出了战斗经验,和大家share吧:
剩的菜汤汁多?那就用来下面条好了,宽汤窄面是祖训,最后再打个蛋花当礼花,高潮就在干净的盘子和没有浪费的愉悦中到来。剩的米饭不多不少?加一个蛋,做蛋炒饭。可是一人嫌多两人不够的量怎么办?熬成粥,放点青菜肉丝,不多不少,两人正好──如果有剩菜,此刻一并打发了也是快事。剩的稀饭有一小碗?加点牛奶麦片就是早点,有咸菜吗?那就是一天最完美的开端了。煮不完的面条可以包好冻起来,不影响下次食用;没人爱吃的烧鸡胸脯可以切成粒做炒饭,也可以手撕成丝来做汤;干的馒头可以搓错了放在肉馅里炸丸子;常见的剩菜剩饭可以一锅烩了,是一个人最好的晚餐。有时候,洗菜多了,比如芹菜多出一两根,洋葱还剩半个,土豆还有一快,干脆再买点西红柿做成义大利菜汤。否则就是当成配菜,放到别的菜里去炒也是能带来不一样的味道──搭配的窍门,我总怀疑是打发剩菜的托词。剩饭不怕,动动脑子,总会被吃下去──浪费粮食,会让一顿饭以不安做结尾的败笔。
剩的肉馅儿
2、3个人吃用三两就差不多了。提前拿出来化着。晚上回来肉馅放大碗里,放一个鸡蛋、淀粉、胡椒粉、姜粉、鸡精,向一个方向搅,一直找到上劲为止。锅里放水,愿意喝汤就多放,拿个勺把肉馅弄成小丸子下到锅里,好像正宗的动作是用手挤,我不喜欢手油腻腻的感觉,就改用勺了。丸子做好,锅里下切好的白菜丝,鸡精粉或清汤块(我做汤一般都是放鸡精不放盐),胡椒粉,白菜煮熟就可以关火了,吃之前倒点香油。这个菜又是汤又是菜,丸子不腻,白菜和汤吸收了肉味,很鲜。就着米饭吃,热热乎乎的方便又解馋。
剩的肥牛
做水煮不错。锅里放油烧热,放郫县辣酱、葱姜爆香,放一点酱油,加水,盐、鸡精,汤烧开后可以放电冰箱里剩下的绿叶菜,菠菜、油菜都成,实在没有切几个白菜叶放进去也不错。菜烫好后捞出来放碗里,把肥牛用少量嫩肉粉抓一下放汤里烫熟,最好是一片片放,不过我没这耐心,然后连汤带肉一股脑倒在先前盛菜的碗里,表面洒辣椒面花椒粉,把锅刷干净,倒油烧热,乘热浇在碗中。也是个下饭的菜,稍微麻烦一点。

2010年1月25日星期一

一个例外引发的解决方法-Gem View Goo的源码分析及解决,特例

       受朋友之托,非要从网上抓取信息。想来不是很难,就帮帮吧。使用mechanize,nokogiri就能搞定。
因为有一段时间没用了,想起原来使用过的gem views--Goo,开源的,@RobinLu出品。下载0.4版后
在macos上跑了一下,出来的gem list竟然是Library/Ruby/Gems下的。我晕。原来这和我的环境有关系
我把ruby环境全部使用Darwin Ports来安装的。幸好Goo开源的,去github上clone一份,打开xcode分析。

       我对Cocoa/object C不熟悉,当然我只关心它是如何拿到gem list的。没用多久,找到它:gem_helper.rb
关键代码就是:
  def self.specs
    spec_dir = File.join Gem.dir, 'specifications'
    source_index = Gem::SourceIndex.from_gems_in spec_dir
    template = ERB.new TEMPLATE
    puts template.result(binding)
  end
可是我的bash profile已经配置path了,怎么又变成系统原生的路径了呢???
代码没有错,就只能是这个rb第一行的解释不对。是的。ruby是script language,所以第一行解释环境还是很重要的。ok.
改一下,
from #!/usr/bin/env ruby to #!/opt/local/bin/ruby

Done.Goo就跑起来了。这里注意,为了满足个人的喜好,并不需要重新编译,直接去Goo查看内容包,在包里直接改代码即可。

--
tommy xiao
E-mail: xiaods(AT)gmail.com

2010年1月24日星期日

保持简单即最优-Mysql的部署原则

建议在考虑此方案时一定要三思。为什么?参考这里 Kiss KISS KISS. 其实Schema-Less没有错,但不能什么场景都上此方案,要
分析利弊,减少不必要的应用层复杂度。
文中提到的Serialized objects的保存技术,就是(entity-attribute-value) EAV, 说一下总结的缺点:
1.它对搜索不友好(都压缩存在一字段里,肯定不能搜索),这确实是一个问题。FriendFeed使用变相index,解决了它需要解决的问题。但只能是规避。
2.Select精确选择字段是不成了,每次都是SELECT * FROM xx,当然使用Memcache可以很少的解决此问题。
3.不能加约束(constraints),应用层需要作校验,其实就是增加了数据层的复杂库。
4.如果使用Json,不能使用Number和IP的原始形式存储,必须转换成String。这点好像不是那么重要,因为我们可以使用的文本协议有很多。比如Google的
protobuf

其实最重要的原则在Kiss KISS KISS中已经说的很清楚。对于刚开始的应用,使用Master-slaver足以。不要使用什么"优化",那些
其实就是"扯淡"。对于Scaling out方案更是应该简单有效为主,说白了,对于Mysql而言,一台Master及一台或几台slaver就是"最佳方案"。

--
tommy xiao
E-mail: xiaods(AT)gmail.com

2010年1月9日星期六

想找一份Ruby on rails的工作,我应该知道哪些知识?

     新年刚开始,已经有一些生猛的朋友要开始新的职场生涯了,不知道会不会遇到这样的问题: 想找一份Ruby on rails的工作,我应该知道哪些知识?
     还好,我并不是想指点你什么,只是想按我的思维方式展开,让你能"闻"到点东西即成.
古云:知己知彼,百战不殆;不知彼而知己,一胜一负;不知彼,不知己,每战必殆。一句话,想知道自已能不能找到rails的工作,就应该知道别人要什么样的人.对方公司的情况是没法知道的,因为咱们不是"FBI".只有一条路,招聘启事中的Requirements.所谓专家看门道,外行看热闹就是在这些需求上出的.
    正巧看到博文<7 Top Ruby and Rails Jobs for January 2010>有专业ruby on rails公司的招聘启事.那咱们就边走边看.相信会有收获.
1.Billmonitor,英国的手机公司,不错,也就是说在手机应用都需要与web进行交互,所以使用ruby on rails是比较理想的.咱们看看它的Requirements:
  • 3-5 years experience in web development(3-5年是什么概念?也就是说ruby onrails并不是一个web开发新手(Newbie)的最佳进入职场的着陆点,一句话,没做过网站,想来趟这混水很难.)
  • Demonstrable experience developing & deploying Ruby on Rails web sites in the real world(这条很简单,实践经验,你可以通过虚拟机加上server之后,自已动手作作automate deploy试试.)
  • Practical experience in debugging and tuning web sites(这是最核心的技能了,除了动手多写代码之外,可能看书学习可以帮助你.)
  • Understands web security issues(这是基本常识,不会?不知道哪里有?去guides.rubyonrails.com的security知识点看看.)
  • You're smart, gets things done, and agile(人品问题,不展开)
  • We're a team (rogue pirates and ninjas need not apply)(人品问题,不展开)
2.NewRelic,如果在ruby on rails社区玩过一阵,都会知道它.一家作性能监控应用的公司,看它的Requirements:
• Built and deployed commercial RoR applications (please provide your urls) (这家直接要看你之前作的东西,够狠,没有?从现在走就多去看看开源项目,fork下来自已看能不能看懂,跑跑,然后看issue解决它,并提交patch,这些就够证明你的实力了.)
• Strength in all the Rails fundamentals (routing, active record, migrations, ...) (基本功,一本DDH的Agile Web Development with Rails就够了.感觉不踏实的家伙就只能去看rails的源码了,如果还有不踏实的家伙,只能去看ruby源代码了,还不踏实?重写ruby或者rails,自立门户吧)
• A demonstrable knowledge of Javascript and CSS (again, urls) (这个要求太基本了,会作web开发的都会,但其人弱的地方咱们应该强啊,同一起跑线上,勇者胜)
• Experience with user-centered interaction design (这种能力需要常时间泡在应用上才能有所顿悟,和学历无关.)

3.groupon.INC Chicago的一家公司.不了解,直接看需求:
-Thorough knowledge of Ruby on Rails (3yr+) (三年,呵呵,我觉的只要你的web开发经验在3年以上就可以,不强求ruby on rails.)
-Proven track record with high-traffic sites (这条是经验要求,一般人可能不具备,如果你遇到这个,多看看scailing方面的文章就可以了解.)
-Familiarity with agile software methodologies - able to thrive in a fast-paced, highly-collaborative environment(这个需要时间锻炼)
-Strong commitment to quality(提交的代码质量还有要求,说白了就是要求你是老手,如果练手老手?去开源社区去看看别人的代码啊.)
-Thorough understanding of software testing (RSpec, Cucumber, Testing)(这条技能要实践,要多练,核心思路不难,关键是你要去实践.assert大法有好多种样多,不练就是不会.)


4.snapizzi inc ,圣巴巴拉市(美国加利福尼亚州西南海岸城市),软件公司,不了解,咱就直接看需求:
• Proficiency in Ruby on Rails framework(精通?最怕Proficiency,是吧.没关系,认真读完DHH的书Agile Web Development with Rails就应该算精通了.更何况国人的年青人一读就读好多本呢.)
• Proficiency with MySQL or similar database technologies (要求数据库知道,Mysql是指名要的,去看书学吧)
• Ability to produce standards-compliant XHTML, CSS and JavaScript code(网页会做吗?不会,练吧)
• Minimum of Bachelors in Computer Science or Engineering(要求学历了,最好与计算机相关,一个"本"还是很重要的)

5.AlphaSights ,伦敦的公司,英国人看的吧,我估计。不费话直接看需求吧:
  • Demonstrable track record developing with Ruby and/or Rails(之前有作品,需要是ruby on rails的。多写开源代码应该能保证)
  • Understand the key factors in making your code secure(对安全还是不放心啊,这条要求很严格)
  • Unit testing. Preferably with experience of RSpec(test喜欢使用rspec,也算是一种趋势吧,注意,不要被误导,初学test时,用最简单的开始)
  • Experience in Git, SQL, HAML, JQuery/PrototypeJS(这些其实是最基本的,一周后学会。几年就能磨成老手。)
  • Working knowledge of unix-like environments such as Mac OS X and Linux(要是Linux用户,是的,想使用ruby on rails,你必须是linux使用者,让windows去死吧)
That's All.Done!

--
tommy xiao
E-mail: xiaods(AT)gmail.com

2010年1月8日星期五

rails中实现Schemaless 数据的plugin,基于mysql

说话,如果你读到dbanotes关于FriendFeed使用Mysql的博文<FriendFeed 使用 MySQL 的经验>,肯定会知道
FriendFeed巧妙的使用原生Mysql的特性来实现"Schema-less",说白点就是使用一个字段来存一个实体属性集合。
它使用binary格式存储。
上面说了这些,你如果想使用rails来实现,现推荐此rails plugin Dynamic Attributes
就是按上面的思路实现的,挺好,实用,去下一个吧。

另外,对于windows上的一键ruby环境安装,我用virtualBox安装上windows测试了一款日本货,不错,开源的。
rumix,在中文winXP下安装测试,没有问题。vista,win7就不要上了,听其它网友安装上,有点小问题。点击下载吧
Rumix 1.00(通常版)
--
tommy xiao
E-mail: xiaods(AT)gmail.com

2010年1月7日星期四

拯救怡帆:请帮助这位漂亮、坚强的女孩



他的女儿潘怡帆今年5岁。出生第二天就进了急救病房。后诊断为肺动脉高压,一直靠氧气机呼吸。目前她的肺部已经转纤维化,不能提供自己所需的氧气,生命垂 危。她的父母为了挽救女儿的生命,已经倾其所有,卖掉了房子。国内专家已经无能为力,需要转美国治疗此病经验丰富的德州儿童医院进行心肺移植手术。所需资 金约50万美元。

请大家一起帮助她,程序员的下一代。因为病魔的折磨,她还没有学会走路,她的记忆里更多的只是针头和面罩,她更多的是从电视里知道了世界,她还保存着给四川灾区捐款一万元而收到的感谢信。

【捐款方式】

请访问怡帆基金网站捐赠页面 http://www.yifanfund.com/cn/

更多详情请访问 http://www.help-yifan.org

--
tommy xiao
E-mail: xiaods(AT)gmail.com

2010年1月3日星期日

新年第一推,快速创建rails3应用

今天有空读了一篇Yehada Katz的博文, Spinning up a new Rails app。正好合适新年的第一推,所以上来发一下。
目的很明确,就是快速创建rails3项目,按如下操作即可:

Step 1: Check out Rails
$ git clone git://github.com/rails/rails.git

Step 2: Generate a new app

$ ruby rails/railties/bin/rails new_app
$ cd new_app

Step 3: Edit the app's Gemfile

# Add to the top directory "/path/to/rails", :glob => "{*/,}*.gemspec" git "git://github.com/rails/arel.git" git "git://github.com/rails/rack.git"

Step 4: Bundle

$ gem bundle

注意,这里需要先安装gem install bundler,才可以。

最后

Everything should now work: script/server, script/console, etc.如果实在想搞自动化的,需要脚本的朋友,可以看看这里



收工。祝新年好运!

--
tommy xiao
E-mail: xiaods(AT)gmail.com