`
Hooopo
  • 浏览: 335112 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Ruby Tricks 大全

    博客分类:
  • Ruby
阅读更多

下面所有用法都是1.8.6里的,同时欢迎补充1.9和rails里面的tricks...


一.神奇的*
1.String#*

  "Hello!" * 2
 #=> "Hello!Hello!"
 


2.Array#*

   %w{one two three} * 2
  #=> ["one", "two", "three", "one", "two", "three"]
 


3.Shortcut for Array#join

   %w{one two three} * ", "
  #=> "one, two, three"
 

 

 %w{this is a test} * ", "                 # => "this, is, a, test"
 h = { :name => "Fred", :age => 77 }
 h.map { |i| i * "=" } * "&"              # => "age=77&name=Fred"
 


4.explore to enumerator

  a = %w{a b}
b = %w{c d}
[a + b]                              # => [["a", "b", "c", "d"]]
[*a + b]                             # => ["a", "b", "c", "d"]
 

 

 a = { :name => "Fred", :age => 93 }
[a]                                  # => [{:name => "Fred", :age =>93}]
[*a]                                 # => [[:name, "Fred"], [:age, 93]]
  

 

  a = %w{a b c d e f g h}
b = [0, 5, 6]
a.values_at(*b).inspect              # => ["a", "f", "g"]
 

 

  fruit = ["apple","red","banana","yellow"]
#=> ["apple", "red", "banana", "yellow"]

Hash[*fruit]    
#=> {"apple"=>"red", "banana"=>"yellow"}
 


5.*arg作为参数

 def my_method(*args)
  a, b, c, d = args
end 


6.Object#*

 match, text, number = *"Something 981".match(/([A-z]*) ([0-9]*)/)

 

  a, b, c = *('A'..'Z')

Job = Struct.new(:name, :occupation)
tom = Job.new("Tom", "Developer")
name, occupation = *tom



二.默认返回值.
Array#[]在index超出array范围时会默认返回nil(如果不想要默认值或是要扩展默认值可以用Array#fetch):

 irb(main):074:0> a = [1 ,2, 3]
=> [1, 2, 3]
irb(main):075:0> a[5]
=> nil
irb(main):076:0> a.fetch(8)
IndexError: index 8 out of array
        from (irb):76:in `fetch'
        from (irb):76
        from :0
irb(main):077:0> a.fetch(8,nil)
=> nil
irb(main):078:0> a.fetch(8,"index out of array!")
=> "index out of array!"
 


Hash也是在key不存在的时候返回默认值nil,也可以自己设置默认值或default_proc

 irb(main):008:0> hash = Hash.new{|hash,key| hash[key] = key.upcase if key.kind_o
f? String}
=> {}
irb(main):009:0> hash[1]
=> nil
irb(main):010:0> hash["key"]
=> "KEY"



Regex也可以有默认返回值:

 email = "Fred Bloggs <fred@bloggs.com>"
email.match(/<(.*?)>/)[1]            # => "fred@bloggs.com"
email[/<(.*?)>/, 1]                  # => "fred@bloggs.com"
email.match(/(x)/)[1]                # => NoMethodError 
email[/(x)/, 1]                      # => nil


当然最强大的还是method_missing了....

三.习以为常的single line method
在ruby里一行代码完成一个方法是很常见的....这主要归功于enumerable模块里面定义的神奇方法,还有if,unless等

 queue = []
%w{hello x world}.each do |word|
  queue << word and puts "Added to queue" unless word.length <  2
end
puts queue.inspect

# Output:
#   Added to queue
#   Added to queue
#   ["hello", "world"]



三元操作符:

 def is_odd(x)
  x % 2 == 0 ? false : true
end

 

 all?, any?, collect, detect, each_cons, each_slice,
 each_with_index, entries, enum_cons, enum_slice, enum_with_index,
 find, find_all, grep, include?, inject, inject, map, max, member?,
 min, partition, reject, select, sort, sort_by, to_a, to_set, zip

 

 

  p queue = %w{hello x world}.select { |word| word.length >= 2 }


