ためすう
Ruby で private_class_method を使ってみる
2019-07-16やったこと
Ruby で private_class_method を使ってみます。
確認環境
$ ruby --version
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin17]
調査
ruby-private-class-method.rb
class Sample
def self.hoge
p __method__
end
def self.hoge2
p __method__
end
def hoge3
p __method__
end
private_class_method :hoge
end
検証
$ irb
...
irb(main):007:0> require './ruby-private-class-method'
=> true
irb(main):008:0> Sample.hoge
Traceback (most recent call last):
4: from /Users/hogehoge/.rbenv/versions/2.6.3/bin/irb:23:in `<main>'
3: from /Users/hogehoge/.rbenv/versions/2.6.3/bin/irb:23:in `load'
2: from /Users/hogehoge/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/irb-1.0.0/exe/irb:11:in `<top (required)>'
1: from (irb):8
NoMethodError (private method `hoge' called for Sample:Class)
Did you mean? hoge2
irb(main):009:0> Sample.hoge2
:hoge2
=> :hoge2
irb(main):010:0> Sample.new.hoge3
:hoge3
=> :hoge3
参考
Ruby で uniq を使ってみる
2019-07-15やったこと
Ruby で uniq を使ってみます。
確認環境
$ ruby --version
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin17]
調査
$ irb
irb(main):001:0> p [1, 1, 1].uniq
[1]
=> [1]
irb(main):002:0> p [1, 2, 3, '1'].uniq
[1, 2, 3, "1"]
=> [1, 2, 3, "1"]
irb(main):003:0> p [1, 2, 3, '1'].uniq {|n| n.to_s}
[1, 2, 3]
=> [1, 2, 3]
参考
Ruby で insert を使ってみる
2019-07-15やったこと
Ruby で insert を使ってみます。
確認環境
$ ruby --version
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin17]
調査
test.rb
ary = [
{a: 1},
{a: 2},
{a: 3},
]
p ary
ary.insert(1, {a: 999})
p ary
ary.insert(10, {a: 10})
p ary
出力結果
$ ruby test.rb
[{:a=>1}, {:a=>2}, {:a=>3}]
[{:a=>1}, {:a=>999}, {:a=>2}, {:a=>3}]
[{:a=>1}, {:a=>999}, {:a=>2}, {:a=>3}, nil, nil, nil, nil, nil, nil, {:a=>10}]
参考
Ruby で tap を使ってみる
2019-07-14やったこと
Ruby で tap を使ってみます。
確認環境
$ ruby --version
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin17]
調査
メソッドチェインの途中で直ちに操作結果を表示するために メソッドチェインに “入り込む” ことが、このメソッドの主目的です。
$ irb
irb(main):001:0> (1..10).tap {|x| puts "original: #{x}" }.
irb(main):002:0* to_a.tap {|x| puts "array: #{x}"}.
irb(main):003:0* select {|x| x.even? }.tap {|x| puts "evens: #{x}"}
original: 1..10
array: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
evens: [2, 4, 6, 8, 10]
=> [2, 4, 6, 8, 10]
参考
Ruby で map の &: を使ってみる
2019-07-13やったこと
Ruby で map(&:) を使ってみます。
確認環境
$ ruby --version
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin17]
調査
$ irb
irb(main):001:0> numbers = [1, 3, 5, 7]
=> [1, 3, 5, 7]
irb(main):002:0> numbers.map(&:to_s)
=> ["1", "3", "5", "7"]
irb(main):003:0> numbers.map {|i| i.to_s}
=> ["1", "3", "5", "7"]
map メソッドの &: を使うと簡潔に書くことができます。
参考
Rails の config で eager_load を設定してみる
2019-07-13やったこと
Rails の config で eager_load を設定してみます。
確認環境
$ ruby --version
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin17]
$ rails --version
Rails 5.2.3
調査
config.eager_load: trueにすると、config.eager_load_namespacesに登録された事前一括読み込み(eager loading)用の名前空間をすべて読み込みます。ここにはアプリケーション、エンジン、Railsフレームワークを含むあらゆる登録済み名前空間が含まれます。
共通で使う、下記のようなファイルを作成します。
app/models/hogehoge/abc.rb
module Hogehoge
class Abc < Abc
end
end
config.eager_load = false の時
$ rails c
irb(main):001:0> Object.const_defined?('Hogehoge::Abc')
=> false
irb(main):002:0> Hogehoge::Abc
=> Hogehoge::Abc
irb(main):003:0> Object.const_defined?('Hogehoge::Abc')
=> true
config.eager_load = true の時
$ rails c
irb(main):001:0> Object.const_defined?('Hogehoge::Abc')
=> true
参考
Rails5 の require_dependency を使ってみる
2019-07-11やったこと
Rails の require_dependency を使ってみます。
確認環境
$ ruby --version
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin17]
$ rails --version
Rails 5.2.3
調査
クラス名が衝突する
app/controllers/concerns/hoge/piyo_controller.rb
- このファイルがロードされる時、Hoge::ApplicationController が呼ばれていないと
::ApplicationController を見に行ってしまいます。
module Hoge
class PiyoController < ApplicationController
end
end
app/helpers/application_controller.rb
module Hoge
class ApplicationController
def abc
p "method: #{__method__}"
end
end
end
app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
def root_app
p "method: #{__method__}"
end
end
出力結果
irb(main):009:0> Hoge::PiyoController.new.abc
Traceback (most recent call last):
1: from (irb):9
NoMethodError (undefined method `abc' for #<Hoge::PiyoController:0x00007fb4244b20c8>)
irb(main):010:0> Hoge::PiyoController.new.root_app
"method: root_app"
=> "method: root_app"
以上より、::ActionController が継承されていることが分かります。
クラス名の衝突を解決する
変更があるファイルだけ載せます。
解決方法は下記の方法があるようでした。
- 名前空間をきっちり記述する
- require_dependency を使う
今回は require_dependency を使います。
require_dependency 'app/helpers/application_controller'
module Hoge
class PiyoController < ApplicationController
end
end
出力結果
irb(main):012:0> Hoge::PiyoController.new.abc
"method: abc"
=> "method: abc"
irb(main):013:0> Hoge::PiyoController.new.root_app
Traceback (most recent call last):
1: from (irb):13
NoMethodError (undefined method `root_app' for #<Hoge::PiyoController:0x00007fb423ee5a00>)
Hoge::ApplicationController が継承されていることが分かりました。
ちなみに
Rails がファイルを読み込むときのパスは下記のようになっています。
irb(main):001:0> puts ActiveSupport::Dependencies.autoload_paths
/Users/demo/app/assets
/Users/demo/app/channels
/Users/demo/app/controllers
/Users/demo/app/controllers/concerns
/Users/demo/app/helpers
/Users/demo/app/jobs
/Users/demo/app/mailers
/Users/demo/app/models
/Users/demo/app/models/concerns
/Users/demo/app/workers
/Users/demo/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/activestorage-5.2.3/app/assets
/Users/demo/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/activestorage-5.2.3/app/controllers
/Users/demo/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/activestorage-5.2.3/app/controllers/concerns
/Users/demo/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/activestorage-5.2.3/app/javascript
/Users/demo/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/activestorage-5.2.3/app/jobs
/Users/demo/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/activestorage-5.2.3/app/models
/Users/demo/spec/mailers/previews
参考
Ruby でマジックコメントの frozen_string_literal を使ってみる
2019-07-09やったこと
Ruby でマジックコメントの frozen_string_literal を使ってみます。
確認環境
$ ruby --version
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin17]
調査
test.rb
# frozen_string_literal: true
a = 'abc'
puts a.frozen?
puts a.upcase
# 例外が発生します
puts a.upcase!
出力結果
$ ruby test.rb
true
ABC
Traceback (most recent call last):
1: from ruby-frozen.rb:9:in `<main>'
ruby-frozen.rb:9:in `upcase!': can't modify frozen String (FrozenError)
参考
Ruby で concat を使ってみる
2019-07-08やったこと
Ruby で concat を使ってみます。
確認環境
$ ruby --version
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin17]
調査
$ irb
irb(main):001:0> a = [1, 2]
=> [1, 2]
irb(main):002:0> b = [4, 3]
=> [4, 3]
irb(main):003:0> a.concat(b)
=> [1, 2, 4, 3]
irb(main):004:0> a
=> [1, 2, 4, 3]
concat を呼び出した a に破壊的な変更が入ります。
$ irb
irb(main):001:0> a = [1, 2]
=> [1, 2]
irb(main):002:0> b = [8, 9]
=> [8, 9]
irb(main):003:0> a + b
=> [1, 2, 8, 9]
irb(main):004:0> a
=> [1, 2]
irb(main):005:0> b
=> [8, 9]
Array の + を使うと、破壊的な変更を入れずに配列の結合ができます。
参考
やったこと
Rails の generate コマンドを使った時、rspec のファイルも自動生成されますが
今回、自動生成される rspec のファイルを制御します。
確認環境
$ ruby --version
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin17]
$ rails --version
Rails 5.2.3
$ gem list | grep rspec-rails
rspec-rails (3.8.2)
調査
変更前
$ rails g controller Users new
Running via Spring preloader in process 49766
create app/controllers/users_controller.rb
route get 'users/new'
invoke erb
create app/views/users
create app/views/users/new.html.erb
invoke rspec
create spec/controllers/users_controller_spec.rb
create spec/views/users
create spec/views/users/new.html.erb_spec.rb
invoke helper
create app/helpers/users_helper.rb
invoke rspec
create spec/helpers/users_helper_spec.rb
invoke assets
invoke coffee
create app/assets/javascripts/users.coffee
invoke scss
create app/assets/stylesheets/users.scss
変更後
config/application.rb
module Sample2
class Application < Rails::Application
# 途中コードはスキップ
config.generators do |g|
g.test_framework :rspec,
fixtures: false,
view_specs: false,
helper_specs: false,
routing_specs: false
end
end
end
$ rails g controller Users new
Running via Spring preloader in process 51917
create app/controllers/users_controller.rb
route get 'users/new'
invoke erb
create app/views/users
create app/views/users/new.html.erb
invoke rspec
create spec/controllers/users_controller_spec.rb
invoke helper
create app/helpers/users_helper.rb
invoke rspec
invoke assets
invoke coffee
create app/assets/javascripts/users.coffee
invoke scss
create app/assets/stylesheets/users.scss
参考
- Everyday Rails - RSpecによるRailsテスト入門 (2. RSpecのインストール)