浏览 6771 次
锁定老帖子 主题:浏览(遍历)Ruby模块
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2006-06-15
module AA # something else... module BB # something else... end module CC # something else... end # something else... end 如何做一个module browser,也就是说,找出它的模块结构树(如下)呢? 引用 module AA
- module BB - module CC 用regular express读入源文件分析,还是用reflection机制? 两种方法我都考虑过,reflection机制,module好像没有sub_modules方法;直接分析源文件,遇到一些细节问题,如单双引号,也挺繁的。 做这个是因为最近考虑用Ruby做网页自动测试(比方调用WATIR或Selenium),testcase很多,需要模块化,所以想做一个模块浏览器。请问各位有何高招呢? 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2006-06-15
刚刚看了一下Eclipse RDT,它就做得比较好,能随着源代码的改变,自动生成一个模块、类和方法的outline。不知道它的实现机理是什么。见附件。
|
|
返回顶楼 | |
发表时间:2006-06-15
做了些实验,觉得RDT采用的方式,不象是在用reflection,而是直接对源文件进行语法分析(比方分块)。
仔细想想,也觉得这样做比较合适。看来我得继续朝这个方向努力了。有什么结果我会告诉大家。我会先用Ruby写一个分析器,整理出一棵树,然后套上GUI。 有何高见,希望继续讨论。谢谢。 |
|
返回顶楼 | |
发表时间:2006-06-16
哈哈,FreeRIDE也有这个功能,而且是用Ruby写成。可是对一个三千多行的.rb文件(watir.rb,Web自动测试库),它却分析不出来了,RDT可以。
继续研究。 |
|
返回顶楼 | |
发表时间:2006-06-16
Find配合正则就差不多了
|
|
返回顶楼 | |
发表时间:2006-06-16
是这样,不过做起来还是需要仔细的。比方不能把单引号和双引号里的字符串、regex、单行注释与多行注释里的关键字也算进去。有点语法分析器的味道。还是要花些时间的。
|
|
返回顶楼 | |
发表时间:2006-06-17
找到了:
http://rubyforge.org/projects/rubylexer/ 这个ruby库可以解析ruby源文件 成 一个个token 并可遍历。 原以为太复杂自已玩不转,试了试还可以。下面是解析出module结构树的代码: require "rubylexer.rb" f = open('d:\test\testrr6.rb') lexer=RubyLexer.new('d:\test\testrr6.rb', f) # module tree node class ModNode attr_reader :children, :mod_name def initialize(mod_name) @mod_name = mod_name @children = [] end def <<(child_mod) @children << child_mod end def dump(level) self.class.dump_level(level) print @mod_name print "\n" if not @children.empty? then for child in @children child.dump(level+1) end end end def self.dump_level(level) print '--' * level end end need_capture = false # whether should capture next VarNameToken as module name mod_stack = [] keyword_stack = [] root = ModNode.new('root') mod_stack.push root # iterate tokens until EoiToken===(tok=lexer.get1token) if tok.kind_of?(KeywordToken) then next if tok.has_end?.nil? if tok.has_end? == true then keyword_stack.push tok.ident elsif tok.ident == 'end' then ident = keyword_stack.pop mod_stack.pop if ident == 'module' end if tok.ident == 'module' then need_capture = true next end end if need_capture and tok.kind_of?(VarNameToken) then mod_name = tok.ident mod = ModNode.new(mod_name) mod_stack.last << mod mod_stack.push mod need_capture = false end end # dump the module tree root.dump(0) 执行结果是: 引用 root
--AA ----BB ----CC 3000行的watir行不行,很期待 |
|
返回顶楼 | |
发表时间:2006-06-17
原先考虑过这种方式:
s = open('d:\test\testrr6.rb').read module XX end XX.module_eval(s) ObjectSpace.each_object(Module) do |clazz| puts clazz.name if clazz.name.match(/^XX\:\:/) and not clazz.kind_of?(Class) end 执行结果是: 引用 XX::AA::CC
XX::AA::BB XX::AA d:\test\testrr6.rb 是待解析的ruby源文件。 对过滤出的clazz.name做下处理就会有收获,不过实在是.... 太土了 |
|
返回顶楼 | |
发表时间:2006-06-17
哈哈,非常谢谢找出了这个rubylexer,经过n秒钟之后,watir.rb的结果也正确地出来了:
引用 root
--Watir ----SupportsSubElements ----FormAccess ----OptionAccess ----CommonCollection 接下来,我看看怎样把class和method什么的都搞进去,我试了一下class,结果一不小心,把level搞乱了,再仔细调试调试。 另外,ObjectSpace的方法我也试了一下,关键是它会去执行一遍被分析的文件,有时候不是我们所希望的,呵呵。 liusong1111 写道 找到了:
http://rubyforge.org/projects/rubylexer/ 这个ruby库可以解析ruby源文件 成 一个个token 并可遍历。 原以为太复杂自已玩不转,试了试还可以。下面是解析出module结构树的代码: ... 执行结果是: 引用 root
--AA ----BB ----CC 3000行的watir行不行,很期待 |
|
返回顶楼 | |
发表时间:2006-06-20
呼呼,又知道了个新东东~
|
|
返回顶楼 | |