四.其他
1.Format decimal amounts quickly

 money = 9.5
"%.2f" % money                       # => "9.50"


2.Surround text quickly

"[%s]" % "same old drag"             # => "[same old drag]"


3.Delete trees of files

require 'fileutils'
FileUtils.rm_r 'somedir'


4.Cut down on local variable definitions

 (z ||= []) << 'test'



5.Using non-strings or symbols as hash keys

 does = is = { true => 'Yes', false => 'No' }
does[10 == 50]                       # => "No"
is[10 > 5]                           # => "Yes"



6.Do something only if the code is being implicitly run, not required

 if __FILE__ == $0
  # Do something.. run tests, call a method, etc. We're direct.
end



7.Use ranges instead of complex comparisons for numbers

#让 if x > 1000 && x < 2000 歇菜吧
 year = 1972
puts  case year
        when 1970..1979: "70后"
        when 1980..1989: "80后"
        when 1990..1999: "90后"
      end



8.See the whole of an exception's backtrace

  def do_division_by_zero; 5 / 0; end
begin
  do_division_by_zero
rescue => exception
  puts exception.backtrace
end



9.Rescue blocks don't need to be tied to a 'begin'

 def x
  begin
    # ...
  rescue
    # ...
  end
end

 

 def x
  # ...
rescue
  # ...
end


10.Rescue to the rescue

 h = { :age => 10 }
h[:name].downcase                         # ERROR
h[:name].downcase rescue "No name"        # => "No name"


11.convert a Fixnum into any base up to 36

  >> 1234567890.to_s(2)
=> "1001001100101100000001011010010"

>> 1234567890.to_s(8)
=> "11145401322"

>> 1234567890.to_s(16)
=> "499602d2"

>> 1234567890.to_s(24)
=> "6b1230i"

>> 1234567890.to_s(36)
=> "kf12oi"



12.module_function

#让module更class
  module M
  def not!
    'not!'
  end
  module_function :not!
end

class C
  include M

  def fun
    not!
  end
end

M.not!     # => 'not!
C.new.fun  # => 'not!'
C.new.not! # => NoMethodError: private method `not!' called for #<C:0x1261a00>

 

 module M
  module_function

  def not!
    'not!'
  end

  def yea!
    'yea!'
  end
end


class C
  include M

  def fun
    not! + ' ' + yea!
  end
end
M.not!     # => 'not!'
M.yea!     # => 'yea!'
C.new.fun  # => 'not! yea!'


13.use  here document and any character you want to delimit strings 

 message = "My message"
