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:37

Wow, no one mentioned the flip flop operator:

1.upto(100) do |i|
  puts i if (i == 3)..(i == 15)
end
查看更多
狗以群分
3楼-- · 2019-01-04 04:38

create an array of consecutive numbers:

x = [*0..5]

sets x to [0, 1, 2, 3, 4, 5]

查看更多
兄弟一词,经得起流年.
4楼-- · 2019-01-04 04:39

From Ruby 1.9 Proc#=== is an alias to Proc#call, which means Proc objects can be used in case statements like so:

def multiple_of(factor)
  Proc.new{|product| product.modulo(factor).zero?}
end

case number
  when multiple_of(3)
    puts "Multiple of 3"
  when multiple_of(7)
    puts "Multiple of 7"
end
查看更多
冷血范
5楼-- · 2019-01-04 04:39

One of the cool things about ruby is that you can call methods and run code in places other languages would frown upon, such as in method or class definitions.

For instance, to create a class that has an unknown superclass until run time, i.e. is random, you could do the following:

class RandomSubclass < [Array, Hash, String, Fixnum, Float, TrueClass].sample

end

RandomSubclass.superclass # could output one of 6 different classes.

This uses the 1.9 Array#sample method (in 1.8.7-only, see Array#choice), and the example is pretty contrived but you can see the power here.

Another cool example is the ability to put default parameter values that are non fixed (like other languages often demand):

def do_something_at(something, at = Time.now)
   # ...
end

Of course the problem with the first example is that it is evaluated at definition time, not call time. So, once a superclass has been chosen, it stays that superclass for the remainder of the program.

However, in the second example, each time you call do_something_at, the at variable will be the time that the method was called (well, very very close to it)

查看更多
Deceive 欺骗
6楼-- · 2019-01-04 04:39

Fixnum#to_s(base) can be really useful in some case. One such case is generating random (pseudo)unique tokens by converting random number to string using base of 36.

Token of length 8:

rand(36**8).to_s(36) => "fmhpjfao"
rand(36**8).to_s(36) => "gcer9ecu"
rand(36**8).to_s(36) => "krpm0h9r"

Token of length 6:

rand(36**6).to_s(36) => "bvhl8d"
rand(36**6).to_s(36) => "lb7tis"
rand(36**6).to_s(36) => "ibwgeh"
查看更多
唯我独甜
7楼-- · 2019-01-04 04:40

I'm late to the party, but:

You can easily take two equal-length arrays and turn them into a hash with one array supplying the keys and the other the values:

a = [:x, :y, :z]
b = [123, 456, 789]

Hash[a.zip(b)]
# => { :x => 123, :y => 456, :z => 789 }

(This works because Array#zip "zips" up the values from the two arrays:

a.zip(b)  # => [[:x, 123], [:y, 456], [:z, 789]]

And Hash[] can take just such an array. I've seen people do this as well:

Hash[*a.zip(b).flatten]  # unnecessary!

Which yields the same result, but the splat and flatten are wholly unnecessary--perhaps they weren't in the past?)

查看更多
登录 后发表回答