用pry阅读ruby源码--以task方法为例

来源:互联网 发布:联想笔记本网络驱动 编辑:程序博客网 时间:2024/04/28 02:24

rails项目中有个目录 lib/tasks,里面定义了一个rake任务:

task hello: :hello do
puts “hello”
end

看到这里的时候,是不是可能会对 task 方法产生一些兴趣?

可以在rails项目的Gemfile中加入 pry这个强大的工具,然后一步步找到这个task方法的本质。

1,在task中加入断点:
binding.pry

2,断点中用 show-method 方法
用show-method按图索骥,可以层层揭开 task 的面纱。

[33] pry(main)> [34] pry(main)> show-method taskFrom: /home/liukun/.rvm/gems/ruby-2.1.1@zhe800_zhaoshang/gems/rake-10.0.4/lib/rake/dsl_definition.rb @ line 31:Owner: Rake::DSLVisibility: privateNumber of lines: 3def task(*args, &block)  Rake::Task.define_task(*args, &block)end[35] pry(main)> show-method Rake::Task.define_taskFrom: /home/liukun/.rvm/gems/ruby-2.1.1@zhe800_zhaoshang/gems/rake-10.0.4/lib/rake/task.rb @ line 350:Owner: #<Class:Rake::Task>Visibility: publicNumber of lines: 3def define_task(*args, &block)  Rake.application.define_task(self, *args, &block)end[36] pry(main)> show-method Rake.application.define_taskFrom: /home/liukun/.rvm/gems/ruby-2.1.1@zhe800_zhaoshang/gems/rake-10.0.4/lib/rake/task_manager.rb @ line 23:Owner: Rake::TaskManagerVisibility: publicNumber of lines: 13def define_task(task_class, *args, &block)  task_name, arg_names, deps = resolve_args(args)  task_name = task_class.scope_name(@scope, task_name)  deps = [deps] unless deps.respond_to?(:to_ary)  deps = deps.collect {|d| d.to_s }  task = intern(task_class, task_name)  task.set_arg_names(arg_names) unless arg_names.empty?  if Rake::TaskManager.record_task_metadata    add_location(task)    task.add_description(get_description(task))  end  task.enhance(deps, &block)end[37] pry(main)> 

3, environment的作用是什么?
用来通知Rake需要加载rails环境。
参考:
http://stackoverflow.com/questions/7044714/whats-the-environment-task-in-rake

4,进一步理解 environment
http://jasonseifer.com/2010/04/06/rake-tutorial

  task :turn_off_alarm do    puts "Turned off alarm. Would have liked 5 more minutes, though."  end  task :groom_myself do    puts "Brushed teeth."    puts "Showered."    puts "Shaved."  end  task :make_coffee do    cups = ENV["COFFEE_CUPS"] || 2    puts "Made #{cups} cups of coffee. Shakes are gone."  end  task :walk_dog do    puts "Dog walked."  end  task :ready_for_the_day => [:turn_off_alarm, :groom_myself, :make_coffee, :walk_dog] do    puts "Ready for the day!"  end

By running the ready_for_the_day task it notices that the turn_off_alarm, groom_myself, make_coffee, and walk_dog tasks are all prerequisites of the ready_for_the_day task. Then it runs them all in the appropriate order.

0 0
原创粉丝点击