Open12

ruby学習しての感想 ~2024/08/17

toketoke

.included_modulesメソッド便利。
継承しているモジュールが分かる。

[5] pry(main)> Array.included_modules
=> [ActiveSupport::ToJsonWithActiveSupportEncoder,
 JSON::Ext::Generator::GeneratorMethods::Array,
 MessagePack::CoreExt,
 Enumerable,
 ActiveSupport::Dependencies::ZeitwerkIntegration::RequireDependency,
 ActiveSupport::ToJsonWithActiveSupportEncoder,
 PP::ObjectMixin,
 ActiveSupport::Tryable,
 ActiveSupport::Dependencies::Loadable,
 JSON::Ext::Generator::GeneratorMethods::Object,
 Kernel]
toketoke

rubyではオブジェクト自身が使えるインスタンスメソッドや、クラスが使えるインスタンスメソッドや、継承しているモジュールを調べることができる

toketoke

pやputsメソッドはKernelモジュールの特異メソッドとして定義されている。
なので、Kernelというレシーバーを指定しても実行できるし、Kernelモジュールは他のクラスにもincludeされているので、インスタンスメソッドとしても使える

[12] pry(main)> Kernel.p 12
12
=> 12
[13] pry(main)> Kernel.puts 12
12
=> nil
toketoke

クラスが継承している親クラスをその親のクラス + ミックスインしている全てのモジュールはancestorsメソッドで調べることができる

[15] pry(main)> String.ancestors
=> [ActiveSupport::ToJsonWithActiveSupportEncoder,
 String,
 JSON::Ext::Generator::GeneratorMethods::String,
 MessagePack::CoreExt,
 Comparable,
 ActiveSupport::Dependencies::ZeitwerkIntegration::RequireDependency,
 ActiveSupport::ToJsonWithActiveSupportEncoder,
 Object,
 PP::ObjectMixin,
 ActiveSupport::Tryable,
 ActiveSupport::Dependencies::Loadable,
 JSON::Ext::Generator::GeneratorMethods::Object,
 Kernel,
 BasicObject]
toketoke

rubyのprocは関数の中で保有している値を元に何かをして欲しい時に使えそう。

rails的なscopeだとただのjs的なアロー関数使ってます感だけど、
メソッドの中で特定のメソッド呼んで処理させる的なコールバック的な事をやりたい際に向いてそう

toketoke

rubyで意識することは全てのオブジェクトが何かしらのクラスのオブジェクトを理解することか。

クラスによって使えるメソッドは決まってるから、もしできない事があるならオブジェクトを型変換したり、includeとかして足す感じなのかな

toketoke

出来上がったオブジェクトに対してto_hする方が、
mapの中でfindで探すとかよりも早い気がする

toketoke

こうらしい。
配列の方が単純なイメージしたけど、

toketoke

3万件の2つの要素がある多重配列を作るのと、
それをハッシュ構造で作るのだと、どっちが早い?

rubyだと高速にハッシュを作成できるらしい。
しかし配列の方が早いと予測してきた。

require 'benchmark'

# データの準備
data = (1..30000).map { |i| [i, "value#{i}"] }

# 配列の作成
array_time = Benchmark.realtime do
  array = data.map { |k, v| [k, v] }
end

# ハッシュの作成
hash_time = Benchmark.realtime do
  hash = data.to_h
end

puts "Array creation time: #{array_time} seconds"
puts "Hash creation time: #{hash_time} seconds"

toketoke

こんな感じのコードで試したんだけど、そこまで遅くなかった。
SQLでorder指定の方が遅い気がする

require 'benchmark'

# データの準備
data = (1..30000).map { |i| [i, "value#{i}"] }
hash = {}
# ハッシュの作成
hash_time = Benchmark.realtime do
  hash = data.to_h
end

puts "Hash creation time: #{hash_time} seconds"
p hash
toketoke

そんなに遅いようには思えない。
配列にpushして行ってもそこまで遅くない。
SQLよりかはマシ

benchmarkライブラリ便利だなー

require 'benchmark'

# データの準備
data = (1..30000).map { |i| [i, "value#{i}"] }

array = []
hash = {}
# 配列の作成
array_time = Benchmark.realtime do
  array << data.map { |k, v| [k, v] }
end

# ハッシュの作成
hash_time = Benchmark.realtime do
  hash = data.to_h
end

puts "Array creation time: #{array_time} seconds"
puts "Hash creation time: #{hash_time} seconds"
toketoke

ここにもあったけど便利で簡単だなー
module Benchmark (Ruby 3.3 リファレンスマニュアル)

ガンガン測定して行こー

require 'benchmark'

n = 50000
Benchmark.bm do |x|
  x.report { for i in 1..n; a = "1"; end }
  x.report { n.times do   ; a = "1"; end }
  x.report { 1.upto(n) do ; a = "1"; end }
end

#=>
#
#     user     system      total        real
# 1.033333   0.016667   1.016667 (  0.492106)
# 1.483333   0.000000   1.483333 (  0.694605)
# 1.516667   0.000000   1.516667 (  0.711077)