开发者

Elegant Ruby one liners [closed]

开发者 https://www.devze.com 2023-01-27 12:50 出处:网络
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references,or expertise, but this question will likely solicit debate, a
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, poll开发者_如何转开发ing, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance. Closed 10 years ago.

One of the reasons I like writing in Ruby so much is because it is very capable of achieving a lot via one liners.

I like:

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

It capitalizes the first letter of each word, which is not the most stunning, but quite efficient.

What's the most elegant one liner you have seen or written with Ruby?


You posted the oneliner:

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

But you misunderstand a couple things about Ruby.

First off, saying x= in a map call doesn't affect anything outside of the map call. The new value of that array element is the value returned by the block.

Secondly, you don't need to mutate the first string with << -- a concatenation that creates a new string (using +) is a much better option.

Thirdly, map! makes changes directly to the array returned by split. What you want to do is leave that array untouched (even though it doesn't change program semantics), and return a new array with the mapped results, by using map.

So you should have written:

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

Now the statement x[0..0].upcase + x[1..-1] is still very obtuse. Maybe you should replace it with the capitalize method, which already changes the first letter of the string to uppercase. (Note that it also downcases all of the others, which may or may not be what you want.)

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

I'd probably use gsub! to change parts of the string in-place, but that's probably a little obtuse:

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

One more thing. If the only purpose of a block is to call a single method on the object passed to the block, you can do the following:

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

or to modify my gsub! version:

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


You might want to take a look at Ruby Quiz #113.


Open a file, write to it, and close it in one line:

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

Most of my best Ruby one-liners in every day scripts utilize and, unless, if, && and so forth, like:

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

You can use unless and if interchangeably, but unless significantly improves readability when used correctly:

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

Oftentimes, the best Ruby one-liners are ultimately done in two to three lines of one-liners working together, often in conjunction with Ruby's "valence" system for variables (nil and false are the only "negatives"):

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

I say one-liners composed of several one-liners because that method itself is less than a one-liner somewhere else in my code. Many of my methods just one line though:

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

That's how you really start to get elegant. Break out code into individual methods. One-line methods are perfect.


The Fibonacci number for sure!

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


Well, I wrote one a few days ago but couldn't use it as an answer because the question was closed by then. It replaces the first line of a file with a string if the string isn't already there.

I hope someone improves on this one also:

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


Fibonacci sequence generator:

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

same as:

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


Absolutely this emulation of GREP (Windows user). [credit goes to Dave Thomas]

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

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号