Ruby 大家来贴一下常用的小技巧吧

john1king · 2011年12月20日 · 最后由 zw963 回复于 2012年04月17日 · 6072 次阅读

因为是搞前端出生的,学 ruby 的时候最大感受是内建的方法非常好用,大部分简单的操作都可以一行搞定。不过也因为内建方法比较多,所以很多都是用的时候才查的,目前还不是很熟。时不时看都别人的代码,才发现自己之前写的代码里很多用内建的方法就可以很轻易的搞定,于是每次修改时都可以 delete 一大段代码...下面举几个例子,希望大家也能贴一贴,相信这类资料应该还是很有用的。

File.join("lib/","ruby","gem.rb")
#=> bin/ruby/gem.rb
# 好处是不用处理斜杠了


def print_args(a) 
    Array(a).each {|i| print i}
end
print_args [1,2,3] #=> 123
print_args 1 #=> 1
# 定义灵活的方法参数时经常用到



%w(a b c).map &:upcase
#=> ["A", "B", "C"]
# 可用于代替简单的代码块
["ruby","on","rails"].join(" ")

用于组合字符串

ary = ["a",1,"b",2]
Hash[*ary]  #=> {"a"=>1, "b"=>2}

将 Array 按顺序转换为 Hash 的键值

#3 楼 @Saito 那个都看过了,我经常用到的就是贴出来的那几个。

# coding:utf-8
# unicode转义
"" << 0x6f22 #=> 漢

写 Ruby 代码必用

class Object
  # returns instance methods of current object's class and its singleton methods
  def lm # abbr of local methods
    self.methods.sort - self.class.superclass.instance_methods
  end
end

https://github.com/mvj3/utils/blob/master/ruby/debug.rb#L1

选取位置是 3 倍数的字母

Array("a".."z").select.with_index {|x,i| i%3 == 2}
#=> ["c", "f", "i", "l", "o", "r", "u", "x"]

irb 中不打印返回值

conf.echo = false

在 Dir.glob 中匹配方括号

Dir.glob('[\[]ruby[\]]') #=> "[ruby]"

数组:["a","b","c"].delete("b") 或者 ["a","b","c"] - ["b"]

这帖子好!

#8 楼 @kevinhua 这是挖坟啊 #5 楼 @mvj3 还是 pry 好用,就是慢了点

#2 楼 @john1king 我是个新人 刚刚看书看到了 这个!感觉很好~

#10 楼 @john1king 不是挖坟,是这个 node 许久没有更新啦。

这个帖子好呀

['a', 'b', '', nil, 'c', 'c'].compact.uniq 
=> ["a", "b", "", "c"]


清理数组

(1..10).to_a
=> [1,2,3,4,5,6,7,8,9,10]

Rails 中

return if data.blank? # 等效于 return if data == nil return if data == ""

@john1king %w(a b c).map &:upcase 这个&:upcase 怎么理解呢

#15 楼 @ery 等效这个说法不恰当。。。

#17 楼 @hooopo 哈哈,那 什么样的说法,恰当那?

#18 楼 @ery

https://github.com/rails/rails/blob/master/activesupport/lib/active_support/core_ext/object/blank.rb
An object is blank if it's false, empty, or a whitespace string.

是包含关系:-)

之前的这种好贴,建议都挖出来才好。

#20 楼 @hooopo 有道理,措辞严谨,佩服,佩服,哈哈哈

#16 楼 @LinuxGit +1

%w(a b c).map &:upcase

这个&:upcase 怎么理解呢

split 是可以传两个参数的..

"hello".split("", 2)
 => ["h", "ello"] 

zip 是可以接受 block 的,不需要 each...

[1,2,3].zip([4,5,6], [7,8,9]){|x| p x}
[1, 4, 7]
[2, 5, 8]
[3, 6, 9]


%W是可以内插的~

item = 123
 => 123 
