18 Apr 2015
最近通过两个非常好的视频学习了一些git的基本原理,其中包括了git的对象模型,对象的组织方式等。
在理解了这些基本的原理后,再使用git的命令,就会比较清楚什么是merge,什么是rebase等,以及在不同的场合下合理得使用git命令。
第一个视频是《Metaprogramming Ruby》 的作者Paolo Perrotta讲的Wrapping Your Head Around Git,我发现他总是非常擅长讲述一些原理性的知识,让你通过了解底层的原理,来更加扎实得掌握一门技术。
VIDEO
第二个视频是Introduction to Git with Scott Chacon of GitHub, Scott Chacon在github工作, 是git方面的大牛。虽然这个视频是2011年的,但是里面讲的原理和基本概念还是非常有用,绝对没有过时的。
VIDEO
19 Mar 2015
大部分的Ruby开发者都知道在case
表达式中的when
后面可以使用直接量,类,范围(Range)和正则表达式:
case something
when Array then ...
when 1 .. 100 then ...
when /some_regexp/ then ...
end
你可能也知道在case
中实际是使用===
方法来进行比较。Ruby会将上面的代码象下面一样执行:
case something
when Array === something then ...
when 1 .. 100 === something then ...
when /some_regexp/ === something then ...
end
当然你可能不知道Proc
类中也定义了===
方法,用于执行proc
或者lambda
。相当于把===
右边的参数作为参数传递给Proc#call
方法,例如:
is_even = -> ( n ) { n . even? }
is_even === 5 # => false
#same as
is_even . call ( 5 )
这样我们就可以在when
的后面使用proc
或lambda
,下面是一个非常简单的例子:
def even?
-> ( n ) { n . even? }
end
def odd?
-> ( n ) { n . odd? }
end
case x
when even? then puts 'even'
when odd? then puts 'odd'
else puts 'Impossible!'
end
也可以直接在when
的后面定义lambda
,例如:
case x
when -> ( n ) { n . even? } then puts 'even'
when -> ( n ) { n . odd? } then puts 'odd'
else puts 'Impossible!'
end
因为proc
或lambda
的闭包特性,所以可以给lambda
的定义方法传递参数,进行更强大的比较功能:
def response_code? ( code )
-> ( response ) { response . code == code }
end
case response
when response_code? ( 200 ) then 'OK'
when response_code? ( 404 ) then 'Not found'
else 'Unknown code'
end
下面是一个在具体项目中使用的用于对Array
进行模式匹配的方法:
def matches ( expected )
-> ( actual ) {
expected . zip ( actual ). all? do | ( exp , act ) |
exp === act
end
}
end
def __
-> ( x ) { true }
end
使用时就可以像下面这样对Array
进行匹配:
case [ a , b ]
when matches ([ true ])
"matches when a is `true`"
when matches ([ true , true ])
"matches when a and b are `true`"
when matches ([ __ , true ])
"matches when b is `true`"
when matches ([ false , ( 4 .. 10 )])
"matches when a is `false` and b is number in range 4-10"
when matches ([ Array , Hash ])
"matches when a is an `Array` and b is a `Hash`"
本文参考:
Lambdas/Procs in Case Expressions
06 Mar 2015
最近由于很多时间是在家里工作的,所以就需要把家里的工作环境和设施弄得舒服,实用一些。
今天终于把看了很久的Dell U2913WM 29寸的显示器买了回来,这个显示器的比例很特别是21:9的,所以看上去很宽。分辨率是2560*1080,并不是最牛的4k显示器。这是由于我的需求决定,我想用一个显示器来显示两屏的代码,而且4k的显示器,有时候应用菜单或者标题很小,经常需要调整字体大小。当然价钱也是一个考虑因素,这款显示器非常实惠,网上买的价格:580澳币。
小插曲:显示器自带了一根DisplayPort-Mini DisplayPort的线,我的Macbook Pro是可以用,但是一开始显示效果不好,代码看上去模糊,我尝试了各种办法进行调校都没有搞定,准备换一根Mini DisplayPort-Mini DisplayPort的线再试试。后来,我随手升级了一些MacOS的补丁,重启后发现就正常了。
今天还买了宜家的电脑椅,我这屁股对椅子比较挑剔,有一次在一个朋友家坐了几次宜家的电脑椅,发现很舒服。所以就果断买了,型号是:MALKOLM Swivel chair,买之前我专门买了一杯咖啡,然后到宜家的showroom,坐着这把椅子把咖啡喝完。
接下来其实我还想买的就是能够自由升降,可以站立或者坐着办公的桌子,我喜欢站着工作,同时对身体也好。宜家美国的网站已经有有一款这样的新产品BEKANT Desk sit/stand,澳洲这里还没有,再等等吧。不过我在澳洲发现了款不错的替代产品VARIDESK ,可以直接放到已有的桌子上进行升降,不需要买一个新的桌子。
看,这就是我现在工作桌面的样子。
其他的宝贝还有:
Bose QuietComfort 25 强力消音耳机(很给力,娃再哭再闹都听不见!)
Macbook Pro
NSO Power Ball (神奇健身球)
微软的无线键盘鼠标
黑色的Mug (简直太配了!)
13 Feb 2015
性能优化
bullet - 帮忙优化Rails的N+1 queries
日志相关
lograge - 精简rails log的gem
activerecord-colored_log_subscriber - 让Rails中不同的sql语句显示不同颜色(Rails5之前)
代码检查
brakeman - 检查应用安全漏洞的gem
rubocop - 检查code style
rails_best_practices
dawn
开发调试
awesome_print - 漂亮得打印出ruby的对象
rack-dev-mark - 给页面加个彩带,用于区分开发或者测试环境
quiet_assets - 干掉烦人的静态文件的请求日志
activerecord-colored_log_subscriber - 用不同的颜色显示不同的SQL语句
peek - 方便查看应用各个基础服务的信息和性能
环境配置
dotenv-rails - 方便配置和使用
注释相关
annotate - 给ActiveRecord等model加注释
国际化
money - 处理钱或货币的gem
money-rails - Ruby Money与Rails的整合
12 Feb 2015
参考资料
这次系统得学习一下cucumber,首先还是通过几个railscasts上的视频进行学习,虽然里面使用的是rails2,我还是用rails3及相关的gem重新实现了一遍。
实现代码:Learn cucumber
Railscasts上相关视频教程:
进一步深入学习的话还有两个资源可以参考:
技巧及经验总结
命令行参数
cucumber features
-r :用于指定在那个或者那些目录下面寻找匹配的step definition
-t :用于指定scenario的标签。例如: -t @focus, 或者排除指定标签: -t ~@focus
工具
Sublime可以安装Sublime Gherkin Formatter
这个插件,可以用于格式化表格数据,快捷键是:<Cmd> + <Shift> + |
DRY
可以使用background定义一系列的scenario需要用到步骤
可以使用scenario outline定义类似的一组测试
使用launchy gem调试
可以使用step: Then show me the page
可以在step的定义里面调用: save_and_open_page
可以用下面的方法当测试失败时,自动打开页面调试:
新建/features/support/debugging.rb
,
添加代码:
After do | scenario |
save_and_open_page if scenario . failed? and ( ENV [ "debug" ] == "open" )
end
然后运行测试时加上debug环境变量
cucumber features debug=open
使用World扩展cucumber
使用Class进行扩展
例如,需要反复用到用户登录的功能,可以重构一个helper方法:
# features/support/login_helpers.rb
class LoginHelpers
def login_user ( username )
visit ( "/login" )
fill_in ( "user name" , :with => username )
fill_in ( "password" , :with => "tester" )
click_button ( "login" )
page . should have_content ( "welcome" )
end
def another_logging_method . . .
end
World do
LoginHelpers . new
end
# features/step_definitions/user/login.rb
When /^"(.?)" logs in do |username|
login_user(username)
end
# features/support/paths.rb
module NavigationHelpers
def path_to ( page_name )
case page_name
when /the homepage/
root_path
when /the list of (.+)/
send " #{ $1 } _path"
when /the show page for (.+)/
polymorphic_path ( model ( $1 ))
else
raise "Can't find mapping from \" #{ page_name } \" to a path."
end
end
end