Ruby中任务构建工具rake的入门学习教程

Rake简介

Rake的意思是Ruby Make,一个用ruby开发的代码构建工具.

但是,为什么Ruby需要Rake?

按理说Ruby代码无需编译,应该不需要Rake才对呀?原来,Rake另有妙用,即把Rake当做一个任务管理工具来使用...这样做有两个好处:

1.以任务的方式创建和运行脚本

当然,你可以用脚本来创建每一个你希望自动运行的任务.但是,对于大型的应用来说,你几乎总是需要为数据库迁移(比如Rails中db:migrate任务)、清空缓存、或者代码维护等等编写脚本.对于每一项任务,你可能都需要写若干脚本,这会让你的管理变得复杂.那么,把它们用任务的方式整理到一起,会让管理变得轻松很多.

2.追踪和管理任务之间的依赖

Rake还提供了轻松管理任务之间依赖的方式.比如,"migrate"任务和"schema:dump"任务都依赖于 "connect_to_database"任务,那么在"migrate"任务调用之前,"connect_to_database"任务都会被执行.

下面入正题吧,即如何用Rake编写一个任务脚本..

顺序执行

在Rake中定义任务后,可以指定任务的执行顺序,例如,每天早晨起床后的例行公事:
1. 关闭闹钟
2. 梳洗打扮
3. 泡杯咖啡
4. 遛狗
上面的几项事物,在Rakefile中这样描述

 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

通过rake ready_for_the_day来执行任务,然后你就可以看到,所有的task都在按照你预定的顺序在执行。

 Turned off alarm. Would have liked 5 more minutes, though.
 Brushed teeth.
 Showered.
 Shaved.
 Made 5 cups of coffee. Shakes are gone.
 Dog walked.
 Ready for the day!

此外还可以用过rake make_coffee COFFEE_CUPS=5这样在命令中给变量赋值。

命名空间

上面那样定义任务没有问题,但如果你需要另外定义些事物,比如工作相关的,交通相关的,这时候所有的任务混杂到一起显然就不合适了,毕竟上面那些任务只是我们起床的例行事物,与其它无关。

通过namespace可以帮助我们定义出Rails中类似rake db:migrate的任务,描画出事物间清晰的边界,将上面的任务包括在namespace的一个代码块中,如下

 namespace :morning do
  task :turn_of_alarm
  ....
 end

这一次我们的调用命令就需要稍微做出些许变化,rake COFFEE_CUPS=3 morning:ready_for_the_day。 是不是跟rails中的rake任务调用方式很像呢?

默认Task

有了上面那些设置,如果我们忘记或者不想写详细的任务名称,直接执行rake会有什么效果呢,结果是rake aborted!,任务被中断的报错。既然有这样的可能性,我们就需要消除这些隐患,通过设置default默认任务就可以做到,如下:

 task :default => 'morning:turn_off_alarm'

当你直接执行rake命令时,会执行默认操作,帮我们关闭闹钟。

描述你的Task

当任务渐渐变多以后,管理问题就暴露出来了,除了命名空间以外,我们还需要文档类的支持,帮助我们梳理任务并显示的告诉我们每个任务的目的和功能,这时你可以试一试用desc描述任务。

 ...
 desc "Make coffee"
 task :make_coffee do
  cups = ENV["COFFEE_CUPS"] || 2
  puts "Made #{cups} cups of coffee. Shakes are gone."
 end
 ...

上面的描述不仅可以在文档中查看,同时使用rake -T也能清洗的了解到每个任务是做什么的。rake -T的输出结果是按照字母顺序排的序。

 rake morning:make_coffee    # Make coffee

调取Task

Rake还允许在不同任务之间互相调用,例如下面的代码,你想在下午也来杯咖啡,不用重复定义,直接使用上午的泡法,来一杯即可。

namespace :afternoon do
  task :make_coffee do
   Rake::Task['morning:make_coffee'].invoke
   puts "Ready for the rest of the day!"
  end
 end