ree-1.8.7-2011.03 :023 > %W(1 2 3 4 #{item})
 => ["1", "2", "3", "4", "123"] 

"abc\n\n".scan /./m
 => ["a", "b", "c", "\n", "\n"]

这个本来觉得很正常。。。直到我见到 javascript 的正则

result ||= a 等效于 result = a if result.nil? 今天看到的。

#23 楼 @ery #16 楼 @LinuxGit %w(a b c).map &:upcase 全写是%w(a b c).map{ |obj| obj.upcase }

#29 楼 @camel 谢谢,这个语法 有木有 名字,或者有木有文档,谢谢

#30 楼 @ery &表示后面要接一个 Proc 对象,&a_proc 展开充当前面方法的代码块 如果&后面不是 Proc 对象,则调用其 to_proc 方法看看能不能生成一个 Proc 实例 核心类里有 to_proc 方法的是 Proc、Method 和 Symbol,这里就是:upcase.to_proc 的效果 实际生成这样的代码块: 1 :upcase.to_proc 2 {|obj,*args| obj.send(:upcase, *args) } 3 {|obj| obj.send(:upcase) } 4 {|obj| obj.upcase }

#29 楼 @camel 看了全写明白了,谢谢。

#28 楼 @LinuxGit result ||= a 应该等效于 result = result || a,不等效于 result = a if result.nil?

r = 123
p [(r ||= '123')] #=> [123]
p [(r = r || '123')] #=> [123]
p [(r = '123' if r.nil?)] #=> [nil]

看看返回值的结果是不同的。

实际上||=也不完全等同于拆开的=和||

A = 123
A ||= 456 # 无警告信息

A = 123
A = A || 456 # warning: already initialized constant A

||= 是经过优化的特殊运算符

34 楼 已删除

#34 楼 @victordong 这种写法不算好啊 最直观的就是写成 10.times.map { '1' }

ActiveSupport 里的:

数组分组

a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
# => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

a.in_groups_of(2)
# => [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, nil]]

a.in_groups(2)
# => [[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, nil]]


```


矩阵~~转制~~转置


````ruby
b = a.in_groups(2)
# => [[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, nil]]
> b.transpose
# => [[1, 7], [2, 8], [3, 9], [4, 10], [5, 11], [6, nil]]


``````` 

#23 楼 @ery 很早的一篇文章供参考 一段 Ruby 代码的解释 。这是 Symbol#to_proc 方法,新版本的 rails 没有定义这个,可能是其他包里有。

#1 楼 @huacnlee 组合字符串还可以用星号 *

["ruby","on","rails"] * " "

#37 楼 @zhangyuan Symbol#to_proc 的行为更像 lambda,参数处理不够灵活。试着在 String 上用 Proc 定义了一个 to_proc 方法


class String
  def to_proc
    Proc.new { |o, *args| o.send(self.to_sym, *args)}
  end
end

ary = [1, 2, 3].zip([3, 2, 1])

p ary.map(&:+)
# => in `+': wrong number of arguments(0 for 1) (ArgumentError)
p ary.map(&'+')
# =>[4, 4, 4]

也可以定义一个 to_proc 类方法 :)


class Hello
  def self.to_proc
    lambda { |w| new(w).say }
  end

  def initialize(word)
    @word = word
  end

  def say
    puts "Hello #{@word}!"
  end

end

%w(LZ LS LX).each(&Hello)

# =>
# Hello LZ!
# Hello LS!
# Hello LX!


#37 楼 @zhangyuan 谢谢 #31 楼 @FenRagwort 谢谢 偶懂了:)

#27 楼 @hooopo

"abc\n\n".scan /./m
 => ["a", "b", "c", "\n", "\n"]


放着 to_a 或 spilt 不用,用 scan, 这真有点大才小用了啊,而且用 scan 性能肯定差好多了。

"abc\n\n".chars.to_a
"abc\n\n".split("")


#33 楼 @FenRagwort

这位兄弟解释的太清楚了。赞一个~

需要 登录 后方可回复, 如果你还没有账号请 注册新账号