Help us understand the problem. What is going on with this article?

Hashのこんな使い方

More than 5 years have passed since last update.

RubyのHash、僕が知らなかっただけかもしれないですが、便利な使い方を発見。

initializeでブロックを渡す

ブロックを渡すと、 [] でアクセスした時にそのブロックが評価されるようになります。
使用例:

require 'uri'
uri = Hash.new do |hash, key|
  puts 'evaluated'
  hash[key] = URI.parse(key) rescue nil
end

host = uri['http://google.com'].host
#=> evaluated
puts host
#=> google.com

host = uri['http://google.com'].host
#=>何も出力されない
puts host
#=> google.com

p uri
#=> {"http://google.com"=>#<URI::HTTP:0x0000010718edb0 URL:http://google.com>}

key に対するアクセスに対して、自身にその key がセットされていなければブロックを評価、ブロックには自身の hash も渡されるので、 hash にsetすることもできる。

コレ結構便利で、例えばDBへの処理を、同じクエリに対して複数行わないように結果をキャッシュするといった時、

require 'mysql2'

client = Mysql2::Client.new

db = Hash.new do |data, sql|
  data[sql] = client.query(sql).to_a
end

# example
# 一回目はクエリが走る
user = db['SELECT * from users where id = 1']

# 二回めはクエリが走らない
user = db['SELECT * from users where id = 1']

みたいなことが可能です。

もう1年くらいrubyやってるのに知らなかった…

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away