- 開発
週刊Railsウォッチ(20190909-1/2前編)Rails 6のキャッシュバージョニング、Rubyのキーワード引数周りが変わる、Faker 2がリリースほか
こんにちは、hachi8833です。消費税アップが迫ってきましたね。
つっつきボイス:「そうそう、消費税アップ来ますね😅」「皆さんの中で消費税対応されてる方は?」「経理部とやりとりしたりしてますね」「もう終わりました?」「まだまだです🤣」「食品みたいに軽減税率対応のものを扱ってると面倒そうですね」「どちらにしろ2%アップはやってくるので、商品マスターデータを更新するかどうかとか考えないといけないかも☺️」
「今回の場合、消費税を『還元する』とか『サービスする』的な触れ込みをしてはいけないという指示とかが上のPDFにもあるんですよね↑」「ちとわかりにくいですけど😆」「他にもいろいろ注意事項あるので、消費税を扱ってるかどうかにかかわらず読んどかないとですね☺️」
- 各記事冒頭には⚓でパーマリンクを置いてあります: 社内やTwitterでの議論などにどうぞ
- 「つっつきボイス」はRailsウォッチ公開前ドラフトを(鍋のように)社内有志でつっついたときの会話の再構成です👄
- 毎月第一木曜日に「公開つっつき会」を開催しています: お気軽にご応募ください
今回は第14回公開つっつき会を元にお送りします。ご参加いただいた皆さまありがとうございます!
⚓Rails: 先週の改修(Rails公式ニュースより)
今回は6.0.1マイルストーンや最近マージされたPR中心に見繕ってみました。
⚓リグレッション修正: @prepared_statement_status
をスレッドローカル変数化してインスタンス固有にした
# activerecord/lib/active_record/connection_adapters/abstract_adapter.rb#L13
+ require "concurrent/atomic/thread_local_var"
...
attr_accessor :pool
- attr_reader :visitor, :owner, :logger, :lock, :prepared_statements
+ attr_reader :visitor, :owner, :logger, :lock
alias :in_use? :owner
...
def initialize(connection, logger = nil, config = {}) # :nodoc:
super()
@connection = connection
@owner = nil
@instrumenter = ActiveSupport::Notifications.instrumenter
@logger = logger
@config = config
@pool = ActiveRecord::ConnectionAdapters::NullPool.new
@idle_since = Concurrent.monotonic_time
@visitor = arel_visitor
@statements = build_statement_pool
@lock = ActiveSupport::Concurrency::LoadInterlockAwareMonitor.new
if self.class.type_cast_config_to_boolean(config.fetch(:prepared_statements) { true })
- @prepared_statements = true
+ @prepared_statement_status = Concurrent::ThreadLocalVar.new(true)
@visitor.extend(DetermineIfPreparableVisitor)
else
- @prepared_statements = false
+ @prepared_statement_status = Concurrent::ThreadLocalVar.new(false)
end
@advisory_locks_enabled = self.class.type_cast_config_to_boolean(
config.fetch(:advisory_locks, true)
)
end
...
+ def prepared_statements
+ @prepared_statement_status.value
+ end
...
def unprepared_statement
- old_prepared_statements, @prepared_statements = @prepared_statements, false
- yield
- ensure
- @prepared_statements = old_prepared_statements
+ @prepared_statement_status.bind(false) { yield }
end
この問題をデモする簡単なアプリ: https://github.com/careport/racy
この問題は、システムテストで単一のDBコネクションが全サーバースレッドで共有されていることから始まっている。
unprepared_statement
がコネクションの@prepapred_statements
インスタンス変数を改変するので、これを用いるやりとりがよくないことになっている。その改変が、コネクションを共有する他のスレッドから透けて見えるため、一部のクエリのパラメータが誤ってパラメータ化される。
この問題が853f568で顕在化しない理由はわからない。引き続き調べてみるが、Active Recordの内部に詳しい人ならすぐわかるかもしれない。
同issueより大意
つっつきボイス:「スレッド関連かな?」「システムテストで1つのデータベースコネクションを全サーバースレッドで共有しているときに問題が生じたとissueにありました↑」「Concurrent::ThreadLocalVar
なんてのがある」「これはRubyのメソッドかな?」「ruby-concurrencyっていうgemみたいです」
参考: ruby-concurrency/concurrent-ruby: Modern concurrency tools including agents, futures, promises, thread pools, supervisors, and more. Inspired by Erlang, Clojure, Scala, Go, Java, JavaScript, and classic concurrency patterns.
参考: Class: Concurrent::ThreadLocalVar
— Concurrent Ruby
「Concurrent::ThreadLocalVar
のドキュメントにJavaのThreadLocal
へのリンクがあるから↓、これとパラダイムが近いということかも」「一瞬このライブラリがJavaなのかと思った😆」
参考: ThreadLocal (Java Platform SE 7 )
「最近スレッド周りの修正が毎週のように出てきますね😳」「探せば探すほど出てきちゃうのかも」「修正も大変ですけど、スレッド絡みの現象を再現するのはもっと大変ですね😅: Active Recordのこの辺で問題が起きそうと見当をつけることはできても、こういう再現テストを書ける人ってマジでスゴいと思いますし🙇」「スレッドのバグって、100万回回すと数回起きるみたいなのもありますね😇」
⚓rails new
のプロジェクト名に丸かっこ()
があるとビューテンプレートが見つからなくなる問題を修正
- PR: Fix escaping in OptimizedFileSystemResolver by jonathanhefner · Pull Request #37119 · rails/rails -- まだopenです(2019/09/12: その後マージされました)
# actionview/lib/action_view/template/resolver.rb#L352
def build_regex(path, details)
- query = escape_entry(File.join(@path, path))
+ query = Regexp.escape(File.join(@path, path))
exts = EXTENSIONS.map do |ext, prefix|
match =
if ext == :variants && details[ext] == :any
".*?"
else
arr = details[ext].compact
arr.uniq!
arr.map! { |e| Regexp.escape(e) }
arr.join("|")
end
prefix = Regexp.escape(prefix)
"(#{prefix}(?<#{ext}>#{match}))?"
end.join
%r{\A#{query}#{exts}\z}
end
なお、issue #37107については以下のPRが先にあったのですが、入れ違いで上のPRが投げられていたため以下はcloseされていました。
つっつきボイス:「プロジェクト名に丸かっこ()
を入れるのってちょっとどうかなと思ったので😆」「なんと🤣」「issueの方がわかりやすいかも」「これか↓」「()
に限らずメタ文字が入るとビューを参照できなくなってたそうです」
# 同issueより
rails new "path-escape-bug (testing)"
cd "path-escape-bug (testing)"
rails g controller public example
bin/rails s
# open "http://localhost:3000/public/example" in your browser
「これが正常に動くと思う人っていなさそうだけど、それでも書きたい人がいるのかも😆」「なお#37119はまだマージされてませんね」「Railsプロジェクト名にダブルクォートとか入れたい人っているんだろうか🤣」「仕様上メタ文字はプロジェクト名で使えないことにする方が早い気もしますし😆」
def test_can_find_when_special_chars_in_path
special_chars = ((" ".."~").grep(/\W/) - ["|", "/", "\\"]).join("_")
dir = "test#{special_chars}"
with_file "#{dir}/hello_world", "Hello funky path!"
templates = resolver.find_all("hello_world", dir, false, locale: [:en], formats: [:html], variants: [:phone], handlers: [:erb])
assert_equal 1, templates.size
assert_equal "Hello funky path!", templates[0].source
assert_equal "#{dir}/hello_world", templates[0].virtual_path
end
「ところで、テストのこの(" ".."~")
という書き方↑でメタ文字をカバーできるのかな?🤔」「ASCIIコード表見ながらIRBを動かしてみると、スペース文字から~
までを取って、/\W/
で英数字を除去して、["|", "/", "\\"]
を差し引いて_
でjoinすると...たしかにできた!」「おぉ〜」「こうやってRangeで取るのは初めて見たな〜: 脳内にASCIIコードがないと思いつかないし😆」「numbered parameterで書きたかったけどそういえばRuby 2.6にはなかった😆」「このファイル名、Windowsで通るんだろうか😆」「そのうち絵文字もありになったり?😆」
special_chars = ((" ".."~").grep(/\W/) - ["|", "/", "\\"]).join("_")
#» " _!_\"_#_$_%_&_'_(_)_*_+_,_-_._:_;_<_=_>_?_@_[_]_^_`_{_}_~"
参考: ASCIIコード表
⚓Active Jobキュー名の文字列をfreezeさせた
# 同PRより
Retained String Report
-----------------------------------
...
217 "default"
200 /tmp/bundle/ruby/2.6.0/bundler/gems/rails-59e746d4d07b/activejob/lib/active_job/qu
# activejob/lib/active_job/queue_name.rb#L49
def queue_name_from_part(part_name) #:nodoc:
queue_name = part_name || default_queue_name
name_parts = [queue_name_prefix.presence, queue_name]
- name_parts.compact.join(queue_name_delimiter)
+ -name_parts.compact.join(queue_name_delimiter)
end
つっつきボイス:「キュー名の"default"
という文字列が重複してたそうで、大したことはないけど修正はすごく簡単だったので修正したとPRにありました」「memory profilerで見つけたんでしょうね」「シンボルで返すようにしたのかな?と思ったら、-
でfreezeさせたのね」「+
がdupを返すんでしたっけ」「この辺の記号、どっちがどっちだったか不安になりがち😅」
参考: instance method String#-@
(Ruby 2.6.0)
「たしかに-
だとobject_idは一致する↓」
h1 = -"hoge"
#» "hoge"
h2 = -"hoge"
#» "hoge"
h1.object_id
#» 70279179364960
h2.object_id
#» 70279179364960
h3 = "hoge"
#» "hoge"
h4 = "hoge"
#» "hoge"
h3.object_id
#» 70136481465760
h4.object_id
#» 70136481387620
⚓Style/BracesAroundHashParameters
copを無効にした
-# .rubocop.yml#L37
-# Do not use braces for hash literals when they are the last argument of a
-# method call.
-Style/BracesAroundHashParameters:
- Enabled: true
- EnforcedStyle: context_dependent
つい最近のRubyのキーワード引数の扱い変更↓に伴う変更のようです。
- PR: Separate Keyword Arguments from Positional Arguments by jeremyevans · Pull Request #2395 · ruby/ruby
- issue: Feature #14183: "Real" keyword argument - Ruby master - Ruby Issue Tracking System -- まだ動いているようです
参考: RuboCop | Style/BracesAroundHashParameters
EnforcedStyle - Qiita
つっつきボイス:「Rubyのキーワード引数の扱いが変わることになったのを反映したとのことです」「#14183でずっと議論してたヤツね: キーワード引数とハッシュが混じるとえらいことになる、breaking change不可避の問題↓」「issue長いな〜」「closeはしたけどまだ少々動いてるっぽいですね」「ここはみんな困っている問題だから、何らかの形で修正しないといけないヤツですね」
# actionpack/test/dispatch/cookies_test.rb#L900
key_generator = @request.env["action_dispatch.key_generator"]
old_secret = key_generator.generate_key(@request.env["action_dispatch.signed_cookie_salt"])
- old_value = ActiveSupport::MessageVerifier.new(old_secret).generate({bar: "baz"})
+ old_value = ActiveSupport::MessageVerifier.new(old_secret).generate({ bar: "baz" })
「このスペース追加↑って何なんでしょう?」「スペースはあっても解釈は変わらなかったと思うけど🤔」「Style/BracesAroundHashParameters
のcopがコンフリクトしてたので外してオートコレクトしたらスペースが入ったということみたい」「d94263f...5665fb5にはこういう修正が入ってる↓」「あ、こっちの{}
追加の方がメインだったのか😅」
# activesupport/test/message_encryptor_test.rb#L127
def test_rotating_serializer
old_message = ActiveSupport::MessageEncryptor.new(secrets[:old], cipher: "aes-256-gcm", serializer: JSON).
- encrypt_and_sign(ahoy: :hoy)
+ encrypt_and_sign({ahoy: :hoy})
encryptor = ActiveSupport::MessageEncryptor.new(@secret, cipher: "aes-256-gcm", serializer: JSON)
encryptor.rotate secrets[:old]
assert
参考: RuboCop | Style/BracesAroundHashParameters EnforcedStyle - Qiita
「Rubyの#2395のコメント↓を見ると『昨日developer meetingで受理された』とあって、それが6日前(つっつき当日から見て)ということだから、つい1週間前だったんですね」
「話は変わりますけど、RubyとRailsはコミッターが割と近い関係にあるから、言語とフレームワークがこうやって密に連携しているのがありがたいですよね😋」「たしかに!」「PHPとかだとかなり分かれてる感ありますし☺️」
⚓番外: SolarisではProcess.clock_gettime(Process::CLOCK_PROCESS_CPUTIME_ID)
を使ってはいけない
つっつきボイス:「Solaris環境ではProcess#clock_gettime(CLOCK_PROCESS_CPUTIME_ID)
は使うなとchangelogに追加されてました」「ソラリス!😆」「互換性がなかったんでしょうね」「Ruby on Solarisやってる人いるんだ😆」
「SolarisっていうOS、そもそも皆さんご存知です?」「いやぁ😅」「SolarisといえばあのSunの特徴的な薄いブルーというか紫色の筐体で、秋葉のジャンク屋に安く積んであったりするとつい買っちゃったりしますよね😆」「見たことならありますけど触るまでは😅」
「Solarisっていう名前の由来って、もしかすると旧ソ連が国力を挙げて制作した映画『惑星ソラリス』と関係あるんだろうか?ってうっすら気になってました」「由来はわかんない😆」「この映画を見た人はあまりの尺の長さに必ず寝ちゃう催眠フィルムだと一部で評判でした😆」「😆」
後でSolarisという名前の由来をググると以下が出てきましたが、今のWikipediaには英語版日本語版ともにこの記述はないので、たぶん違うんでしょうね。
参考: Solaris系OSはなぜ ソラリス とゆうのですか?教えてください。 - Solaris(ソラ... - Yahoo!知恵袋
⚓Rails
⚓Rails 6のcollection_cache_versioning
以前も簡単に取り上げました(ウォッチ20190507)。
コンフィグでActiveRecord::Base.collection_cache_versioning = true
を指定しないと有効になりません。
参考: 3.7 Active Recordを設定する -- Rails アプリケーションを設定する - Rails ガイド
つっつきボイス:「これってどういう機能だったっけ」「上のガイドに一応あります」「ここは英語で見ておきたいな↓」
参考: Configuring Rails Applications — Ruby on Rails Guides
config.active_record.collection_cache_versioning
enables the same cache key to be reused when the object being cached of typeActiveRecord::Relation
changes by moving the volatile information (max updated at and count) of the relation's cache key into the cache version to support recycling cache key. Defaults tofalse
.
Ruby on Rails Guidesより
「元記事のタイトルにもあるけど、キャッシュキーがrecyclableなのがポイントらしい: そうそう、キャッシュバージョンとキャッシュキーを分けられるようになったということですね↓」「おぉ?」
# 同記事より
>> ActiveRecord::Base.cache_versioning = true
>> post = Post.last
>> cache_key = post.cache_key
=> "posts/1"
>> before_update_cache_version = post.cache_version
=> "20190527080152975653"
>> Rails.cache.fetch(cache_key, version: before_update_cache_version) { post }
=> #<Post id: 1, title: "First Post", created_at: "2019-05-22 17:23:22", updated_at: "2019-05-27 08:01:52">
「以前はキーとバージョンが一体化していたので、キャッシュバージョンを更新するとキャッシュ自体が別キャッシュとして作られてたんですが、バージョニングできるようになったことでキーとバージョンを別々に更新できるようになったということだと思います」「記事の最後にこう書いてますね😋↓: cache_version
はタイムスタンプとかを含んでいてvolatileだから、キャッシュが同じでもこの部分は変わる可能性があり、cache_key
は一意に生成される」「Rails 6から挙動がこう変わるから、コンフィグでActiveRecord::Base.collection_cache_versioning = true
を指定しないと有効にならないようにしたんでしょうね」
- Rails 6より前
ActiveRecord::Relation
のcache_keyフォーマットは{table_name}/query-{query-hash}-{count}-{max(updated_at)}だった- Rails 6の場合
- 以下に分割される
・安定的なcache_key
:{table_name}/query-{query-hash}
・変わりうるcache_version
: {count}-{max(updated_at)}
「Redisとかにキャッシュを乗せている場合、ここが変わるとデプロイしたときに全部のキャッシュが死んでしまうでしょうね😇」「あ〜」「Railsって、rails app:update
みたいなコマンドで、互換性を保つ設定をconfig/initializers/new_framework_defaults.rbに生成するみたいな機能がありましたよね」「ありますね: で後から対応できたときに順に消していくという」「このキャッシュ機能のコンフィグもそういうときに使うんでしょうね☺️」「Rails 6でrails new
する分にはいいけど、アップグレードでは注意が必要そう」
参考: 1.4 アップデートタスク -- Rails アップグレードガイド - Rails ガイド
⚓GoRails.comのスクリーンキャスト
RailsCastsの更新が止まって無料化されて久しいですが、GoRailsを最近見てなかったので覗いてみました。今もマメに更新されているようです。
このスクリーンキャストとかがちょっと気になりました↓。
つっつきボイス:「GoRails?」「RailsCastsに代わるスクリーンキャストというと今のところここぐらいなのかなと思って見に行くと、サイトが前より心持ちシンプルになってて、かなりマメに更新してました」
「こういうオンライン講座的なものって皆さんは見たりします?自分は動画になってるとコピペとかできないんで見ない方ですけど😆」「ITとは少し違いますけどCoursera↓とかは見たりしますね」「こーせら?」「日本語化もされてるんですね😋」
「GoRails割と頑張ってるみたいで、ここのリポジトリ↓を見る方が新着情報もわかりやすいかなと」「どちらかというと、動画で今見えてるものをさくっとコピペしたいんですよね〜」「作り込み難しそうですね😅」「まあ今ならスクショ取ってGoogleドライブに置いてOCRする手もあるかもしれませんけど😆」
- リポジトリ: GoRails Screencasts
「初心者の方はこういう動画の講座を好む印象がちょっとあるかな〜」「あと英語圏もスクリーンキャスト好きですよね」「ステップバイステップの操作って記事で書こうとすると量が増えてすんごく大変なんですよ😭: 動画はその点では製作しやすいから、動画でやりたい気持ちはわかるかも☺️」
⚓Rails 6のDNS Rebinding対策で開発中にlvh.meが効かなくなる(Awesome Rubyより)
参考: 【Rails】ローカル環境の開発でサブドメインがある場合「localhost」ではなく「lvh.me」を使う - FujiYasuの日記
参考: DNS Rebinding ~今日の用語特別版~ | 徳丸浩の日記
つっつきボイス:「おぉ、この記事にある問題、今日まさに社内のメンバーが踏んでましたよ😆: Rails 6にはDNSリバインディング対策が入ったので、デフォルトのlocalhost以外のドメインはconfig.hosts
に明示的に追加しないとdevelopment環境でアクセスできなくなるという↓」「おぉ〜」
# 同記事より
# config/enviroments/development.rb
config.hosts << '.lvh.me'
⚓Trestle: Bootstrap 4ベースのレスポンシブ管理画面(Awesome Rubyより)
つっつきボイス:「Railsの管理画面は山ほどありますけど、これはどうかなと思って」「みんなこういうのいっぱい作りますよね☺️」「出たなDSL↓」
Trestle.resource(:posts) do
# Add a link to this admin in the main navigation
menu do
group :blog_management, priority: :first do
item :posts, icon: "fa fa-file-text-o"
end
end
# Define custom scopes for the index view
scopes do
scope :all, default: true
scope :published
scope :drafts, -> { Post.unpublished }
end
# Define the index view table listing
table do
column :title, link: true
column :author, ->(post) { post.author.name }
column :published, align: :center do |post|
status_tag(icon("fa fa-check"), :success) if post.published?
end
column :updated_at, header: "Last Updated", align: :center
actions
end
# Define the form structure for the new & edit actions
form do
# Organize fields into tabs and sidebars
tab :post do
text_field :title
# Define custom form fields for easy re-use
editor :body
end
tab :metadata do
# Layout fields based on a 12-column grid
row do
col(sm: 6) { select :author, User.all }
col(sm: 6) { tag_select :tags }
end
end
sidebar do
# Render a custom partial: app/views/admin/posts/_sidebar.html.erb
render "sidebar"
end
end
end
「こういうDSLって自分で作ってるときが一番楽しいんですよね🤣」「達成感は半端ない🤣」「見た目はよさそうだけど、凝ったカスタマイズをしようとすると辛くなりそうな予感が😆」「業務のプロジェクトでこういうのが流れてきたら頭抱えそう😅: でも自分しか使わないアプリならむしろこれでいいかなって思いますし😋」「今度オレオレRailsアプリで使ってみようかな😍」「自分だけが使うなら許せる😆」
「こういう管理画面とかをプログラマーがボタンぽちぽちして自動生成できたらうれしい気持ちはあるんですけど、それならRailsでやらなくてもよくね?って思ったりしますし、コードを書いて作るのはコードでないとできないことがあるからですし」「たしかに〜」
「グラフのカスタマイズとかもついやりたくなりますけど、ああいうのもGoogleデータポータル↓とかでやる方がよかったりしそうですよね😆」「データポータルは使ったことないな〜: Googleアナリティクスをこねこねする的な印象ありますけど、こういうのってなかなか思ったように作れなかったりしそうですし😅」「内部のMySQLだかPostgreSQLだかを把握するとうまく使えるようになるかなって思ったり☺️」「半端にGUIになってるとやりづらかったりしますね☺️」「競合はTableauあたりかな🤔」
- サイト: Google データポータル
⚓Rails Attributes APIで巨大JSONをPostgreSQLに保存する(Ruby Weeklyより)
つっつきボイス:「JSONをRails側でGzip圧縮解凍、ってわざわざRails側でやる必要あるんだろうか?😆」「たぶんぽすぐれのそういう圧縮機能とかデータストアを探して使う方がよくね?😆」「実用では使わないと思いますけど、練習にはいいと思いますね☺️」
# 同記事より
def value_to_hash(value)
JSON.parse(
ActiveSupport::Gzip.decompress(value),
symbolize_names: true
) || {}
end
def value_to_binary(value)
ActiveSupport::Gzip.compress(value)
end
参考: PostgreSQL: Documentation: 9.0: Binary Data Types
⚓その他Rails
Ctrl + N / Ctrl + P でも選択できます。キーマップから up / downとか検索するとどんなショートカットが割り当てられているか確認できます。右クリックすれば任意のショートカットを割り当てることもできます #jbugj pic.twitter.com/vUQBze3kGR
— ユースケ / Yusuke (@yusuke) September 3, 2019
つっつきボイス:「Twitterで見かけたRubyMineの質問に@yusukeさんがすごい勢いで回答してました」「JetBrainsの日本の代理店をやってる方ですね☺️」「いつも見ててくれてるらしい😍」
We’re in the process of soft-launching a new edition of the Rails Tutorial, so there may be some temporary disruptions. The previous edition will still be available at a different URL for those in the middle of following it.
— Rails Tutorial (@RailsTutorial) September 4, 2019
なお、その後のRails Tutorial(英語版の方)では、進行中のRails 6対応版のうち第3章までのみが公開されています↓。
⚓Ruby
⚓k0kubunさんの「Optimizing Ruby with JIT」
Buildersconでのスライドです。
- イベント: builderscon tokyo 2019
発表後 シェア忘れてた 資料ですhttps://t.co/UQcw5by7Jm#builderscon #ビルコン川柳
— k0kubun (@k0kubun) August 31, 2019
つっつきボイス:「こういうRubyのコアをきっちり解説してくれるのはうれしい😂」「しかも日本語で🇯🇵」「NESでの測定では2.5倍速くなったそうです」
⚓Faker 2がリリース(Ruby Weeklyより)
- リポジトリ: faker-ruby/faker: A library for generating fake data such as names, addresses, and phone numbers.
Changelogの日付が米国式風(年-日-月)になっていて、一瞬間違ってるのかと思いました😅。現在は2.2.2まで進んでいます。2.0でオプション引数がごっそりキーワード引数に置き換わっています。
# 同リポジトリより
Faker::Books::Dune.quote(character = nil)
↓
Faker::Books::Dune.quote(character: nil)
つっつきボイス:「Fakerはどこが変わったのかしら?」「2.0でオプション引数をキーワード引数に置き換えたのがbreaking changesだそうです」
Fakerだけでもロケール次第で日本語のフェイクデータを作れるんですね↓。デフォルトの日本語データが意外にささやかなサイズでした。
「Fakerは日本語拡張が使いたい部分ですね😋: こういうのとか↓」「あ、デフォルト以外にこんな大きい日本語Fakerがあるんですね😅」「名前データでかい!」「日本語住所は対応してないようですが」「バージョンアップで影響受けないといいけど(受けます: 後述)」
# ruby-faker-japaneseより
姓:高垣 名:芳人
姓:尾関 名:きね子
姓:夜久野 名:利常
姓:飯星 名:邦則
姓:草柳 名:大造
姓:納米 名:ナツコ
姓:金高 名:喜久蔵
姓:キーティング 名:秋江
姓:島居 名:悦二郎
姓:戸河内 名:さかえ
姓:片里 名:朝長
姓:上依知 名:洌
姓:湧井 名:宗矩
姓:隆速 名:美禅
「ついでに@willnetさんのgimeiというgem↓を今頃知りました」「gimeiというのもありますね〜: 日本語の名前専門かと思ったら、いつの間にか日本語のダミー住所も生成できるのか」
- 元記事: 【Rails】gem 'gimei' で日本語のダミーデータを生成する | RemoNote
- リポジトリ: willnet/gimei: random Japanese name and address generator
# gimeiより
address = Gimei.address
address.kanji # => 岡山県大島郡大和村稲木町
address.to_s # => 岡山県大島郡大和村稲木町
address.hiragana # => おかやまけんおおしまぐんやまとそんいなぎちょう
address.katakana # => オカヤマケンオオシマグンヤマトソンイナギチョウ
address.romaji # => Okayamaken Ooshimagunyamatoson Inagicho
追記: つっつきの後にkoicさんが以下の記事を出していました。Faker 2に移行するときのbreaking changesに対応するRuboCop Fakerを作ってくださったそうです🙇。
参考: Faker 2.2.2 がリリースされた - koicの日記
参考: RuboCop Faker を作った - koicの日記
Faker の org メンバーになりました。https://t.co/V0AA6g3S56
— Koichi ITO (@koic) September 5, 2019
⚓Rumale: Rubyで機械学習
# 同リポジトリより
require 'rumale'
# Load the training dataset.
samples, labels = Rumale::Dataset.load_libsvm_file('pendigits')
# Map training data to RBF kernel feature space.
transformer = Rumale::KernelApproximation::RBF.new(gamma: 0.0001, n_components: 1024, random_seed: 1)
transformed = transformer.fit_transform(samples)
# Train linear SVM classifier.
classifier = Rumale::LinearModel::SVC.new(reg_param: 0.0001, max_iter: 1000, batch_size: 50, random_seed: 1)
classifier.fit(transformed, labels)
# Save the model.
File.open('transformer.dat', 'wb') { |f| f.write(Marshal.dump(transformer)) }
File.open('classifier.dat', 'wb') { |f| f.write(Marshal.dump(classifier)) }
つっつきボイス:「ruby-jp Slackでちらっと見かけたRubyの機械学習gemです」「よく作ったな〜これ😳」「モチベーションが知りたい」「Pythonに依存しないんでしょうか?」「READMEにPythonのScikit-Learnに近いインターフェースになってるってありますし、Pythonを使ってるとは書いてないからおそらくそうなんでしょうね🤔」「Rubyでここまでやるのスゴい!」
Red Data Toolsプロジェクトとは別のようですね。
⚓custom_cops_generator: RuboCopのカスタムcopを生成
# 同リポジトリより
$ custom_cops_generator rubocop-foobar
Creating gem 'rubocop-foobar'...
create rubocop-foobar/Gemfile
create rubocop-foobar/lib/rubocop/foobar.rb
create rubocop-foobar/lib/rubocop/foobar/version.rb
create rubocop-foobar/rubocop-foobar.gemspec
create rubocop-foobar/Rakefile
create rubocop-foobar/README.md
create rubocop-foobar/bin/console
create rubocop-foobar/bin/setup
create rubocop-foobar/.gitignore
Initializing git repo in /tmp/tmp.Gu7G94wX00/rubocop-foobar
Gem 'rubocop-foobar' was successfully created. For more information on making a RubyGem visit https://bundler.io/guides/creating_gem.html
create rubocop-foobar/lib/rubocop-foobar.rb
create rubocop-foobar/lib/rubocop/foobar/inject.rb
create rubocop-foobar/lib/rubocop/cop/foobar_cops.rb
create rubocop-foobar/config/default.yml
create rubocop-foobar/spec/spec_helper.rb
create rubocop-foobar/.rspec
update lib/rubocop/foobar.rb
update lib/rubocop/foobar.rb
update lib/rubocop/foobar/version.rb
update rubocop-foobar.gemspec
update rubocop-foobar.gemspec
update Rakefile
update Gemfile
It's done! You can start developing a new extension of RuboCop in rubocop-foobar.
For the next step, you can use the cop generator.
$ bundle exec rake 'new_cop[Foobar/SuperCoolCopName]'
つっつきボイス:「これもruby-jpでちらっと見かけましたけど、カスタムcopを作りたいことって結構あるんでしょうか?」「プロジェクト固有のコーディングルールを設定したいときとかでしょうね: 事業会社とかで1つのRailsプロジェクトに何十人も職業的メンバーがいるみたいな環境ならあるかも☺️」「たしかShopifyがcop的なものを作って頑張っているみたいな話がありましたね↓: それこそ100人以上のRailsエンジニアがコードを書いている環境」
参考: RubyKaigi、shopifyのテストの話が良かった · hoshinotsuyoshi.com - 自由なブログだよ
⚓その他Ruby
- イベント: Ruby Hack Challenge Holiday #7 - connpass -- Ruby インタプリタをハックするという、かなり濃そうなイベントです(10月06日)。
前編は以上です。
バックナンバー(2019年度第3四半期)
週刊Railsウォッチ(20190902)Ruby 2.6.4セキュリティ修正リリース、スライド「All About Ruby in 2019」、Shrine gem 3.0に入る新機能ほか
- 20190826 6-0-stableの更新を見てみる、『Morning Cup of Coding』ニュースレター、Rails TutorialがRails 6対応に動き出すほか
- 20190821-2/2後編 [11のgemにバックドア、ruby-jp Slackがとてもアツい、Fullstaq Rubyでチューンアップ、HTTPサービス監視chaoほか]/hachi8833/2019_08_26/79727
- 20190819-1/2前編 祝: Rails 6がついにリリース、RailsガイドもRails 6に対応、Arelはpublicだったかほか
- 20190806-2/2後編 RSpec CopのLeakyConstantDeclaration、serveoでゼロコンフィグ公開、RuboCopのPerformance/RegexpMatch改修ほか
- 20190805-1/2前編 Rails 6のActive Recordは速くなった、Windows WSL2+VSCodeでのRails開発、Martin Fowler記事ほか
- 20190730-2/2後編 Docker 19.03の新機能に注目、ngrokはスゴい、redis-namespaceほか
- 20190729-1/2前編 Rails 6のリリースは近そう?、Evil MartiansのRails+Docker記事、Railsパフォーマンス測定ほか
- 20190723-2/2後編 Rails 6 rc2がリリース、「MySQLパフォーマンスチューニングTips」が超便利、Aurora Serverlessほか
- 20190722-1/2前編 Rails 6エラー画面の改良点、Dateを四捨五入できるtime_calc、Rackミドルウェアのデザインパターンほか
- 20190717-2/2後編 NFSのよさとは、Linuxカーネル5.2リリース、Puppeteerでメモリリーク検出ほか
- 20190709-2/2後編 strong_password v0.0.7がハイジャックされていた、TerraformとCloudFormation、CSSの設計ミスリストほか
- 20190708-1/2前編 ActiveRecord::FixtureSetがめちゃ強くなってた、MacだとRubyが遅い理由、Puma 4登場ほか
- 20190701 RMagickのメモリ使用量が劇的に改善、インスタンス変数の定義順で速度が変わる?、GitLab CIランナーをローカルで回すほか
今週の主なニュースソース
ソースの表記されていない項目は独自ルート(TwitterやはてブやRSSなど)です。