Ruby中您最喜欢的功能是什么?

时间:2008-12-25 16:48:29

标签: ruby

.NETJava也提出了类似的问题,但Ruby没有。那么, Ruby中你最喜欢的功能是什么?

您可能也对hidden features of Ruby感兴趣。

请具体说明并在每个答案中发布一个功能。解释或代码示例会很好。

13 个答案:

答案 0 :(得分:12)

块非常好:

my_array.each { |element| print element } 

#...

File.open("foo.txt") do |file|
  # do stuff with file
end

答案 1 :(得分:7)

这是一个非常小的,几乎无关紧要的功能,但我真的很喜欢这个结构:

var ||= "default"

如果尚未设置var,则会将"default"设置为默认值(var),如果已设置var,则保留当前值new_val = old_val || "default" 。我喜欢紧凑的语法。

同样,我可以这样做:

||

也设置默认值。

一般来说,我喜欢所有Ruby表达式都返回一个值,因此我可以使用像{{1}}这样的运算符来编写简短的紧凑语句。

答案 2 :(得分:3)

我喜欢能够调用没有括号的函数,并且函数返回最后一次计算的表达式。

前者节省了大量不必要的括号,使代码更容易阅读。

后者有时会变得非常混乱,但它对于单行(尤其是逻辑)函数来说非常棒。

答案 3 :(得分:3)

可枚举!关于为什么它很棒的一些例子。

a = ['foo', 'bar', 'baz']

a.delete_if {|i| i =~ /^f/ }
# vs
new = []
a.each do |i|
  if i !~ /^f/
    new << i
  end
end



a.select {|i| i =~ /^f/ }
# vs
new = []
a.each do |i|
  if i =~ /^f/
    new << i
  end
end


a.detect {|i| i =~ /^f/ }
# vs
a.each do |i|
  if i =~ /^f/
    return i
  end
end

能够通过'select','detect','delete_if'等直接说出你想要实现的东西,而不是循环并手动完成所有事情,这是非常好的。 Enumerable使得在阅读代码时更容易输入和更容易理解。

答案 4 :(得分:2)

这些类是对象,new是类中的方法:

c = Array
a = c.new()

我喜欢案件的运作方式。它在每个case值上调用===并返回一个值:

if(0 <= age &&  age <= 10){
  x = "kid"
}else if(10 <= age && age <= 80)
  x = "person"
}else if(80 <= age && age <= 99)
  x = "old"
}else{
  x = "???"
}

=>

x = case age
  when 0..10:  "kid"
  when 10..80: "person"
  when 80..99: "old"
  default:     "???"
end

这是有效的,因为范围(0..10)有一个===方法来检查某些东西是否在范围内:(5..10)=== 6 ==&gt;真正。正则表达式也支持===,所以你可以这样做:

case str
  when /regex1/: ...
  when /regex2/: ...
  ...
end

您甚至可以为自己的对象编写===方法。

答案 5 :(得分:2)

另一个不错的功能:确保。它就像最后一样,但在Ruby中有一个简洁的语法。你有这样的东西时可以使用它:

def foo(x)
  return_value = bar(x)
  dosomething(x)
  return return_value
end

=>    

def foo(x)
  bar(x)
ensure
  dosomething(x)
end

答案 6 :(得分:2)

开放课程是我最喜欢的一个。例如,这个:

# try.rb

class TryObjectMock
  public_instance_methods.reject { |x| x =~ /^__/ }.each { |x| undef_method(x) }

  def method_missing(symbol, *args)

  end
end

class Object
  def try
    self.nil? ? TryObjectMock.new : self 
  end
end

使处理nil能够对象的代码更清晰:

irb(main):001:0> require 'try'
irb(main):002:0> puts "5".try.to_i
5
irb(main):003:0> puts nil.try.to_i
nil
irb(main):004:0> puts [1, 2].try.find { |x| x == 2 }.try + 3
5
irb(main):005:0> puts [1, 2].try.find { |x| x == 3 }.try + 3
nil
irb(main):006:0> puts nil.try.find { |x| x == 3 }.try + 3
nil
irb(main):007:0>

它避免了很多if-else s:

irb(main):007:0> a = [1, 2]
irb(main):008:0> puts(if a
irb(main):009:2>        if b = a.find { |x| x == 2 }
irb(main):010:3>          b + 3
irb(main):011:3>        end
irb(main):012:2>      end)
5
irb(main):013:0> c = "5"
irb(main):014:0> puts(c ? c.to_i : nil)
5

这个技巧通过为对象空间中的每个类定义方法try来实现。当它被调用时,当对象为nil时,它返回一个特殊对象(nilNilClass的实例,它是Object的子类!)或对象本身否则。对于调用的每个方法(通过空nil实现),该特殊对象只返回method_missing。请注意,它也适用于运算符,因为它们是左侧对象的方法。

答案 7 :(得分:2)

非布尔值的布尔运算符。

&&||

两者都返回最后一个表达式的值。通过短路,这些可以创造出方便的捷径。为了短路检测的目的,它们将任何非零或假的值视为真。

示例:

a = b || c 

仅当b为nil或false时才将c的值赋给a。

a = b && c

将c的值指定为只有b不是nil或false,否则指定b。

此行为说明了已提及的||=

然而,&&=运算符却没有得到同样的爱。

string &&= string + "suffix"

相当于

if string
  string = string + "suffix"
end

如果变量未定义,那么破坏性操作非常方便。

答案 8 :(得分:2)

我不可能只选择一个,但第一个想到的是splat:*

基本上它可以让你把数组转换成参数列表,反之亦然,让你做这样的事情:

odds  = [1, 3, 7]
evens = [2, 4, 6]

case 4
  when *odds  then "odd!"
  when *evens then "even!"
end
# => "even!"


arr = [ :a, 1, :b, :2 ]    
Hash[*arr] # => { :a => 1, :b => 2 }


a, b, c = *(1..3)
puts a # => 1
puts b # => 2
puts c # => 3


a = 1, *[2, 3] # => [1, 2, 3]


# And of course...
def f(*args)
  puts args
end

f 1, 2, 3 # => [1, 2, 3]

答案 9 :(得分:1)

问号/感叹号命名惯例

方法调用后通常不需要parens

的rubygems

好的,我想这是一些最爱:)

答案 10 :(得分:1)

我最喜欢的功能(最近处理Soap4R之后)可能是可用的内省。这两种方法特别有用:

public_methods - 返回对象上所有方法的列表。当您试图找出可以对某些事情做些什么时,从调试器或irb中获得超级有用。 (紧随其后

instance_variables - 返回对象上所有实例变量的列表。

这里有各种其他好东西:http://www.ruby-doc.org/core/classes/Object.html

答案 11 :(得分:1)

instance_eval和class_eval:)

答案 12 :(得分:1)

if语句也是表达式,因此块的最后一行返回一个值。允许使用以下代码:

my_var = if some_var.is_true?
           if some_other_var > 8
             1
           else
             23
           end
         else
           5
         end

此处,my_var最终会得到值1,23或5,具体取决于条件的评估方式。