Ruby On Rails--rake 任务中定义方法的陷阱
来源:互联网 发布:淘宝组装电脑都在武汉 编辑:程序博客网 时间:2024/05/29 14:39
问题描述
在rails项目中,有时候需要导出数据、处理历史数据等,这时用rake是很方便的。
在rake中,有时候由于逻辑比较复杂,所以我们就会分离逻辑或者需要重用代码,这时候可能会定义方法。
但是,在rake中定义方法有一个问题:在不同rake文件和不同命名空间下定义的方法,如果存在了同名方法,那么后来定义的方法会覆盖掉之前定义的方法,这时候可能会导致bug。
下面我们用一个例子来具体说明下:
比如有个项目 sample_app,我们有2个rake文件:
sample_app/lib/tasks/export_data/export_users.rake
sample_app/lib/tasks/handle_old_data/hanlde_old_users.rake
在项目中排列顺序和这里列出的顺序一致。
对应代码如下:
# sample_app/lib/tasks/export_data/export_users.rakenamespace :export_data task export_users: :environment do user_data = get_user_data # other operations end def get_user_data puts "In export_data, get_user_data" # return user_data endend#sample_app/lib/tasks/handle_old_data/hanlde_old_users.rakenamespace :handle_old_data task handle_old_users: :environment do user_data = get_user_data # other operations end def get_user_data puts "In handle_old_data, get_user_data" # return user_data endend
在命令行执行 rake handle_old_data:handle_old_users时会打印出:
In handle_old_data, get_user_data
这时如果在命令行执行 rake export_data:export_users ,那么会打印出来什么呢?
答案是:
In handle_old_data, get_user_data
也就是说,在第一个rake中调用 get_user_data 方法时,实际上是调用的 第二个rake中定义的该方法。
那么这是为什么呢?
问题解答和解决方案
这个问题出现的原因,其实仔细思考一下是不难得到答案的:
lib/tasks/ 目录下的文件是依次加载的,而且rake中的命名空间(namespace)是只对rake任务起作用的,不会对文件中的方法起作用,所以后加载的第二个rake文件中的方法定义覆盖掉了前一个同名方法。
那么,怎么解决这个问题呢?
也许有人会说,不要用同名方法不就行了吗?
这样当然是一种解决问题的方式。但是这样对于开发者来说很不友好–谁会喜欢在定义方法前,去全局搜索下别人有没有用过这个方法名?
所以,我们需要更加优雅的解决方案。
我们可以有一种方式来很好地解决这个问题:
我们在rake中定义方法时,给方法加上命名空间–可以新定义一个class或者一个module,然后将方法定义到其中;这样相当于将我们的方法定义限制在了我们期望的范围内。
以同时使用module和class为例,可以这样解决问题:
# sample_app/lib/tasks/export_data/export_users.rakenamespace :export_data task export_users: :environment do user_data = ExportData::ExportUsers.get_user_data # other operations end module ExportData class ExportUsers def self.get_user_data puts "In export_data, get_user_data" # return user_data end end endend#sample_app/lib/tasks/handle_old_data/hanlde_old_users.rakenamespace :handle_old_data task handle_old_users: :environment do user_data = HandleOldData::HandleOldUsers.get_user_data # other operations end module HandleOldData class HandleOldUsers def self.get_user_data puts "In handle_old_data, get_user_data" # return user_data end end endend
这样,这两个方法就相互不影响。
在命令行执行 rake handle_old_data:handle_old_users 时会打印出:
In handle_old_data, get_user_data
这时如果在命令行执行 rake export_data:export_users ,那么会打印出来:
In export_data, get_user_data
- Ruby On Rails--rake 任务中定义方法的陷阱
- Ruby on Rails中的Rake教程
- rails中创建rake任务
- Ruby on Rails中的Rake教程(Rake如何把我灌醉!)
- Ruby on Rails 错误“Rails 4.0.0, Gemfile requires rake 10.1.0 for Rake” 解决方案
- Ruby on Rails,rake工具使用和数据库migrations迁移的概念
- ruby on rails学习第5篇:rake的用法(转载)
- Ruby on Rails(ROR)——rake routes
- Ruby on Rails 使用 Cookie 的方法
- ruby on rails 的数据库查询方法
- ruby on rails 的数据库查询方法
- Ruby自定义rake任务
- ruby on rails 中render的使用
- ruby on rails 中脚手架的使用
- Ruby on Rails,数据库迁移任务出错后的解决办法
- 如何将Gem中的rake任务导入Rails Project中
- rails之自定义Rake任务
- ruby on rails 中gsub方法做替换处理。
- .net 代码里的monitor
- Linux的进程/线程间通信方式总结 02
- HTTP Get请求URL最大长度
- iOS闭包循环引用精讲
- 关于java
- Ruby On Rails--rake 任务中定义方法的陷阱
- Android开发之Fragment
- 面试题之Memcached与Redis的区别
- Java图形界面基础实战项目讲解以及构造方法的介绍
- 算法笔记——【动态规划】最大子段和
- 安卓调用系统相机,通过路径返回清晰图片
- aircarck-ng
- JAVA-多线程
- ps aux命令显示的状态列中的Ss+,Rsl,R+,S<sl都是什么意思呢?