`
RednaxelaFX
  • 浏览: 3018438 次
  • 性别: Icon_minigender_1
  • 来自: 海外
社区版块
存档分类
最新评论

Ruby方法名简写的trick……(外加方法名缩写的trick)

    博客分类:
  • Ruby
阅读更多
刚才跟NS老兄聊的时候他给我看了段代码:
night_stalker 写道
看到一个方法简写 trick
irb(main):004:0> "Hello World".spl
=> ["Hello", "World"]
irb(main):005:0> "Hi there Daniel".sp
=> ["Hi", "there", "Daniel"]
irb(main):006:0> "Hi there Daniel".s
=> "Ambigous abbreviation s ->  select, slice, sub!, squeeze, send, split,
size, strip, succ!, squeeze!, sub, slice!, scan, sort, swapcase, swapcase!,
sum, singleton_methods, succ, sort_by, strip!"


我正无聊,回答说这实现起来不难,就模仿那段代码的行为估摸了一个出来。不过这么简单的东西我一开始居然写错了,郁闷 T T
class Object
  def method_missing(name, *args, &block)
    candidates = methods.grep /^#{name}/
    raise "undefined method `#{name}' for #{self}:#{self.class}" if candidates.empty?
    raise "Ambigous abbreviation #{name} -> #{candidates.join ', '}" unless candidates.one?
    method(candidates.first).call *args
  end
end

一开始忘写method,直接拿candidates.first[*args]就调用了……找起错来还挺麻烦的 T T

另外,还可以尝试匹配下划线分隔的名字中的缩写,像是把end_with?缩写成ew。在Ruby 1.9上可以这样写:
class Object
  def method_missing(name, *args, &block)
    candidates = methods.grep /^#{name}/
    if candidates.empty?
      downcase_name = name.to_s.downcase
      candidates = methods.map{|m| m.downcase}.reject{|m| m[0] != name[0]}.select do |m|
        downcase_name == m.to_s.sub(/[?!=]$/, '').split(/_/).map{|p| p[0]}.join
      end
    end
    raise "undefined method `#{name}' for #{self}:#{self.class}" if candidates.empty?
    raise "Ambigous abbreviation #{name} -> #{candidates.join ', '}" unless candidates.one?
    method(candidates.first).call *args
  end
end

主要是Ruby 1.9之前String#[]返回的是字节的值,是个Fixnum,要转成字符还得用Fixnum#chr,比较烦……要在Ruby 1.8上运行这代码的话,要在[0]后面都加上.chr。

E:\build_area\ruby191\bin>irb
irb(main):001:0> class Object
irb(main):002:1>   def method_missing(name, *args, &block)
irb(main):003:2>     candidates = methods.grep /^#{name}/
irb(main):004:2>     if candidates.empty?
irb(main):005:3>       candidates = methods.select do |m|
irb(main):006:4*         name.to_s.downcase == m.to_s.sub(/[?!=]$/, '').split(/_/).map {|p| p[0]}.join.downcase
irb(main):007:4>       end
irb(main):008:3>     end
irb(main):009:2>     raise "undefined method `#{name}' for #{self}:#{self.class}" if candidates.empty?
irb(main):010:2>     raise "Ambigous abbreviation #{name} -> #{candidates.join ', '}" unless candidates.one?
irb(main):011:2>     method(candidates.first).call *args
irb(main):012:2>   end
irb(main):013:1> end
=> nil
irb(main):014:0> 'alpha'.ew 'a'
=> true
irb(main):015:0> 'alpha'.end_with? 'a'
=> true


结束语:人不能太无聊了 XDD
分享到:
评论
4 楼 RednaxelaFX 2009-04-25  
night_stalker 写道
着色那个最好加上
require 'win32/Console/ANSI'

不过 tab 后一些字符会删不掉 -_-

对高亮没啥追求,能tab就行……
require 'irb/completion'之后,打了3.然后按tab,出来一长串列表……不停按回车然后总是错过后面再出来的3. T T

昨晚想说的忘说了。根据方法名的每个单词开头字母组成的缩写来搜索这个,不是我突然想到的,而是最近Visual Studio 2010和MonoDevelop 2.0都宣传它们实现了类似的搜索符号的功能,深深的印在了我的娱乐列表上……
3 楼 night_stalker 2009-04-25  
着色那个最好加上
require 'win32/Console/ANSI'

不过 tab 后一些字符会删不掉 -_-
2 楼 RednaxelaFX 2009-04-25  
Hooopo 写道
继中文编程之后,又一娱乐实践。。。

跟NS老兄聊天就总是能找到乐子,呵呵~

不过说真的,在Windows上用默认配置的、裸的irb难道你们不会觉得不爽么?如果能用缩写来打方法名有时候不会很爽么……
至少把这个配置给弄上,不然太落伍了 XDD
要是不在Windows上的话,还有些古老的办法可以让irb“亮”起来……
1 楼 Hooopo 2009-04-25  
继中文编程之后,又一娱乐实践。。。

相关推荐

Global site tag (gtag.js) - Google Analytics