分类目录归档:Ruby on Rails

太恶心了– rubygems安装gem需要使用代理服务器了

换了一台电脑,想用rubygems重新安装rails,但一直遇到各种如问题:

sudo gem install -v=2.3.9 rails
Password:
ERROR:  Could not find a valid gem 'rails' (= 2.3.9) in any repository
ERROR:  While executing gem ... (Gem::RemoteFetcher::FetchError)
    too many connection resets (http://production.s3.rubygems.org/latest_specs.4.8.gz)

ERROR: While executing gem ... (Gem::DependencyError)
  Unable to resolve dependencies: rails requires activesupport (= 3.0.5), actionpack (= 3.0.5), activerecord (= 3.0.5), activeresource (= 3.0.5), actionmailer (= 3.0.5), railties (= 3.0.5), bundler (~> 1.0)

google了半天(期间google中短NNN次),才明天了现在使用rubygems 安装gem也得开代理了。。。

要使用加了代理的命令:

sudo gem install rails -p http://127.0.0.1:8118

现在rubygems好像只支持http代理。 如果你使用的是socks代理,可以通过Privoxy(支持linux和mac)这个软件来搞一个http代理 通道, 详细参看这个教程

发表在 Ruby on Rails | 标签为 , , , | 一条评论

使用Unicorn替代Mongrel作为Ruby on Rails的服务器

先前的开发的Ruby on Rails网站使用的服务程序是Mongrel + Nginx, 现在用了Rails 3, 发现Mongrel对它有兼容问题, 所以要换一个。 虽然现在Phusion Passenger大行其道, 但使用前要重新编译Nginx。 为了避免重新安装nginx,我找到mongrel的替代品Unicorn。 没想到unicorn的设置非常方便。 我记录在这里供大家参考:

安装unicorn:

sudo gem install unicorn

创建网站配置文件(myproject是项目名称):
继续阅读

发表在 Ruby on Rails, 站长文档 | 标签为 , , , , | 一条评论

[BUG] cross-thread violation on rb_gc()

今天在mac os x leopard上安装typo时遇到
[BUG] cross-thread violation on rb_gc()
错误.
google了一下, 发下有可能是因为系统上安装了多个版本的ruby 引起的. 我的mac上的确有多个ruby: 一个是leopard原带的, 另一个是自己用macport安装的. 但是系统原带的ruby1.8.6已经在清理硬盘空间时给删除了, 文件快捷链接也都换了, 使用ruby -v也显示是1.8.7版的信息.
全系统搜索了一下, 竟然发现系统上还有个
/System/Library/Frameworks/Ruby.framework/Versions/Current/usr
里面带有ruby文件.
将它去除, 改成一个文件快捷链接到自己安装的那个ruby文件那里, 问题解决了.

发表在 Ruby on Rails | 标签为 , | 一条评论

怎样看本地ruby gem的rDoc文档

在本地查看rDoc文档其实很简单, 只要运行:
gem server
你就可以用浏览器通过 http://localhost:8808/ 网址查看所有已经安装的ruby gem的rDoc文档了.

发表在 Ruby on Rails | 标签为 , | 留下评论

ruby中10进制和16进制的转换

16进制到10进制:
>> "B0A0".hex
=> 45216

>> "B0A0".to_i(16)
=> 45216
10进制到16进制:
>> 45216.to_s(16)
=> "b0a0"

发表在 Ruby on Rails | 留下评论

Ruby中如何复制对象 (deep clone)

用Ruby复制一个对象(object)也许没有你想像的那么容易. 今天我google了半天, 做个总结吧.
先从最简单的开始, b = a 是复制吗? 看代码说话:
>> a= [0,[1,2]]
>> b=a
>> b[0]=88
>> b[1][0]=99
>> b 
=> [88, [99, 2]]
>> a 
=> [88, [99, 2]]
从上面代码发现, 一但修改b, 原来的a也同时被改变了. 甚至:

>> b.equal?(a)
=> true
原来b跟a根本就是同一个object, 只是马甲不一样罢了. 所以b = a不是复制.
那 b = a.dup呢?? 还是看代码:
>> a= [0,[1,2]]
>> b=a.dup
>> b[0]=88
>> b[1][0]=99
>> b
=> [88, [99, 2]]
>> a
=> [0, [99, 2]]
情况似乎有所好转, 在修改b后, a还是有一部分被修改了.(0没有变,但原来的1变成了99).
所以dup有时候是复制(如在Array只有一级时), 但有时不是复制哦.
再来一个, b = a.clone呢? 上代码:
>> a= [0,[1,2]]
>> b=a.clone
>> b[0]=88
>> b[1][0]=99
>> b
=> [88, [99, 2]]
>> a
=> [0, [99, 2]]
情况几乎跟dup一模一样. 所以clone也不一定可以相信哦!
原来ruby中的dup和clone都是shallow复制, 只针对object的第一级属性.
汗, 难道在Ruby中没有办法复制对像吗? 也不完全是, 看这个:
>> a= [0,[1,2]]
>> b=Marshal.load(Marshal.dump(a))
>> b[0]=88
>> b[1][0]=99
>> b
=> [88, [99, 2]]
>> a= [0,[1,2]]
=> [0, [1, 2]]
修改b后a没有被改变!!! 似乎终于成功找到复制的办法了!!!
为什么要加"似乎"呢? 因为有些object是不能被Marshal.dump的.如:
>> t=Object.new
>> def t.test; puts ‘test’ end
>> Marshal.dump(t)
TypeError: singleton can’t be dumped
    from (irb):59:in `dump’
    from (irb):59
更完善的复制方案可以考虑给ruby增加一个deep clone功能, 可以参考以下链接:
http://d.hatena.ne.jp/pegacorn/20070417/1176817721
http://www.artima.com/forums/flat.jsp?forum=123&thread=40913
好了, 复制这个小问题, 没想到也能引出这么长的文章来, 没想到吧?

发表在 Ruby on Rails | 留下评论

用Benchmark测试不同ruby代码的运行速度

如果比较功能相同的几组代码的运行速度, 可以使用ruby语言里的Benchmark模块.
(开始前 设置中文环境, $KCODE = ‘u’)
比如, 连接两个字串, 如:
str1 = "中国"
str2 = "一定强!!!"

可以使用+
?> str1 + str2
=> "中国一定强!!!"
也可使用
>> "#{str1}#{str2}"
=> "中国一定强!!!"
还可以使用<<
>> str1 << str2
=> "中国一定强!!!"
(注意这种方法会改变str1的值,
>> str1
=> "中国一定强!!!")

如果想要知道这三种方法哪一个速度更快, 就可以使用Benchmark比较.
先定义三个不同的方法:

def joined_by_plus(str_a, str_b)
    500000.times do; str_a.dup + str_b; end
end

def joined_by_uniting(str_a, str_b)
    500000.times do; "#{str_a.dup}#{str_b}"; end
end

def joined_by_adding(str_a, str_b)
    500000.times do; str_a.dup << str_b; end
end

因为这三种方法速度都很快, 比较一次的时间很难分出上下, 所以每种方法都做500000次.
因为<< 会改变变量, 所以在第三个方法中使用了str_a.dup, 备份出一个str_a来测试, 其它二个方法虽然从理论上不须要这个dup, 但为了时间上的公平, 也给它们加上了.

下面是测试代码:
require ‘benchmark’

Benchmark.bmbm(10) do |t|
  t.report(‘加号连接’) { joined_by_plus(str1, str2) }
  t.report(‘放进引号’) { joined_by_uniting(str1, str2)}
  t.report(‘使用<<’) { joined_by_adding(str1, str2)}
end

bmbm是Benchmark的测试方法, 这是双重测试, 用来提高精确度. 里面参数10用来调节标签在结果里的显示占位宽度, 不对结果产生影响.
report(‘加号连接’)里的参数是为相应测试的标签名, 用来区别测试结果.

下面就是结果:

Rehearsal ————————————————
加号连接   1.800000   0.580000   2.380000 (  2.435614)
放进引号   2.080000   0.590000   2.670000 (  2.706669)
使用<<       2.000000   0.580000   2.580000 (  2.635540)
————————————— total: 7.630000sec

                   user     system      total        real
加号连接   1.810000   0.600000   2.410000 (  2.476613)
放进引号   2.050000   0.600000   2.650000 (  2.656080)
使用<<       1.960000   0.600000   2.560000 (  2.567434)

因为使用了bmbm方式, 所以会有两个结果, 第一个是演习结果, 第二个是真实结果.  如果使用bm方法, 将只会有一组结果.
结果有user时间, 系统时间, 总时间和实际花费的时间. 单位为秒.

从结果可以看出, 使用+连接两个字串时速度最快, 而放进引号的方法最慢. 不过从结果也可以看出即使进行500000执行的结果也相差在0.3秒之内, 平时换用问题不大.

看来不是这一次, 希望下次你在自己的Benchmark试验中, 会发现给你的程序带来巨大速度提供的代码.

发表在 Ruby on Rails | 留下评论

用ruby语言以句子为单位拆分一个字串

目标, 用ruby语言以句子为单位拆分一个字串. 如:
给出字串:
s="这是一个句子,另一个句子.一个新句子!难道这不是另一个句子吗?"
将它分拆为:
 ["这是一个句子,"], ["另一个句子."], ["一个新句子!"], ["难道这不是另一个句子吗?"]
样式.
测试前将ruby的$KCODE环境变量设置为’u', 启动UTF8编码支持中文.
$KCODE=’u’
尝试1:
>> s.split(/\.|,|\?|\!/)
=> ["这是一个句子", "另一个句子", "一个新句子", "难道这不是另一个句子吗"]
等同于:
>> s.split(/[.,!?]/)
=> ["这是一个句子", "另一个句子", "一个新句子", "难道这不是另一个句子吗"]
虽然分开了句子, 但失去了标点.

>> s.split(/([.,!?])/)
=> ["这是一个句子", ",", "另一个句子", ".", "一个新句子", "!", "难道这不是另一个句子吗", "?"]
用括号将正则组成一组, 标点出来了, 但和句子是分开的.

改用scan
>> s.scan /.+?[.,?!]/
=> ["这是一个句子,"], ["另一个句子."], ["一个新句子!"], ["难道这不是另一个句子吗?"]
成功了!!

如果一定要这样:
>> s.scan(/(.+?(\.|\?|\!))/).collect{|p|p[0]}
=> ["这是一个句子,另一个句子.", "一个新句子!", "难道这不是另一个句子吗?"]
也是可行的.

发表在 Ruby on Rails | 留下评论

Rails string字符串相关转换

总结字串转变到其它与它相关的object的方法. 在这里整理分享一下, 希望能帮助到你.

变量相关
读取

instance_variable_get("@name")     #返回@name值

设置

instance_variable_set("@name", "三国演义") #@name =  "三国演义"

method相关
string到method名
send

book.send("name") #返回 book.name值

注意: book.send("name") = "三国演义" 会出错.
但可以:

book.send("name=", "三国演义") #book.name = "三国演义"

单复数转化
string复数化
pluralize
可用于生成table_name

"country".pluralize #=> "countries"

string单数化
singularize
和上面的相反

"posts".singularize #=> "post"

table和class相关

将表格名转成class名
classify

"blog_pictures".classify #=> "BlogPicture"

转成table_name(和上面的相反)
tableize

"BlogPicture".tableize #=> "blog_pictures"

将class名转成class
constantize

"Country".constantize #=> Country

可以将classify和constantize联用将string转成class model

"books".classify.constantize.find_by_name("三国演义")
#=> Book.find_by_name("三国演义")
发表在 Ruby on Rails | 留下评论

半semantic, 数据的价值和数据显示

让机器读懂之前先让人读懂!
出发点?
 数据的价值不一, 因此不应该用同样的方式显示这些数据.
 
价值?
价值针对不同个体应该是不一样的, 有条件最好做到面向不同个体(根据IP地址, 性别, 年龄, 历史记录), 如果做不到就尽量力求满足最大群体.

数据怎样的价值?
有用?/没有用?
重要?/不重要?
要紧?/不要紧?

不同的显示?
文字:字体, 字体大小, 颜色, 底色… 直接改用图标?
位置,:左上角?  扔到最下面?

方案
数据和显示的对接
数据输出时附带显示模式信息, 对准备好的view pattern直接对接
out => (data, view_options)
@title, @content, @sidebar, @item.name, @item.content 变量名直接附带意义

比rails更rails
使用统一的column名, 如name, content…
使用统一的变量名, 如@title, @item…
使用统一的view patterns, 如用来显示列表的index页面, 换到哪个model一样使用.
使用统一的view 局部pattern(最简单, google, wikipedia化, 实用, 可以指出数据的重要性, 美观不是第一的, 美观还费带宽和美工), 如可以重复使用的list显示pattern, comments显示pattern….

发表在 Ruby on Rails, 信息处理 | 留下评论