优雅的红宝石内衬

时间:2010-11-28 17:04:14

标签: ruby

我喜欢在Ruby中写这么多的原因之一是因为它非常能够通过一个衬里实现很多。

我喜欢:

@sentence = @sentence.split(' ').map!{|x| x = x[0..0].upcase << x[1..-1] }.join(' ')

它将每个单词的第一个字母大写,这不是最令人惊叹的,但非常有效。

你用Ruby看过或写过的最优雅的衬垫是什么?

7 个答案:

答案 0 :(得分:28)

你发布了oneliner:

@sentence = @sentence.split(' ').map!{|x| x = x[0..0].upcase << x[1..-1] }.join(' ')

但你误解了一些关于Ruby的事情。

首先,在地图调用中说x=不会影响地图调用之外的任何内容。该数组元素的新值是块的返回值。

其次,您不需要使用<<改变第一个字符串 - 创建新字符串的连接(使用+)是一个更好的选择。

第三,map!直接对split返回的数组进行更改。你想要做的是保持该数组不变(即使它不改变程序语义),并使用map返回带有映射结果的新数组。

所以你应该写:

@sentence = @sentence.split(' ').map{|x| x[0..0].upcase + x[1..-1] }.join(' ')

现在陈述x[0..0].upcase + x[1..-1]仍然非常迟钝。也许您应该用capitalize方法替换它,该方法已经将字符串的第一个字母更改为大写。 (请注意,它也会降低所有其他内容,这可能是您想要的,也可能不是。)

@sentence = @sentence.split(' ').map{|x| x.capitalize }.join(' ')

我可能会使用gsub!来就地更改字符串的部分内容,但这可能有点迟钝:

@sentence.gsub!(/\S+/){|x| x.capitalize}

还有一件事。如果块的唯一目的是在传递给块的对象上调用单个方法,则可以执行以下操作:

@sentence = @sentence.split(' ').map(&:capitalize).join(' ')

或修改我的gsub!版本:

@sentence.gsub!(/\S+/,&:capitalize)

答案 1 :(得分:1)

您可能需要查看Ruby Quiz #113

答案 2 :(得分:0)

好吧,我几天前写了一篇,但是不能用它作为答案,因为那时候问题已经结束了。 如果字符串不存在,它用字符串替换文件的第一行。

我希望有人也能改进这个:

ruby -i.bak -pe "print ($_!~/string/ && $.<2) ? \"string\n\":''" filename.txt

答案 3 :(得分:0)

Fibonacci序列生成器:

def fib n;n==0?[0]:n==1?[0,1]:(2..n-1).inject([0,1]){|a|a<<(a[-1]+a[-2])};end

同样如下:

def fib n;n<2?(0..n-1).to_a():(2..n-1).inject([0,1]){|a|a<<(a[-1]+a[-2])};end

答案 4 :(得分:0)

打开一个文件,写入文件,然后将其关闭一行:

File.open(File.join(Rails.root, 'lib', 'assets', 'file.txt'), 'a+') {|f| f.write("stuff"+"\n" }

我日常使用的大多数Ruby单行内容都使用andunlessif&&等,例如:

puts "x is nil!" if x.nil?

您可以互换使用unlessif,但如果使用正确,unless会显着提高可读性:

puts "bad input type!" unless ["bs", "cf", "is"].include?(type)

通常,最好的Ruby单行最终完成两到三行单行协同工作,通常与Ruby的变量“valence”系统结合使用(nilfalse唯一的“否定”):

def try_first(actual_index)
    x = [get_header(actual_index, 0), get_data(actual_index, 0)] unless get_header(actual_index, 0).blank?
    x = try_second(actual_index) if x[0].blank? #blank is a rails method, detects nil and empty strings and empty containers ([]) I think too
    puts "x is nil!" if x.nil?
    x
end

我说单行由几个单行组成,因为该方法本身在我的代码中的某个地方不到一行。我的许多方法只有一行:

def get_all_coords(type)
  eval("@#{type}_coords")
end

这就是你真正开始优雅的方式。将代码分解为单个方法。单线方法是完美的。

答案 5 :(得分:0)

绝对是GREP的模拟(Windows用户)。 [credit goes to Dave Thomas]

ruby -pe 'next unless $_ =~ /regexp/' < file.txt

答案 6 :(得分:0)

斐波那契数字肯定!

def fib(n, t = n < 2 ? n : fib(n-1) + fib(n-2)) t; end