Rake脚本编写

先来个简单的例子,如下:

假设你是一个火星成员,老版本那些,即如燕儿虎跑之类的,在周末你打算去车车那边打火锅,然后集体PC去.对应这个情况,你需要为自己制定三个任务:搭车找车车、烤鱼和网吧PC.用vim创建创建一个名叫rakefile的文件(备注:Rake会在当前路径下寻找名叫Rakefile、rakefile、RakeFile.rb和rakefile.rb的rake文件),并键入如下代码:

desc "任务1 -- 搭车去车车那里"#这据说是个苦差,因为太远了
task :busboy do
puts "发现挫男"
end 

desc "任务2 -- 烤鱼"
task :bitchfish do
puts "老板,先烤九斤鱼"
end 

desc "任务3 -- 网吧PC"
task :pc do
puts "我选中路"
end

打开命令行工具,进入这个文件所在目录,然后运行下面的命令,大致应该类似如下结果:

D:\work>rake busboy
(in D:/work)
发现挫男 

D:\work>rake bitchfish
(in D:/work)
老板,先烤九斤鱼 

D:\work\ruby_works\ruby_book>rake laundry
(in D:/work)
我选中路

(备注:文字部分是没啥逻辑的,纯粹娱乐下...)

分析:

相信看完上面那段东东,你已经知道怎么搞了...现在介绍些基础知识,方便加深理解.从上面的代码可以知道,此文件一共定义了3个任务,desc是Rake定义的方法,表示对下面定义任务的描述.这个描述会在使用Rake --tasks(或者Rake -T)命令时输出在屏幕上.

D:\work>rake --tasks
(in D:/work)
rake bitchfish #任务2 -- 烤鱼
rake busboy #任务1 -- 搭车去车车那里(这据说是个苦差,因为太远了)
rake pc 任务3 -- 网吧PC

task是Rake最重要的方法.它的方法定义是:task(args, &block).任务体是一个block,本例中只是简单输出你所要做的工作.需要注意的是代码

puts "发现挫男"

完全是一个普通的Ruby语句,puts是Ruby中进行输出的一般性方法,可以看出,Rake任务可以完全使用Ruby的能力,这使得它非常强大.

go..go..go..go..

接下来加入依赖关系:

很显然,在我们定义的任务中,"烤鱼"是依赖于"搭车去车车那里"的(其它地方有没烤鱼吃不知道,反正地点就定在那了).那么,我们需要在我们的任务定义中加入这个依赖关系,修改后的文件如下:

desc "任务1 -- 搭车去车车那里"
task :busboy do
puts "发现挫男"
end 

desc "任务2 -- 烤鱼"
task :bitchfish => :busboy do
puts "老板,先烤九斤鱼"
end 

desc "任务3 -- 网吧PC"
task :pc do
puts "我选中路"
end

再次运行烤鱼任务,你会得到如下结果:

D:\work>rake bitchfish
(in D:/work)
发现挫男
老板,先烤九斤鱼

加入命名空间:

跟任何编程语言类似,当你的rake文件很多时,当你有很多任务的时候,你需要关注它们的命名冲突问题,命名空间(namespace)就是一个自然的解决方案.你可以为上面的三个任务定义一个叫做dan的命名空间.

namespace :dan do
desc "任务1 -- 搭车去车车那里"
task :busboy do
puts "发现挫男"
end
……
end

再次运行rake --tasks,你会得到如下的结果:

D:\work >rake --tasks
(in D:/work)
rake dan:bitchfish # 任务2 -- 烤鱼
rake dan:pc # 任务3 -- 网吧PC
rake dan:busboy # 任务1 -- 搭车去车车那里

你现在需要使用rake dan:bitchfish才能启动烤鱼这个任务了.
(BTW,你可以在你的rakefile中使用多个命名空间,对任务进行分类.)

了解了上面两个知识点后,我们来了解下两个具体实例:

