核心使用 task 指令 实现多机部署
# encoding:utf-8 # >cap local deploy # >cap remote deploy set :application, "entos" set :deploy_to, "/data/projects/entos" set :scm, "git" set :repository, "git@114.255.155.167:entos.git" set :branch, "master" set :use_sudo, false set :rails_env,"production" task :remote do set :user, "entsea" set :deploy_via, :remote_cache set :copy_exclude, %w(external) server "114.255.155.166", :web, :app, :db, :primary => true end task :local do set :user, 'zzq' set :deploy_via, :remote_cache set :copy_exclude, %w(external) server '192.168.10.105', :web, :app, :db, :primary => true end namespace :deploy do task :start do; end task :stop do; end desc "Creating ln -s , example: database.yml" task :create_sync do run "ln -s #{shared_path}/config/database.yml #{current_path}/config/database.yml" end desc "Restarting unicorn" task :restart, :roles => :app, :except => { :no_release => true } do # run "/bin/sh restart_server.sh" end end after "deploy:symlink", "deploy:create_sync"
今天一个同事 问我 正则 里 ?: 什么意思,记得 以前知道的 , 愣是 忘记了 ,查了下 是非捕获组的意思!
捕获组
()内的是分组,可以用 $1,$2…取值
demo:
ruby-1.9.2-p290 :022 > "abcabc".match(/(abc)/) => #<MatchData "abc" 1:"abc"> ruby-1.9.2-p290 :023 > $1 => "abc"
非捕获组
(?:) 内的不当作分组
demo:
ruby-1.9.2-p290 :024 > "abcabc".match(/(?:abc)/) => #<MatchData "abc"> ruby-1.9.2-p290 :025 > $1 => nil
环境:ruby 1.9.2
有这样一个需求, 给你 任意一个字符串,把它转化为类,网上大多数的 解决办法是 下面三种:
Kernel.const_get(:User) # Object.const_get(:User) eval(’User’) ‘User’.constantize
但是上面三种方法, 这个 User 事先必须是初始化的,不然会报错,如下:
Object.const_get(:User) # uninitialized constant User (NameError)
所以需要加个判断 这个 Class 有没有初始化,没有的话 再set 一个Class
require "rails/all" def Kernel.const_missing(name) Object.const_set(name,Class.new) end #p Kernel.const_get("baoxiaos".to_sym) # wrong constant name baoxiaos (NameError) p Kernel.const_get("baoxiaos".classify.to_sym) # Baoxiao , const的首字母必须大写 p Kernel.constants # [] p Object.constants.include?(:UBaoxiao) # true
刚开始把这个 const 定义在 Object 里:
require "rails/all" def Object.const_missing(name) Object.const_set(name,Class.new) end #p Object.const_get("baoxiaos".to_sym) # wrong constant name baoxiaos (NameError) p Object.const_get("baoxiaos".classify.to_sym)
发现 用在 rails 中后 , rails 处处报错,可能 怪我重写了 Object.const_missing 导致的 ……..
上面方法的原理是 当找不到 const的时候 执行了
Object.const_set(name,Class.new)
那么 name 就变成是 Class 的实例了 , 为什么定义在 Kernel 中的 const_missing ,Object 也可以访问到,需要注意 Object,Kernel 之间的关系,Object 是 inluce Kernel 的,如下:
class Object include Kernel end
SEE:
http://niczsoft.com/2010/01/string-to-class-in-ruby-on-rails/
http://www.ruby-forum.com/topic/96222
环境:mac os x lion
homebrew是用ruby写的脚本,发现和rvm极其相似
安装 homebrew
>/usr/bin/ruby -e "$(curl -fsSL https://raw.github.com/gist/323731)"
安装imagemagick
>brew install imagemagick
安装到libtiff 库时 出错
curl: (7) couldn't connect to host Error: Failure while executing: /usr/bin/curl -f#LA Homebrew\ 0.8\ (Ruby\ 1.8.7-249;\ Mac\ OS\ X\ 10.7.1) ftp://ftp.remotesensing.org/pub/libtiff/tiff-3.9.5.zip -o /Users/wangxianfeng/Library/Caches/Homebrew/libtiff-3.9.5.zip
fixed :
>/usr/bin/curl http://download2.osgeo.org/libtiff/tiff-3.9.5.zip -o ~/Library/Caches/Homebrew/libtiff-3.9.5.zip
再次安装:
>brew install imagemagick
最后测试安装成功:
wxianfeng:inono wangxianfeng$ convert --version Version: ImageMagick 6.7.1-1 2011-09-10 Q16 http://www.imagemagick.org Copyright: Copyright (C) 1999-2011 ImageMagick Studio LLC Features: OpenMP
可以查看出brew安装了下面的库:
wxianfeng:inono wangxianfeng$ brew list imagemagick jasper jpeg libtiff little-cms
see:
https://github.com/mxcl/homebrew/wiki/installation
https://github.com/mxcl/homebrew/pull/5168
时间: 2011-07-24
收获:
发现北京ROR的公司不是一般的多,签到单上看到N多公司,技术上没有太大收获,都是介绍性的,没有实战性的,内容主要涉及: mirah , Mongodb,Erlang,Grape
进程:http://www.surveymonkey.com/s/MSY2L7T
PS : 798 很好玩,很有艺术特色
现场:
798 入口
Ruby活动地方
Rails rumble 创始人
现场job board
现场
清一色老外,清一色Mac
介绍Mirah
798
798
798
yaml 的语法真是变态 , 表示个数组这么麻烦, 更复杂的数据结构 那不是更麻烦 !!!
yaml 文件:
# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html one: name: MyString orgunit_id: 1 inheritable: false # codes 是yaml数组表示方法 # 缩进只能是两个空格为一级,不能是其他字符 codes: - 1 - a - 2 - b - 3 - c
ruby 解析yaml:
ruby-1.9.2-p0 > file = "#{Rails.root}/test/fixtures/enumerations.yml" => "/usr/local/system/projects/entos/ent_os/test/fixtures/enumerations.yml" ruby-1.9.2-p0 > YAML.load File.read(file) => {"one"=>{"name"=>"MyString", "orgunit_id"=>1, "inheritable"=>false, "codes"=>[1, "a", 2, "b", 3, "c"]}}
不知道怎么写的可以 使用 to_yaml 方法 看一下:
irb(main):001:0> => {"one"=>{"name"=>"MyString", "inheritable"=>false, "orgunit_id"=>1, "codes"=>[1, "a", 2, "b", 3, "c"]}} irb(main):002:0> require "yaml" => true irb(main):003:0> hsh.to_yaml => "--- \none: \n name: MyString\n inheritable: false\n orgunit_id: 1\n codes: \n - 1\n - a\n - 2\n - b\n - 3\n - c\n"
可读性 更好的 使用 y 方法
ruby-1.9.2-p0 > y hsh --- one: name: MyString orgunit_id: 1 inheritable: false codes: - 1 - a - 2 - b - 3 - c => nil
环境:ruby 1.9.2 + rake 0.8.7 + rails 3.0.3
今天在写 rake 文件 , 提示我没找到 model Class,问题在于我没加 => :environment , 那为什么加上 => :environment 就可以了 , 研究了下rake:
task :test => :environment do end
其中后面的 :environment 也是 一个 task , 也就是说在执行 test 这个 task 之前 会执行 :environment 这个 task,有点像rails controller 中的 before_filter ,那么 :environment 这个task 定义在什么地方,rails project中也没有啊 。。。,定义在 rails 源码中了 ,你在 你的project下执行 rake environment 不会报错的
wxianfeng@ubuntu:/usr/local/system/projects/entos/ent_os$ rake environment --trace (in /usr/local/system/projects/entos/ent_os) ** Invoke environment (first_time) ** Execute environment
不过 也看不到 输出什么信息,因为只是加载了 运行环境而已 ,那么从哪里执行的,定义在 project 下 Rakefile 中了
# Add your own tasks in files placed in lib/tasks ending in .rake,
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
require File.expand_path('../config/application', __FILE__)
require 'rake'
EntOs::Application.load_tasks继续跟踪 load_tasks:
最后 找到了 task environment
def initialize_tasks
require "rails/tasks"
task :environment do
$rails_rake_task = true
require_environment!
end
end
全部文件 here
所以加载了 environment 也就可以 找到 model Class 了
总结:
1,rake 命名格式
rakefile, Rakefile, rakefile.rb, Rakefile.rb 都可以 ,常用 Rakefile
另外 rails 中使用的话,还可以 使用 .rake 后缀的文件
2,设置命名空间
namespace :test do end
3,设置默认task
task :default => ["test"]
可以指定多个 task,执行 rake 后 ,默认调用的是 default task
4,指定task执行顺序
task :test => [:hello,:world]
5,查看rake 任务
rake -T rake --tasks rake -T db: # 查看db打头的task
6,跟踪task
rake test --trace
更多 options
wxianfeng@ubuntu:/usr/local/system/projects/entos/ent_os$ rake -h rake [-f rakefile] {options} targets... Options are ... -C, --classic-namespace Put Task and FileTask in the top level namespace -D, --describe [PATTERN] Describe the tasks (matching optional PATTERN), then exit. -n, --dry-run Do a dry run without executing actions. -e, --execute CODE Execute some Ruby code and exit. -p, --execute-print CODE Execute some Ruby code, print the result, then exit. -E, --execute-continue CODE Execute some Ruby code, then continue with normal task processing. -I, --libdir LIBDIR Include LIBDIR in the search path for required modules. -P, --prereqs Display the tasks and dependencies, then exit. -q, --quiet Do not log messages to standard output. -f, --rakefile [FILE] Use FILE as the rakefile. -R, --rakelibdir RAKELIBDIR, Auto-import any .rake files in RAKELIBDIR. (default is 'rakelib') --rakelib -r, --require MODULE Require MODULE before executing rakefile. --rules Trace the rules resolution. -N, --no-search, --nosearch Do not search parent directories for the Rakefile. -s, --silent Like --quiet, but also suppresses the 'in directory' announcement. -g, --system Using system wide (global) rakefiles (usually '~/.rake/*.rake'). -G, --no-system, --nosystem Use standard project Rakefile search paths, ignore system wide rakefiles. -T, --tasks [PATTERN] Display the tasks (matching optional PATTERN) with descriptions, then exit. -t, --trace Turn on invoke/execute tracing, enable full backtrace. -v, --verbose Log message to standard output. -V, --version Display the program version. -h, -H, --help Display this help message.
DEMO:
wxianfeng@ubuntu:~/test/rake$ cat Rakefile desc "Default: test" task :default => ["r:test"] namespace :r do desc "test" task :test do puts "test" end desc "test1" task :test1 => :test do puts "test1" end desc "test3" task :test3 => :test4 do puts "test3" end end
SEE:
http://hi.baidu.com/%D0%C7203/blog/item/ebda2dd09f1d698ea1ec9c7a.html
http://guides.rubyonrails.org/command_line.html
http://ericzouthoughts.wordpress.com/2009/06/20/execute-shell-command-in-ruby-rake-task/
今天在rails中使用 returning 的时候 log 打出warning:
Object#returning has been deprecated in favor of Object#tap
环境是 ruby 1.9.2 + rails 3.0.3
从warn上看是returning不建议使用,建议使用tap方法,那么tap方法和returning方法有什么不同
Object#tap 方法是 ruby1.8.7 以后加入的,Object#returning 方法是 rails添加的
rails 3.0.3 returning 源码:here
rails 2.3.5 returning源码:
class Object
# Returns +value+ after yielding +value+ to the block. This simplifies the
# process of constructing an object, performing work on the object, and then
# returning the object from a method. It is a Ruby-ized realization of the K
# combinator, courtesy of Mikael Brockman.
#
# ==== Examples
#
# # Without returning
# def foo
# values = []
# values << "bar"
# values << "baz"
# return values
# end
#
# foo # => ['bar', 'baz']
#
# # returning with a local variable
# def foo
# returning values = [] do
# values << 'bar'
# values << 'baz'
# end
# end
#
# foo # => ['bar', 'baz']
#
# # returning with a block argument
# def foo
# returning [] do |values|
# values << 'bar'
# values << 'baz'
# end
# end
#
# foo # => ['bar', 'baz']
def returning(value)
yield(value)
value
end
# Yields <code>x</code> to the block, and then returns <code>x</code>.
# The primary purpose of this method is to "tap into" a method chain,
# in order to perform operations on intermediate results within the chain.
#
# (1..10).tap { |x| puts "original: #{x.inspect}" }.to_a.
# tap { |x| puts "array: #{x.inspect}" }.
# select { |x| x%2 == 0 }.
# tap { |x| puts "evens: #{x.inspect}" }.
# map { |x| x*x }.
# tap { |x| puts "squares: #{x.inspect}" }
def tap
yield self
self
end unless Object.respond_to?(:tap)
# An elegant way to factor duplication out of options passed to a series of
# method calls. Each method called in the block, with the block variable as
# the receiver, will have its options merged with the default +options+ hash
# provided. Each method called on the block variable must take an options
# hash as its final argument.
#
# with_options :order => 'created_at', :class_name => 'Comment' do |post|
# post.has_many :comments, :conditions => ['approved = ?', true], :dependent => :delete_all
# post.has_many :unapproved_comments, :conditions => ['approved = ?', false]
# post.has_many :all_comments
# end
#
# Can also be used with an explicit receiver:
#
# map.with_options :controller => "people" do |people|
# people.connect "/people", :action => "index"
# people.connect "/people/:id", :action => "show"
# end
#
def with_options(options)
yield ActiveSupport::OptionMerger.new(self, options)
end
# A duck-type assistant method. For example, Active Support extends Date
# to define an acts_like_date? method, and extends Time to define
# acts_like_time?. As a result, we can do "x.acts_like?(:time)" and
# "x.acts_like?(:date)" to do duck-type-safe comparisons, since classes that
# we want to act like Time simply need to define an acts_like_time? method.
def acts_like?(duck)
respond_to? "acts_like_#{duck}?"
end
end
可以看到 tap 方法也封装了,为了防止 ruby版本过低 没有tap方法就 添加Object#tap 方法,tap 和 returning本质是一样的,函数体都是调用block闭包,只不过returning需要传递一个参数给闭包,最后返回的就是这个参数,而 tap直接操作self指针,最后返回的也就是self
另外最新rails源码(>rails3.0.3)已经没有 returning方法了,所以以后最好都用tap方法
DEMO1:
require "rubygems" require "active_support" # Object#tap 是>ruby1.8.7 有的 # Object#returning 是Rails 封装的方法, rails3.X 已经不建议使用 # Object#tap 可以支持链式(chain)操作 (1..10).tap { |x| puts "original: #{x.inspect}" }.to_a.tap { |x| puts "array: #{x.inspect}" }.select {|x| x%2==0}.tap { |x| puts "evens: #{x.inspect}" }.map {|x| x*x}.tap { |x| puts "squares: #{x.inspect}" } def object_tap {}.tap do |h| # => Hash.new.tap h[:a] = 1 h[:b] =2 end end p object_tap # {:b=>2, :a=>1} def object_returning returning Hash.new do |h| # 注意这里不能用 {} , 放在 returning 方法后面 当作成 block闭包了 h[:a] = 1 h[:b] = 2 end end p object_returning # {:b=>2, :a=>1}
DEMO2:
require "rubygems" require "active_support" class Hash def shift_value_tap_self self.tap do |h| h.each { |k,v| v.shift if v.is_a?(Array) } end end def shift_value_tap {}.tap do |h| self.each { |k,v| v.is_a?(Array) ? h[k] = v.shift : h[k] = v } end end def shift_value_returning returning Hash.new do |h| self.each { |k,v| v.is_a?(Array) ? h[k] = v.shift : h[k] = v } end end def shift_value_returning_self returning self do |h| h.each { |k,v| v.shift if v.is_a?(Array) } end end end hsh = {"a"=>[1,2,3],"b"=>["g","f","w"],"c"=>"fuck_china"} hsh1 = {"a"=>[1,2,3],"b"=>["g","f","w"],"c"=>"fuck_china"} hsh2 = {"a"=>[1,2,3],"b"=>["g","f","w"],"c"=>"fuck_china"} hsh3 = {"a"=>[1,2,3],"b"=>["g","f","w"],"c"=>"fuck_china"} p hsh.shift_value_tap # {"a"=>1, "b"=>"g", "c"=>"fuck_china"} p hsh1.shift_value_returning # {"a"=>1, "b"=>"g", "c"=>"fuck_china"} p hsh2.shift_value_tap_self # {"a"=>[2, 3], "b"=>["f", "w"], "c"=>"fuck_china"} p hsh3.shift_value_returning_self # {"a"=>[2, 3], "b"=>["f", "w"], "c"=>"fuck_china"}
SEE:
http://blog.rubybestpractices.com/posts/gregory/011-tap-that-hash.html
http://www.simonecarletti.com/blog/2010/09/rails-3-beware-the-tap-pattern/
http://fuliang.javaeye.com/blog/857163
环境:ruby 1.9.2 + ubuntu 10.10
instance_variables 得到当前 对象已经开辟内存空间的实例变量,疑惑在这里
class Foo attr_accessor :sex,:birthday end p Foo.new.instance_variables # => []
刚开始不理解,怎么是 空……..
后来想了想,因为 ruby 是 动态的解释型的语言,如果没有 给实例变量赋值 的话,是不会开辟内存空间的,所以 instance_variables 只能得到已经开辟内存空间的 实例变量,
但是如果是 编译型的静态语言 则不然,例如java ,实例变量 声明了 就会开辟内存空间了
DEMO1:
# ruby version : 1.9.2 class Foo attr_accessor :sex,:birthday # attr_accessor ruby里封装的method end p Foo.new.instance_variables # => [] f = Foo.new p f.sex #=> nil f.sex = 'M' p f.instance_variables #=> [:@sex] p f.inspect # => "#<Foo:0x85ead8c @sex=\"M\">" b = Foo.new b.birthday = nil # 注意赋值为nil,也开辟了内存空间 p b.instance_variables # => [:@birthday] p b.inspect # => "#<Foo:0x9dca358 @birthday=nil>"
DEMO2:
class Foo def initialize @name = 'wxianfeng' end def bar # => as getter method @name end end f = Foo.new p f.instance_variables #=> [:@name] p f.inspect #=> "#<Foo:0x8aa7c08 @name=\"wxianfeng\">" p f.name # => undefined method `name' for #<Foo:0x99adf7c @name="wxianfeng"> p f.bar # => "wxianfeng"
ruby 源码:
# obj.instance_variables => array
#
#
# Returns an array of instance variable names for the receiver. Note
# that simply defining an accessor does not create the corresponding
# instance variable.
#
# class Fred
# attr_accessor :a1
# def initialize
# @iv = 3
# end
# end
# Fred.new.instance_variables #=> ["@iv"]
#
#
def instance_variables
# This is just a stub for a builtin Ruby method.
# See the top of this file for more info.
end
SEE:
http://www.megasolutions.net/ruby/instance_variables-doesnt-return-unassigned-variables-68358.aspx










