by agate - Published: 2008-07-22 [6:22 下午] - Category: 程序编码
在 win 下的试验... 似乎 rails 不是使用 utf8 的编码方式才导致了乱码. 解决方案十分简单. 当然, 请保证 mysql 的字符集使用 utf8 并且建立库/表也是 utf8 的编码.
最重要的是在 rails 工程中的 application.rb 中加入如下代码:
# application.rb
before_filter :set_charset
before_filter :configure_charsets
def set_charset
@headers["Content-Type"] = "text/html; charset=utf-8"
end
def configure_charsets
@response.headers["Content-Type"] = "text/html; charset=utf-8"
suppress(ActiveRecord::StatementInvalid) do
ActiveRecord::Base.connection.execute 'SET NAMES UTF8'
end
end
看看~是不是搞定了!
by agate - Published: 2008-07-17 [8:45 下午] - Category: 软件使用
最近忙于 linux(主要是Debian) 下面的工作, 发觉安装软件时不论是使用自带的 apt-get 或者是下载源下来自己编译总是不知所云... 换句话说就是安装好了, 可以用了, 就是不知道他做了些什么, 放了些什么在哪里...
觉得能不能有一个类似 win 下面那样的 installer 工具啊? 这样自定义安装地址就好多了! 而且还可以卸载. 基于这个想法就在 google code 上面建立了一个工程托管:
link: http://code.google.com/p/green-softs-for-linux/
svn: svn checkout http://green-softs-for-linux.googlecode.com/svn/trunk/ green-softs-for-linux-read-only
并且把 mysql 和 tomcat 都做了绿化定制. mysql 绿化精简过后解压处在只有 15M 不到. tomcat 呢只做了安装和卸载部分(呵呵, 其实就是在 /usr/bin 下加了软链接罢了), 放入down下来的tomcat目录即可使用.
具体请见 google code svn 中或 google code download 中 README 文件部分.
by agate - Published: 2008-07-12 [10:36 下午] - Category: 程序编码
从实用角度看,在一些场景下Symbol好过String只有两点:节省内存,表达简洁。
而把两者强制拆开,既有额外好处也带来不便。
好处是充分利用两者的不同进行差异处理,如上面举的异常处理/when的用法。
但不便之处也不少,因为很多情况下需要无区别化对待两者,rails中就大量采用了这种风格,使用者无须担心
attr_accessor :abc 和 attr_accessor 'abc'有什么区别,layout 'main'和layout :main有什么区别(当然,跟layout nil和layout false还是有区别的,一点机智和诡异)。
当用户传过的东东作为Hash的key时,两者的不同让人烦死。
比如,我在每个model里声明一些字段的默认值:
class Person < ActiveRecord::Base
DEFAULTS = {
:age => 30
}
end
在controller里
class PersonController < ActiveController::Base
def create
person = Person.new(Person::DEFAULTS.merge(params[:person]))
person.save!
end
end
请注意controller里的merge,假定页面没有传入params[:person][:age],则新建的person的age取默认值30.
那么,当页面传了age参数为40呢?按理merge后age应该为40,事实却不总正确。因为params里的key都是以String存储的,而我的DEFAULTS的key是Symbol,则merge后的结果是
{
:age => 30,
"age" => 40
}
最终save!以哪个为准,天知道~
rails实现了名为HashWithIndifferentAccess的类(继承自Hash),就是为了解决这一问题。无论开发者传过来的是 String还是Symbol(作为key),它都会把预先统一转化成String进行存取,以实现无差别化对待。细心的人可能已察觉,既然params 里的内容都是以String作为Key,为啥还可以params[:person]这样访问,奥秘就是用了这个类。它的源码在 gems/activesupport-x.x.x/lib/active_support/core_ext/hash/indifferent_access.rb
所以,我上面的model要改成:
class Person < ActiveRecord::Base
DEFAULTS = HashWithIndifferentAccess.new({
:age => 30
})
end
即使有这个类,也让人呕吐不止。曾想对它简单封装,提供Hash#to_indiff,仍不满意,不过,注意这个差别并有意避免仍是当前能做到的。
ruby1.9已经把Symbol作为String的子类实现了,并去除了Symbol#to_int,虽然没有百分之百确定出现在 ruby2.0里,还好离解放不远,这样从语言角度两者的边界就更清晰了,"Goodbye, HashWithIndifferentAccess."
:symbol.is_a? String
http://redhanded.hobix.com/inspect/SymbolIs_aString.html
让人绝倒的理由之一:
Smalltalk’s symbols are a subclass of string. (He adds that this is his most motivating reason to do it.)
said by liusong1111 from javaeye!
by agate - Published: 2008-07-12 [10:29 下午] - Category: 未分类, 程序编码
在Ruby中symbol是Symbol类的实例。symbol的语法为一个冒号后面接一个标识符。
symbol就像一个字符串,它表示了一个字符序列。它不像字符串,每个symbol只有一个实例(和Fixnum一样)。因此,有一个内存或
性能问题需要弄清楚。例如,在下面的代码中,"foo"字符串以三个单独的对象存储在内存中,但是symbol :foo作为一个单独的对
象存储(被引用了多次):
array = ["foo", "foo", "foo", :foo, :foo, :foo]
有些人被symbol前面的冒号弄糊涂了。其实没有必要糊涂;这只是一个简单的语法形式。字符串,数组和哈希都有开始和结束界定
符;而symbol只有一个开始界定符。把它当成一个单界定符而不是二元界定符即可。开始时你可能认为这个语法很奇怪,但事实上
没有什么神秘的。
Read more...
by agate - Published: 2008-07-12 [12:44 下午] - Category: 程序编码
起因
最近在学习ruby on rails,的确是一个优秀的数据库开发框架。但在过程中,发现在视图文件夹中的rhtml文件里有大量的类似于以下的语句:
<%= link_to recipe.title, :action => "show", :id => 1 %> |
这是一个指向链接,如果没有冒号这句话的意思很好理解:这是一个指向http://127.0.0.1:3000/recipe/show/1的连接,也就是“显示”数据库表recipe中“id”为1的条目的信息,但让人不解的是action和id前面的冒号,它们是干甚么用的?
ruby面向对象特性的一个缺点
ruby中,一切皆是对象。就一个简单的字符串举例:
ruby -e 'puts "hello world".class'
String
这里打印了"hello world"的字符串所属的类,结果显示它是一个String对象的实例。我们还可以显示它的对象号。
ruby -e 'puts "hello world".object_id'
41436168
ruby一向标榜自己是完全的面向对象的原因就在于此,它的确做的很彻底。但是凡事有好就有坏,一个对象占用的内存空间显然会比纯粹的变量大得多,当程序中涉及到大量的字符串时,一个ruby程序会占用过多的内存。举个例子说:
我们用hash列表来存储歌曲的信息
song1 = { 'title' => 'used to love you', 'artist' => 'john legend'}
song2 = { 'title' => 'i still', 'artist' => 'backstreet boys'}
#......
#很多歌,这里只用两首
for i in 1..2
thesong="song"+i.to_s
eval <<-PROC
#{thesong}.each_key { |key| puts key.object_id.to_s }
PROC
end
结果:
41436144
41436408
41435904
41436000
因为object_id各不相同,在hash表中的各个key都是独立的String对象,即使内容相同(如'title'),ruby还是将其视为不同的对象,这样就无端地占用了不少内存。但事实上,大多数情况下,我们仅将hash中的key视为字段而已,不会涉及到String类的方法,ruby自动将其设置为对象有杀鸡用牛刀之嫌。
symbol是什么
直译来说就是“符号”,在ruby就是形如:action这样的,一个冒号后跟一段字符串。显然,根据“一切都是对象”定律,它也是一个对象。
ruby -e ' puts :action.class '
Symbol
这个对象存在的意义在于,它解决了“同内容字符串,不同对象”带来的过多占用内存的问题。简单的说:action代表了'action'字符串,这里说的是字符串,不是字符串对象。
ruby -e ' puts :action '
action
更确切的讲就是一个symbol对象代表该对象的冒号后的字符串。
ruby -e ' puts :action '
action
ruby -e ' puts :"hello world" '
hello world
所有同内容的字符串只需要一个标记对象就可以代替,这样减少了不必要的对象建立和内存占用。但是,正如我强调的“symbol代表的是字符串,不是对象”,因此不要希望标记可以使用String类的诸如capitalize,center等方法,如果使用的话只会得到提示方法未定义的错误报告:
ruby -e ' puts :action.capitalize '
-e:1: undefined method 'capitalize' for :action:Symbol' (NoMethodError)
幸运的是,symbol提供了转换函数to_s用来生成一个字符串对象,它会提取字符串内容并将其升级为对象。
ruby -e ' puts :action.to_s.capitalize '
Action
另外,很重要的一点是,symbol没有赋值方法,换句话说symbol一旦定义,将不能改变。
ruby -e ' :action="hello" '
syntax error
很遗憾,即使使用了to_s,赋值依然无法顺利进行,因为ruby会认为“to_s=”是一个未定义函数。除非明确地为被转换生成的字符串对象指定一个引用(但事实上在复制之后该连接的指向又发生了变化):
:action
myaction=:action.to_s
myaction="lala"
puts myaction
结果:
lala
怎么使用symbol
任何可以使用symbol的地方都可以使用与之向对应的字符串对象。在rails中有建立类似javabean的方法:
attr_reader :action
它建立了一个读取实例变量@action的方法,也可以写成这样:
attr_reader "action"
反之,只要
字符串在程序运行过程中不用改变
字符串不必使用String类方法
那么我们可以放心用symbol来代替字符串对象,从而大大减少内存的占用,在rails中尤为明显。因为需要频繁地在各个控制方法和页面之间跳转和传出数据,大量的方法名由symbol来代替,及节约了内存也提高了运行速度。
by agate - Published: 2008-07-11 [11:11 上午] - Category: 程序编码
在 rails 升级到2.0+之后, 我们熟悉的 scaffold 似乎用法不大一样了~ 这里包括所谓的动态和静态 scaffold. 可以说动态的 scaffold 基本上是用来快速实现功能的, 很多情况下我们用不到他. 一般来说大多数开发这会习惯于使用 generate 方式的scaffold 来生成基础代码框架.
rails2.0+ 版本中, 静态的scaffold使用方法从原来的:
$./script/generate scaffold ModelName [ControllerName] [action, ...]
变成了:
$./script/generate scaffold ModelName [field:type, field:type]
还句话说原本的自定义Controller名字就不好实现了~ 呵呵, 但是有利有弊拉~ 可以像 hibernate 这类 orm 工具那样生成数据库表结构拉!
当然在 rails2.0+ 下如果需要动态的 scaffold 还可以通过加载 scaffold plugin 来实现(因为在 rails2.0+ 版本中, 动态的 scaffold 被作为插件来实现了! ). 具体操作步骤如下:
$./script/plugin install scaffolding
当然, 不仅仅是 scaffold 很多类似功能都在 rails2.0+ 中转化成 plugin 了. 具体需要什么插件可以使用如下命令来查看需要的插件:
$./script/plugin list
这样当然不是很方便(特别是对于我们这种拿这 agile web development with rails 这本书学习的小朋友来说). 看了网上这么多建议之后, 我还是采纳了"使用 rails1.2.6 来学习, 之后过渡到 rails2.0+ 这种方式". 但是我们平时使用的 gem install 方式, 默认会安装 rails2.0+ (即最新版本). 使用如下命令可以实现指定版本的目的:
$sudo gem install rails --version 1.2.6
这样就可以使用到我们最熟悉的旧版本的命令了. 但是你会说这两个 rails 共存有问题吗? 我不是很清楚, 当然你可以删除一个 rails 的 gem 包来保证其版本的唯一性:
$sudo gem uninstall rails
他会列出你所有的 rails 版本, 并且询问你是否卸载.
这里我说一个我使用的方式, 保证了两个 rails 同时存在, 同时可用:
$rails _x.x.x_ {app_name}
这样就可以建立对应 rails 版本的应用目录了, 当然里头的 script 们也是对应版本的用法!
注: 默认情况下直接输入 rails {app_name} 是建立最新版本 rails 的应用目录.
by agate - Published: 2008-07-09 [11:02 下午] - Category: 未分类
a google online game... maybe it's a game...
by agate - Published: 2008-07-09 [5:17 下午] - Category: 软件工程
Scrum管理者 - Scrum Master,相当于橄榄球队长。
商业分析者:业务分析师,Business Analyst
疾跑:Sprint,Scrum 中的迭代
产品拥有者:Product Owner
结构主体:大概是架构,Architecture
产品订单:Product Backlog
风险的所有承担者:Stakeholders,干系者
“疾跑”订单:Sprint Backlog
就目前而言,虽然没有官方的译法,但是这样已经足够了!
by agate - Published: 2008-07-08 [11:20 下午] - Category: 软件使用
if you are using linux(ubuntu is a good choice). you must use gedit.
if you are using gedit. you must use 'todo' plugin.
but if you are ready for using this plugin maybe it doesn't work.
you must install ruby1.8+ and the python gtk lib.
$sudo apt-get install ruby
$sudo apt-get install python-gnome2-extras
link to the todo plugin: sourceforge.net/projects/gedit-todo
by agate - Published: 2008-07-01 [8:33 上午] - Category: 历程
这是我在上海大学生涯里的最后一份blog,是在网吧里的最后一份blog,是我感受最深的一份blog……千言万语已经是这个“不舍”不能概括的了!
我敬爱的各位老师,我可爱的那些同学、朋友!我要走了~四年啊!人生有多少个相处的四年……我希望我的那些照片中有你!我希望那些带回去的书里有你的名字!我希望你记得我qq的名字,记得我的email,记得……
再过30分钟我就要离开南汇了……一直好多抱怨,但是现在我突然觉得这里很好!好安静!好干净!好空旷!好……就要走了……走了……