1.在一个任务中调用另外一个任务

当任务众多的时候,你很可能需要在一个任务中调用另外一个任务,假设我们把今天所有要做的工作定义为一个任务:today.在这个任务中,有两个任务需要被调用,一个是烤鱼,一个是网吧PC.当然,由于烤鱼依赖于搭车去车车那里,我们还是需要搭车去车车那里的.在文件的顶部定义一个today的任务:

desc "今天的任务"
task :today do
Rake::Task["dan:bitchfish"].invoke
Rake::Task["dan:pc"].invoke
end 

namespace :dan do
……
end

可以看出,调用其它任务的方式很简单,只需要调用

Rake::Task["task_name"].invoke

方法就可以了.在命令行中启动rake today,可以得到:

D:\work >rake today
(in D:/work)
发现挫男
老板,先烤九斤鱼
我选中路

2.默认任务:

可以为Rake增加一个默认任务,这样可以简单地用Rake命令来触发这个默认任务,在上面的rakefile中,我们可以用如下方式把"today"任务作为默认任务.

task :default => [:today]

然后调用直接在命令行中调用rake,可以得到跟调用rake today同样的输出结果.

这就是我们简单的一个Rake任务定义,下面是完整的修改后的rakefile:

task :default => [:today] 

desc "今天的任务"
task :today do
 Rake::Task["dan:bitchfish"].invoke
 Rake::Task["dan:pc"].invoke
end 

namesoace :dan do
 desc "任务1 -- 搭车去车车那里(这据说是个苦差,因为太远了)"
 task :busboy do
  puts "发现挫男"
 end 

 desc "任务2 -- 烤鱼"
 task :bitchfish do
  puts "老板,先烤九斤鱼"
 end 

 desc "任务3 -- 网吧PC"
 task :pc do
  puts "我选中路"
 end
end

看完上面两个例子,估计rake任务就算全部了解了...其它都是些代码枪花罢了..多耍便是..

(0)