contrived_example = "<div id=\"contrived\">#{message}</div>"
contrived_example = %{<div id="contrived-example">#{message}</div>}
contrived_example = %[<div id="contrived-example">#{message}</div>]
sql = %{
    SELECT strings 
    FROM complicated_table
    WHERE complicated_condition = '1'
}
sql = <<-SQL
    SELECT strings 
    FROM complicated_table
    WHERE complicated_condition = '1'
SQL


14.define_method

 ((0..9).each do |n|
    define_method "press_#{n}" do
      @number = @number.to_i * 10 + n
    end
  end


15.create Class at run time..

class Array
#define Array#rand
  def rand
    self.fetch Kernel.rand(self.size)
  end
end
class RandomSubclass < [Array, Hash, String, Fixnum, Float, TrueClass].rand

end

RandomSubclass.superclass # could output one of 6 different classes.


16.call private methods of class with send.

 class A

  private

  def my_private_method
    puts 'private method called'
  end
end

a = A.new
a.my_private_method # Raises exception saying private method was called
a.send :my_private_method # Calls my_private_method and prints private method called'


16.__END__

p DATA #=>#<File:tt.rb>
p DATA.read #=> "line1\nline2\nline3"

__END__
line1
line2
line3


17.FX和NS两位大神提供...目前不知道是做什么的.......

gets gets

 

 

分享到:
评论
15 楼 Hooopo 2010-04-02  
遍历数组时候加上进度条:
  def pretty_process(array, start = Time.now)
    total = array.to_a.size
    array.each_with_index do |item, index|
      yield(item) if block_given?
      count = index + 1
      avg = (Time.now - start) * 1.0 / (index + 1)
      eta = ((total - count)*avg)/60
      printf "\r%.2f %%, %d / %d, AVG: %f sec, ETA: %.0f min, PASSED: %d min ... ", count * 100.0 / total, count, total, avg, eta, (Time.now - start)/60
    end
  end

example:
irb(main):025:0> pretty_process((0..20)) do |i|
irb(main):026:1* sleep i
irb(main):027:1> end
28.57 %, 6 / 21, AVG: 2.503504 sec, ETA: 1 min, PASSED: 0 min ... 
14 楼 Hooopo 2009-12-27  
方法串联:
ruby 1.9里的Object#tap
http://moonbase.rydia.net/mental/blog/programming/eavesdropping-on-expressions
Rails里用returning
13 楼 ray_linn 2009-06-25  
night_stalker 写道
ray_linn 写道
俺倒不是看中短,而是它是标签语言,不知道加入<html>tag会如何。


html5 ? 感觉现在只能用 <script> 或者 XSLT 避免手动穷举 ……



XSLT是个啰嗦的技术。。。。我是觉得用这个来表达视图逻辑。。。感觉很不错。
12 楼 night_stalker 2009-06-25  
ray_linn 写道
俺倒不是看中短,而是它是标签语言,不知道加入<html>tag会如何。


html5 ? 感觉现在只能用 <script> 或者 XSLT 避免手动穷举 ……
11 楼 ray_linn 2009-06-25  
俺倒不是看中短,而是它是标签语言,不知道加入<html>tag会如何。
10 楼 night_stalker 2009-06-25  
扯些关于点点的: 方法与参数是右结合的,但四则运算符是左结合的,但运算符又是方法……
5 * 3 -  2  #=> 13
5.* 3 -  2  #=> 5 在1.8会得到一条警告,future version云云,但1.9就不警告了。
5 * 3.-  2  #=> 语法错误 …… unexpected tINTEGER, 1.8.6, 1.9.1, jruby1.3 均如此
5 * 3.- (2) #=> 5 加个括号就过去了,是不是很囧?……
5.* 3.-  2  #=> 5


ray_linn 写道
<dtml-comment>
   Zope-DTML version of 99 Bottles of beer (Bottles.html)
   See @ http://www.stowasser.tv/algo/Bottles.html
   Harald Stowasser
</dtml-comment>

<dtml-var standard_html_header>
   <dtml-in "_.range(99, 0, -1)" prefix=bottle>
     <dtml-var bottle_item> bottle(s) of beer on the wall<br>
     <dtml-var bottle_item> bottle(s) of beer.<br>
     Take one down, pass it around<br>
     <dtml-var "bottle_item-1"> bottle(s) of beer on the wall."<br><br>
   </dtml-in>
<dtml-var standard_html_footer>


ms这个也很强。


这个没有准确的实现需求,n == 0 时得用 no more,而且 no more 在句首和句中的大小写是不同的,最后一行必须买酒并 reset 99 (于是这个可以无穷的唱下去 ……)

虽然人家特意声明不是比短的,还是写了个相当短的版本 - - http://gist.github.com/135335
9 楼 ray_linn 2009-06-25  
<dtml-comment>
   Zope-DTML version of 99 Bottles of beer (Bottles.html)
   See @ http://www.stowasser.tv/algo/Bottles.html
   Harald Stowasser
</dtml-comment>

<dtml-var standard_html_header>
   <dtml-in "_.range(99, 0, -1)" prefix=bottle>
     <dtml-var bottle_item> bottle(s) of beer on the wall<br>
     <dtml-var bottle_item> bottle(s) of beer.<br>
     Take one down, pass it around<br>
     <dtml-var "bottle_item-1"> bottle(s) of beer on the wall."<br><br>
   </dtml-in>
<dtml-var standard_html_footer>


ms这个也很强。
8 楼 night_stalker 2009-06-25  
RednaxelaFX 写道
iya……说起语法自由,得要体会过“什么是自由”才好说必要不必要,有没有用云云。
兄弟们一定要看看Katahdin,传送门
同样是毕业设计,我的就弱小多了……|||| 好吧人家那是硕士毕设,我的是本科……


你的毕设…… 不能怪你,只能怪微软更新的太慢 ……

o,想用什么语言就载入对应的 .kat …… 无差别格斗流果然很 nb ……

我想起 programing paradigms for dummies 了。
如果把编程范式做成小包,按需要加载和卸载 …… 譬如并发部分就把"不确定性可观测"(observable undeterminism,这个词很量子 ……)这个内涵去掉,写完就加回来 ……

另外一个 nb 的地方就是编写标准库不用重复发明轮子了,直接挑其它语言里实现得最完美的 ……
7 楼 RednaxelaFX 2009-06-25  
iya……说起语法自由,得要体会过“什么是自由”才好说必要不必要,有没有用云云。
兄弟们一定要看看Katahdin,传送门
同样是毕业设计,我的就弱小多了……|||| 好吧人家那是硕士毕设,我的是本科……
6 楼 night_stalker 2009-06-25  
ray_linn 写道
这有点茴香豆的n种写法的味道了....

昨天学了Nemerle之后,觉得这些东西都可以是不必要的,让客户用Marco自由创造远比系统这些糖糖果果好多了。


嗯…… Nemerle 相当有才…… 有个好地方是模式匹配,譬如这个 (取自 99 杯马尿有几种写法
def beers(n) {
  | 0 => "no more bottles of beer"
  | 1 => "1 more bottle of beer"
  | _ => $"$n bottles of beer"
}


还有就是高级 eval —— 卫生宏(这个翻译一直让我觉得很囧) ……

不过 Ruby 做 Macro 也很强,因为 compile time ? runtime ? anytime
给客户用最好还是外部 DSL 吧(内部 DSL 最方便程序员使用),感觉内部 DSL 没必要把语法自由得太彻底 ……
5 楼 RednaxelaFX 2009-06-24  
跑题广告一下:爆栈是架设在ASP.NET的应用哦~
然后Jon Skeet在爆栈上超有名……经常能看到他的身影,特别是关于C#的问题的话

回到主题:楼主加上
gets gets
大法~跟NS学的一招
4 楼 Hooopo 2009-06-24  
爆栈,,,,这个网站不错..刚要订阅之,结果google reader 宕了.

1.9的正则支持Named Regexp Groups了很爽呀!!

要说变态看看人如其名的BrainFvck语言:
brainfvck语言是最简单的程序语言之一,只有8个有效字符,每个字符都有一个特定的含义。这8个字符控制一个指针在线性表里进行移动、读写、循环等操作。所有其它的字符都当作注释处理。
++++++++++[>+++++++++++<-]>-.
<+++[>----<-]>.<+++++[>++++<-]>-.--.
<+++[>---<-]>.<+++++[>+++<-]>.
>+++++[>+++++++++++<-]>-.+.<+++[>---<-]>.<<
<+++++[>----<-]>-.<+++[>++++<-]>.--.


Befunge:
Befunge语言 http://quadium.net/funge/spec98.html
Befunge的代码是二维的。它用 < > v ^这四个符号来控制一个指针在代码中移动,指针经过一个字符或数字则把它压入一个栈,四则运算符号的功能就是弹出栈顶两个元素进行计算后把结果压回去。用_ 和 | 来表示有条件的方向选择:当栈顶元素为0时向右(上)走,否则向左(下)走。& 和 ~分别用于读入数字或字符并压入栈,句号和逗号分别表示将栈顶元素作为整数或字符输出。最后以一个@符号表示程序结束。Befunge代码的注释不需要任何符号标明,你可以把注释写在程序的任何地方,只要运行时指针不会经过它就行了。你甚至可以把注释写在程序正中间,然后写代码时绕开注释写成一圈。Befunge的Hello World程序如下:
复制内容到剪贴板
代码:
                v
>v"Hello world!"0<
,:
^_25*,@
看一个复杂的例子。我找了一个算圆周率的Befunge程序,看起来非常壮观。
复制内容到剪贴板
代码:
aa*       v                +------------------------+
vp*9920p*9930<                | Pi generator in Bef-97 |
>:09a*pa*3/1+19a*p09a*g:09b*v |                      |
v_@# g*b90 p*b910        < p< | 7/2/1997, Kevin Vigor   |
>19a*g:+1-29b*p19a*g::09v    +------------------------+
v*a90g*b90*g*b91: _v#p*9<
>g-#v_ 2a*+\$   v   :$
>\1-aa*ga*+v   p
v1:/g*b92p*991:<   *
>9b*p29b*g*199*g\v9
v*b92p*aa-1g*990-<9
>g2-29b*p099*g1-:0^
v -9p*b92:%ag*991   <
>#v_ 299*g1+299*p>    ^
   >09b*g:#v_$v
v93p*b90-1<
>9*g199*ga/+.v
    v:g*992 <p*9 92-<
v_29b*g399*p ^
>09b*g:#v_v    1
vp*b90-1 < $    g
>199*g9`#v_'9,v    *
      >'0, >' ,299^

via:http://blog.xiaonei.com/GetEntry.do?id=283579963&owner=80288196
3 楼 ray_linn 2009-06-24  
这有点茴香豆的n种写法的味道了....

昨天学了Nemerle之后,觉得这些东西都可以是不必要的,让客户用Marco自由创造远比系统这些糖糖果果好多了。
2 楼 night_stalker 2009-06-24  
1.9 的源代码目录下 (n)make golf,产生的 goruby(.exe) 可以用很多诡异的写法。
譬如世界上最短的 hello world :
h

输出:Hello, world!

1.9 的正则命名分组,不需要 $1 .. $9 了,显式匹配命名组 =~ 会自动赋予局部变量,但是如果不是 /xxx/ =~ 'xxx',就不会产生这堆局部变量。再 但是,用 Regexp#match 产生的 matchdata 是一组类似 hash 的东西,键是命名的符号,值是匹配串,不好的一点就是这个东西虽然类似 hash,但不是 hash ……
re = /^
      \s*(?<template>   template\s*\<.*\>)?
      (?<modifiers>     (?:\s*\b\w+|\s*\"C\")*?)
      \s*\b(?<type>     \w+[\s\*\&\[\]]*)
      \s*\b(?<c2>       __declspec|__stdcall|__fastcall|WINAPI|CALLBACK|const|const\s\*|const\*)?
      \s*\b(?<name>     [\w\:]+)
      \s*\((?<params>   .*)\)
      \s*(?<const_tail> const)?
      \s*\{\s*
$/x 
m = re.match 'int hoho(){'
h = {}
m.names.each do |n|  # 这东西只有 each 可以用
  h[n] = m[n]
end


关于一些 trick,可以瞧瞧 爆栈这个帖爆栈那个帖 …… 充分利用 Perl 相容全局量和 golf 是挺不错的加密混淆手段 ……

引用
If anyone every uses any of those Ruby "hidden features" in code I have to work on, I will stab them in the eye.

x . x 不过貌似作这段评论的兄弟不是搞 ruby 的,所以眼睛保住了 ……
1 楼 Hooopo 2009-06-24  
hash作参数:
def m option={}
  arg2 = option[:arg2]
  arg1 = option[:arg1]
  print arg2,arg1
end

m :arg2 =>"Hi", :arg1 => "hooopo"
#Hihooopo

相关推荐

    Metaprogramming Ruby 2(Pragmatic,2014)

    Dig under the surface and explore Ruby's most advanced feature: a collection of techniques and tricks known as metaprogramming. In this book, you'll learn metaprogramming as an essential component of ...

    ruby cookbook

    We've even included a few silly tricks that were too cool to leave out, like how to blink the lights on your keyboard. &lt;br&gt; &lt;br&gt; The Ruby Cookbook is the most useful book yet written ...

    zip_tricks:针对Ruby的紧凑型ZIP文件编写阅读,适用于流应用程序

    zip_tricks 允许从Ruby输出流式,非倒带的ZIP文件。 最初是作为的精神继任者而写的,现在自豪地为引擎盖提供了动力。 允许您将ZIP存档写出到文件,套接字,字符串或数组中,而无需随时倒带。 可用于创建非常大的...

    rails magazine issue 4

    Oracle Tips and Tricks - **核心观点**:提供了一系列关于Oracle数据库的实用技巧。 - **重要性**:帮助开发者更高效地利用Oracle数据库的功能,提升数据库操作的性能和可靠性。 - **应用场景**:适用于使用Oracle...

    HTML5教程二

    - **作用**:`&lt;ruby&gt;` 和 `&lt;rt&gt;` 标签用于为汉字提供注音或拼音。这对于显示日语、汉语等语言中的注音非常有用。 - **示例**: ```html &lt;ruby&gt; 漢 ㄏㄢˋ &lt;/ruby&gt; ``` #### 四、总结 通过以上对HTML5新标记的...

    Regular Expressions Cookbook, SECOND EDITION

    介绍各种语言中,正则表达式的常用写法,很实用。... You’ll learn powerful new tricks, avoid flavor-specific gotchas, and save valuable time with this huge library of practical solutions.

    web-tips-and-tricks:一个用于捕获我们很棒的提示和技巧以及代码示例的存储库

    10. 开发工具与框架:了解如何使用开发环境(如VS Code、Sublime Text),以及前端框架(如React、Vue、Angular),后端框架(如Node.js、Django、Ruby on Rails),能够加速开发进程。 以上只是"web-tips-and-...

    Console-tricks:这里有一些惊人的控制台技巧

    使用命令行工具如`htmlq`(在Ruby的Nokogiri库中)或`xmllint`,可以在不借助图形界面的情况下解析和查询HTML文档。例如,`htmlq file.html '//*[@id="content"]'`可以提取ID为"content"的元素内容。 5. **多行...

    drupal-jmeter-tricks:在 Drupal 中使用 JMeter 的技巧

    Drupal JMeter 技巧 作者: 要求 JMeter 2.12+ [] 确保jmeter脚本在您的 PATH 和可执行文件中 JMeter 插件 [] Drupal 7 站点 测试站点设置 要设置一个简单的站点来测试这些 JMeter 脚本,请使用以下 Drush 命令 - ...

    Groovy in action

    Groovy, the brand-new language for the Java platform, brings to Java many of the features that have made Ruby popular. Groovy in Action is a comprehensive guide to Groovy programming, introducing Java...

    Go Web Programming (PDF, EPUB, MOBI)

    Sau Sheong Chang is Managing Director of Digital Technology at Singapore Power and an active contributor to the Ruby and Go communities. Table of Contents Part 1 Go and web applications Chapter 1 Go ...

    Fast Bit Gather, Bit Scatter and Bit Permutation Instructions for Commodity Microprocessors - 2008 (Hilewitz_JSPS_08)-计算机科学

    for Commodity MicroprocessorsYedidya Hilewitz & Ruby B. LeeReceived: 10 January 2007 /Revised: 25 February 2008 /Accepted: 12 April 2008 /Published online: 4 June 2008 # 2008 Springer Science + ...

    apache hbase reference guide

    - **Scripting with Ruby**(使用Ruby脚本):利用Ruby语言编写脚本来自动化HBase Shell的操作。 - **Running the Shell in Non-Interactive Mode**(非交互模式下运行Shell):通过命令行参数直接执行Shell命令,...

Global site tag (gtag.js) - Google Analytics