Hidden features of Ruby

2019-01-04 04:31发布

Continuing the "Hidden features of ..." meme, let's share the lesser-known but useful features of Ruby programming language.

Try to limit this discussion with core Ruby, without any Ruby on Rails stuff.

See also:

(Please, just one hidden feature per answer.)

Thank you

30条回答
疯言疯语
2楼-- · 2019-01-04 04:55

Peter Cooper has a good list of Ruby tricks. Perhaps my favorite of his is allowing both single items and collections to be enumerated. (That is, treat a non-collection object as a collection containing just that object.) It looks like this:

[*items].each do |item|
  # ...
end
查看更多
Viruses.
3楼-- · 2019-01-04 04:55

Destructuring an Array

(a, b), c, d = [ [:a, :b ], :c, [:d1, :d2] ]

Where:

a #=> :a
b #=> :b
c #=> :c
d #=> [:d1, :d2]

Using this technique we can use simple assignment to get the exact values we want out of nested array of any depth.

查看更多
来,给爷笑一个
4楼-- · 2019-01-04 04:58

The "ruby" binary (at least MRI's) supports a lot of the switches that made perl one-liners quite popular.

Significant ones:

  • -n Sets up an outer loop with just "gets" - which magically works with given filename or STDIN, setting each read line in $_
  • -p Similar to -n but with an automatic puts at the end of each loop iteration
  • -a Automatic call to .split on each input line, stored in $F
  • -i In-place edit input files
  • -l Automatic call to .chomp on input
  • -e Execute a piece of code
  • -c Check source code
  • -w With warnings

Some examples:

# Print each line with its number:
ruby -ne 'print($., ": ", $_)' < /etc/irbrc

# Print each line reversed:
ruby -lne 'puts $_.reverse' < /etc/irbrc

# Print the second column from an input CSV (dumb - no balanced quote support etc):
ruby -F, -ane 'puts $F[1]' < /etc/irbrc

# Print lines that contain "eat"
ruby -ne 'puts $_ if /eat/i' < /etc/irbrc

# Same as above:
ruby -pe 'next unless /eat/i' < /etc/irbrc

# Pass-through (like cat, but with possible line-end munging):
ruby -p -e '' < /etc/irbrc

# Uppercase all input:
ruby -p -e '$_.upcase!' < /etc/irbrc

# Same as above, but actually write to the input file, and make a backup first with extension .bak - Notice that inplace edit REQUIRES input files, not an input STDIN:
ruby -i.bak -p -e '$_.upcase!' /etc/irbrc

Feel free to google "ruby one-liners" and "perl one-liners" for tons more usable and practical examples. It essentially allows you to use ruby as a fairly powerful replacement to awk and sed.

查看更多
唯我独甜
5楼-- · 2019-01-04 04:58

Fool some class or module telling it has required something that it really hasn't required:

$" << "something"

This is useful for example when requiring A that in turns requires B but we don't need B in our code (and A won't use it either through our code):

For example, Backgroundrb's bdrb_test_helper requires 'test/spec', but you don't use it at all, so in your code:

$" << "test/spec"
require File.join(File.dirname(__FILE__) + "/../bdrb_test_helper")
查看更多
倾城 Initia
6楼-- · 2019-01-04 04:59

One final one - in ruby you can use any character you want to delimit strings. Take the following code:

message = "My message"
contrived_example = "<div id=\"contrived\">#{message}</div>"

If you don't want to escape the double-quotes within the string, you can simply use a different delimiter:

contrived_example = %{<div id="contrived-example">#{message}</div>}
contrived_example = %[<div id="contrived-example">#{message}</div>]

As well as avoiding having to escape delimiters, you can use these delimiters for nicer multiline strings:

sql = %{
    SELECT strings 
    FROM complicated_table
    WHERE complicated_condition = '1'
}
查看更多
仙女界的扛把子
7楼-- · 2019-01-04 04:59

Warning: this item was voted #1 Most Horrendous Hack of 2008, so use with care. Actually, avoid it like the plague, but it is most certainly Hidden Ruby.

Superators Add New Operators to Ruby

Ever want a super-secret handshake operator for some unique operation in your code? Like playing code golf? Try operators like -~+~- or <--- That last one is used in the examples for reversing the order of an item.

I have nothing to do with the Superators Project beyond admiring it.

查看更多
登录 后发表回答