相关推荐

  • 学习Ruby你需要了解的相关知识(rvm, gem, bundle, rake, rails等)

    Ruby 这个就不用多说了 RVM 用于帮你安装Ruby环境,帮你管理多个Ruby环境,帮你管理你开发的每个Ruby应用使用机器上哪个Ruby环境.Ruby环境不仅仅是Ruby本身,还包括依赖的第三方Ruby插件.都由RVM管理. Rails 这个也不用多说,著名开发框架.详细看 http://zh.wikipedia.org/wiki/Ruby_on_Rails RubyGems RubyGems是一个方便而强大的Ruby程序包管理器( package manager),类似RedHat的RP

  • Ruby中任务构建工具rake的入门学习教程

    Rake简介 Rake的意思是Ruby Make,一个用ruby开发的代码构建工具. 但是,为什么Ruby需要Rake? 按理说Ruby代码无需编译,应该不需要Rake才对呀?原来,Rake另有妙用,即把Rake当做一个任务管理工具来使用...这样做有两个好处: 1.以任务的方式创建和运行脚本 当然,你可以用脚本来创建每一个你希望自动运行的任务.但是,对于大型的应用来说,你几乎总是需要为数据库迁移(比如Rails中db:migrate任务).清空缓存.或者代码维护等等编写脚本.对于每一项任务,你

  • MyBatis入门学习教程(一)-MyBatis快速入门

    MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis .2013年11月迁移到Github. iBATIS一词来源于"internet"和"abatis"的组合,是一个基于Java的持久层框架.iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAO) 首先给大家介绍MyBatis的含义

  • mybatis快速入门学习教程新手注意问题小结

    什么是mybatis MyBatis是支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索.MyBatis使用简单的XML或注解用于配置和原始映射,将接口和Java的POJOs(Plan Old Java Objects,普通的Java对象)映射成数据库中的记录. orm工具的基本思想 无论是用过的hibernate,mybatis,你都可以法相他们有一个共同点: 1. 从配置文件(通常是XML配置文件中)得到 ses

  • MyBatis入门学习教程-MyBatis快速入门

    目录 Mybatis 一.快速开始 1.创建 Maven 项目 2.导入 Maven 依赖 3.配置 Maven 插件 4.新建数据库,导入表格 5.编写 Mybatis 配置文件 6.编写实体类 7.编写 mapper 接口 8.编写 mapper 实现 9.Mybatis 配置文件中,添加 mapper 映射 10.编写 Mybatis 工具类 11.测试 二.日志添加 1.添加 Maven 依赖 2.添加 log4j 配置 3.Mybatis 中配置 LOG 4.执行测试 三.Mybati

  • mybatis框架入门学习教程

    MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装.MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录. 1.创建工程,导入jar包 创建一个java工程或者web工程都可以,然后导入mybatis的jar包和依赖包还有数据库的jar包,本人使用Oracle10g数据库

  • Python装饰器入门学习教程(九步学习)

    装饰器(decorator)是一种高级Python语法.装饰器可以对一个函数.方法或者类进行加工.在Python中,我们有多种方法对函数和类进行加工,比如在Python闭包中,我们见到函数对象作为某一个函数的返回结果.相对于其它方式,装饰器语法简单,代码可读性高.因此,装饰器在Python项目中有广泛的应用. 这是在Python学习小组上介绍的内容,现学现卖.多练习是好的学习方式. 第一步:最简单的函数,准备附加额外功能 # -*- coding:gbk -*- '''示例1: 最简单的函数,表

  • Ajax入门学习教程(一)

    1 什么是AJAX AJAX(Asynchronous JavaScript And XML)翻译成中文就是"异步Javascript和XML".即使用Javascript语言与服务器进行异步交互,传输的数据为XML(当然,传输的数据不只是XML). AJAX还有一个最大的特点就是,当服务器响应时,不用刷新整个浏览器页面,而是可以局部刷新.这一特点给用户的感受是在不知不觉中完成请求和响应过程. 与服务器异步交互: 浏览器页面局部刷新: 2. 同步交互与异步交互 同步交互:客户端发出一个

  • Kotlin入门学习教程之可见性修饰符

    目录 前言 1.包场景下的可见性修饰符 2.类内部声明的成员 总结 前言 在Kotlin中四种可见性修饰符:private.protected.internal.public,如果没有显示指定修饰符的话,默认可见性是public. 四种修饰符的说明 public修饰符表示 公有 .此修饰符的范围最大.当不声明任何修饰符时,系统会默认使用此修饰符. internal修饰符表示 模块 .对于模块的范围在下面会说明. protected修饰符表示 私有`+`子类.值得注意的是,此修饰符不能用于顶层声明

  • Vue + OpenLayers 快速入门学习教程

    Openlayers 是一个模块化.高性能并且功能丰富的WebGIS客户端的JavaScript包,用于显示地图及空间数据,并与之进行交互,具有灵活的扩展机制. 简单来说,使用 Openlayers(后面简称ol) 可以很灵活自由的做出各种地图和空间数据的展示.而且这个框架是完全免费和开源的. 前言 本文记录 Vue 使用 OpenLayers 入门,使用 OpenLayers 创建地图组件,分别使用 OpenLayers 提供的地图和本地图片做为地图. Overview OpenLayers

  • 在Ruby中处理文件的输入和输出的教程

    Ruby 提供了一整套 I/O 相关的方法,在内核(Kernel)模块中实现.所有的 I/O 方法派生自 IO 类. 类 IO 提供了所有基础的方法,比如 read. write. gets. puts. readline. getc 和 printf. 本章节将讲解所有 Ruby 中可用的基础的 I/O 函数.如需了解更多的函数,请查看 Ruby 的 IO 类. puts 语句 在前面的章节中,您赋值给变量,然后使用 puts 语句打印输出. puts 语句指示程序显示存储在变量中的值.这将在

随机推荐