こんにちは、hachi8833です。いよいよ明日はRuby25ですね。名札忘れないようにしないと。
Ruby25周年イベント、いよいよ明後日の土曜日となりました!当日は多くの参加者が集まります。交流がしやすくなりますので、他のカンファレンスなどで用意された名札をお持ちの方はぜひご持参ください。(お持ちでない方には、会場にて名札シールと記入スペースを用意しています。) #ruby25
— Ruby25 (@ruby25th) February 22, 2018
Rubyくん25歳のお誕生日おめでとうございます! #擬竜戯画 #ruby25th pic.twitter.com/lNXdwjgsjX
— RAO(らお)@C97土-南ア12b (@RIORAO) February 21, 2018
Rails: 今週の改修
今週は公式情報の他、Rails 6向けのmasterブランチからも見繕いました。文字列のfreeze化やシンボル化によるパフォーマンス向上作業が盛んなようです。
#create_or_find_by
は先週取り上げたのでなしです。
つっつきボイス: 「う、先週は#create_or_find_by
のあたりチェックできなかったー」
Railsのテストをパラレル化
miniTestのパラレルexecutorを直接使っているとのことなのでminiTest用ですね。サムズアップ👍が大量に付いてます。
class ActiveSupport::TestCase
parallelize(workers: 2)
end
class ActiveSupport::TestCase
parallelize(workers: 2)
parallelize_setup do |worker|
# create a db w/ worker. Runs after processes are forked
end
parallelize_teardown do |worker|
# delete the test databases or other cleanup. Runs before processes are closed
end
end
つっつきボイス: 「やっぱりminiTestかー」「話逸れるんですが、こういう見出しを見るとRailsアプリのテストの話なのかRailsフレームワークそのもののテストの話なのかつい考えちゃいますね」
ActiveJob引数のカスタムシリアライズ
class MySpecialSerializer
class << self
# Check if this object should be serialized using this serializer
def serialize?(object)
object.is_a? MySpecialValueObject
end
# Convert an object to a simpler representative using supported object types
# Recommended representative is a Hash with a specific key. Keys can be of basic types only
def serialize(object)
{
key => ActiveJob::Serializers.serialize(object.value)
'another_attribute' => ActiveJob::Serializers.serialize(object.another_attribute)
}
end
# Check if this serialized value be deserialized using this serializer
def deserialize?(object)
object.is_a?(Hash) && object.keys == [key, 'another_attribute']
end
# Convert serialized value into a proper object
def deserialize(object)
value = ActiveJob::Serializers.deserialize(object[key])
another_attribute = ActiveJob::Serializers.deserialize(object['another_attribute'])
MySpecialValueObject.new value, another_attribute
end
# Define this method if you are using a hash as a representative.
# This key will be added to a list of restricted keys for hashes. Use basic types only
def key
"_aj_custom_my_special_value_object"
end
end
end
上のようなカスタムシリアライザを書いて以下のように引数で渡せるようになりました。
ActiveJob::Base.add_serializers(MySpecialSerializer)
つっつきボイス: 「この引数部分がっつり書き直したそうです」「ジョブ自体のシリアライザを自分で書けるようになったのか!」「今までジョブの方でシリアライズしていたのが、こうやって共通部分で自由にシリアライズできるようにするというのはいかにもオブジェクト指向的」
RedisCacheStoreのコネクションプールをサポート
つっつきボイス: 「Railsのコネクションプールの話、前にもウォッチで取り上げたような気がするけど別の話だったかな...」「それはDBのコネクションプールでは?」「あ、それでした」「connection_pool
ってgem初めて見たナ」
# activesupport/lib/active_support/cache.rb#:163
+ class << self
+ private
+ def retrieve_pool_options(options)
+ {}.tap do |pool_options|
+ pool_options[:size] = options.delete(:pool_size) if options[:pool_size]
+ pool_options[:timeout] = options.delete(:pool_timeout) if options[:pool_timeout]
+ end
+ end
+
+ def ensure_connection_pool_added!
+ require "connection_pool"
+ rescue LoadError => e
+ $stderr.puts "You don't have connection_pool installed in your application. Please add it to your Gemfile and run bundle install"
+ raise e
+ end
+ end
関係ありませんが、conversationの末尾でよそのリポジトリがぴょこっと顔を出していますね。
Rails 6ではRuby 2.4.1以降が必須に
2.4.0までの"symbol_from_string".to_sym.dup
バグを避けるためだそうです。
# activesupport/lib/active_support/core_ext/object/duplicable.rb#L76
class Symbol
begin
- :symbol.dup # Ruby 2.4.x.
- "symbol_from_string".to_sym.dup # Some symbols can't `dup` in Ruby 2.4.0.
+ :symbol.dup
+
+ # Some symbols couldn't be duped in Ruby 2.4.0 only, due to a bug.
+ # This feature check catches any regression.
+ "symbol_from_string".to_sym.dup
rescue TypeError
同時に、ActiveSupportのHash#transform_values
が非推奨化されています。
# activesupport/lib/active_support/core_ext/hash/transform_values.rb#L3
-class Hash
- # Returns a new hash with the results of running +block+ once for every value.
- # The keys are unchanged.
- #
- # { a: 1, b: 2, c: 3 }.transform_values { |x| x * 2 } # => { a: 2, b: 4, c: 6 }
- #
- # If you do not provide a +block+, it will return an Enumerator
- # for chaining with other methods:
- #
- # { a: 1, b: 2 }.transform_values.with_index { |v, i| [v, i].join.to_i } # => { a: 10, b: 21 }
- def transform_values
- return enum_for(:transform_values) { size } unless block_given?
- return {} if empty?
- result = self.class.new
- each do |key, value|
- result[key] = yield(value)
- end
- result
- end unless method_defined? :transform_values
+require "active_support/deprecation"
今週の他の修正でも2.4.1+対応のものが目立ちます。
つっつきボイス: 「Rails 6はRuby 2.4.1以降か」「今はいくつ以上だったかな: こういうのはたいていRailsガイドのGetting Start的なところに書いてあるはず: カレントの5.1系はRuby 2.2.2以降、と」
「(見学の方に)軽く説明すると、その昔Rubyは1.8から1.9になるときにbreaking changesが結構発生したことがあったんですよ: ハッシュの順序が保証されたのとかはかなり大きかった」「その頃にうちの会社でRailsを使い始めたんですが、それ以降のRubyではそこまで大きな変更は起きてないですね」
「RailsではRubyの機能を拡張して使っているところがあちこちにあるんですが、そうした機能の一部が後にRubyの方に採用されるなんてこともちょくちょくあったりしますね」「Rubyだと配列の#first
や#last
が取れるんですが、RailsのActiveSupportだと#second
や#third
なんてのも取れます」「一種のジョークですけど#forty_twoなんてのもありますね」
「Rubyはバージョンアップされるたびに速くなってますね」「私のオレオレRailsアプリでも、2.5にアップグレードしただけで体感できましたね」
参考: Wikipedia-ja: 42
Ruby 2.5のString#-@
でパフォーマンス改善
# actionpack/lib/action_dispatch/journey/scanner.rb#L37
+ # takes advantage of String @- deduping capabilities in Ruby 2.5 upwards
+ # see: https://bugs.ruby-lang.org/issues/13077
+ def dedup_scan(regex)
+ r = @ss.scan(regex)
+ r ? -r : nil
+ end
つっつきボイス: 「dedup!聞いたことない言葉」「雰囲気は伝わるかなー」「stringのdedupの方だったか」
ちょっと紛らわしいですが、String#-@
は単項演算子を再定義するときの-@
という記法とは別です。
- self -> String | self
self が freeze されている文字列の場合、self を返します。 freeze されていない場合は元の文字列の freeze された (できる限り既存の) 複製を返します
https://docs.ruby-lang.org/ja/2.5.0/method/String/i/=2d=40.htmより
#13077で当初#fstring
というメソッド名が提案され、最終的にString#-@
に落ち着いたようです。
「fstring
というメソッド名は確かによくない」「でも-
ならいいのか?という疑問はある」
「今さらですが、単項演算子の再定義って+@
と-@
ぐらいしか見たことなかったけど、他にもできる記号あるんですね↓」「[]
なんかも再定義できるのがいい」
# https://docs.ruby-lang.org/ja/latest/doc/spec=2foperator.html より
| ^ & <=> == === =~ > >= < <= << >>
+ - * / % ** ~ +@ -@ [] []= ` ! != !~
ivar
をシンボルにしてdupを減らす
# activesupport/lib/active_support/core_ext/class/attribute.rb#L98
singleton_class.silence_redefinition_of_method("#{name}?")
define_singleton_method("#{name}?") { !!public_send(name) } if instance_predicate
- ivar = "@#{name}"
+ ivar = "@#{name}".to_sym
singleton_class.silence_redefinition_of_method("#{name}=")
define_singleton_method("#{name}=") do |val|
(ドキュメント)結合テストでのActiveStorageファイルクリーンアップはこういう感じで
# guides/source/active_storage_overview.md#L559
+Discarding Files Stored During Integration Tests
+-------------------------------------------
+
+Similarly to System Tests, files uploaded during Integration Tests will not be
+automatically cleaned up. If you want to clear the files, you can do it in an
+`after_teardown` callback. Doing it here ensures that all connections created
+during the test are complete and you won't receive an error from Active Storage
+saying it can't find a file.
+
+```ruby
+module ActionDispatch
+ class IntegrationTest
+ def remove_uploaded_files
+ FileUtils.rm_rf(Rails.root.join('tmp', 'storage'))
+ end
+
+ def after_teardown
+ super
+ remove_uploaded_files
+ end
+ end
+end
+```
Railsガイドの更新です。
つっつきボイス: 「ところで↑上の#rm_rf
っていうRubyのメソッド名はアツいですねー: Unix使ってれば意味は間違いなくわかるんだけど」「心がざわつく名前...」「そこがRubyっぽいとも言える」
Object#blank?
のモンキーパッチを削除
# activesupport/lib/active_support/values/time_zone.rb#L3
require "tzinfo"
require "concurrent/map"
-require "active_support/core_ext/object/blank"
rails g
で名前空間が指定されていると不要なルーティングが生成されていたのを修正
# railties/lib/rails/generators/rails/controller/controller_generator.rb#L17
def add_routes
return if options[:skip_routes]
+ return if actions.empty?
route generate_routing_code
end
つっつきボイス: 「これはrails g
の挙動ですね」「ぱっと見で実行時の話かと思ってた: 失礼しましたー」
# railties/test/generators/controller_generator_test.rb#L112
+ def test_does_not_add_routes_when_action_is_not_specified
+ run_generator ["admin/dashboard"]
+ assert_file "config/routes.rb" do |routes|
+ assert_no_match(/namespace :admin/, routes)
+ end
+ end
ActiveSupport::Multibyte
のUnicodeテーブルを削除
# activesupport/lib/active_support/multibyte/unicode.rb#L14
# The Unicode version that is supported by the implementation
- UNICODE_VERSION = "9.0.0"
+ UNICODE_VERSION = RbConfig::CONFIG["UNICODE_VERSION"]
大文字小文字変換などの対応をRubyに任せることにしたようです。ごっそり削除されています。
つっつきボイス: 「へー、UNICODE_VERSION = RbConfig::CONFIG["UNICODE_VERSION"]
なんて書き方できるのか!Rubyすごい」「RubyのUnicode実装がよくなったから今後はそっちを信用するようになった、と」「今まではRails側でその場しのぎ的な対応してたみたいですね」「ハングルがらみのパッチなんかも削除されてる」
Rails
Railsのビューをもっとオブジェクト指向っぽくするには(RubyFlowより)
#同記事より
--order
|--views
| |--partials
| | `--status_history.slim
| | `--calls_history.slim
| | `--cart.slim
| | `--contact_information.slim
| | `--shipping.slim
| `--show.slim
`--cell.rb
/ show.slim
= render(‘partials/status_history.slim’)
= render(‘partials/calls_history.slim’)
= render(‘partials/contact_information.slim’)
= render(‘partials/cart.slim’)
= render(‘partials/shipping.slim’)
つっつきボイス: 「ビューでオブジェクト指向...?w」「あーなるほど、ビューのパーシャルをなるべくオブジェクト単位にしようぜって話か」「まあ管理画面ぐらいならわかるけど、これやると画面デザインに制限がかかっちゃうから難しいところではある」
「『オブジェクト指向』というほどでもない気はするなー」「タイトルのviewが『見た目』の掛け言葉になってるのかもしれないですね: オブジェクト指向『っぽい』みたいな」
「ちなみにパーシャルは作りすぎるとレンダリングのパフォーマンスが激落ちしますヨ: やるならちゃんとキャッシュに乗せるとかしないと」
Value ObjectとRails 5のAttributes APIでRubyの文字列リテラルを消し去る(RubyFlowより)
「やりすぎではない、と思う」そうです。
# 同記事より
class Plan::Channel < ApplicationRecord
TYPES = %w(
direct
broker
correspondent
bdr
non_funded_origination
).freeze
self.inheritance_column = nil
belongs_to :plan
TYPES.each do |type|
scope type, -> { where(type: "#{type}") }
end
attribute :tiers, Plan::Channel::Tiers::Type.new
attribute :calculation_method, Plan::Channel::CalculationMethod::Type.new
end
つっつきボイス: 「ははーんenumの扱い的な話か、わかるわかる」「ちなみに自分はstring literalの方が楽でいいじゃんと思う派で、kazzさんはValue Object派」「何とw」
「(見学者の方から)freeze
って定数化ですか?」「freeze
は定数化ではなくて変更できなくするやつですね: Rubyを真面目にやるとわかると思いますが、恐ろしいほど動的にいろんなものが変わるんで、特に宣言的なものはこうやってfreeze
するんですよ」
「で、Value Objectを使うとモデルがこうやってすっきり書ける↓、と」
# 同記事より
class Plan::Channel < ApplicationRecord
belongs_to :plan
Plan::Channel::Source.values.each do |source|
scope source, -> { where(source: "#{source}") }
end
attribute :tiers, Plan::Channel::Tiers::Type.new
attribute :calculation_method, Plan::Channel::CalculationMethod::Type.new
attribute :source, Plan::Channel::Source::Type.new
end
Railsのafter_commit
(RubyFlowより)
おなじみEvilmartiansがdev.toに記事書いてますね。
# 同記事より
def pay(user, order_params)
Order.transaction do
order = order.new(order_params)
order.save!
ActiveRecord::Base.connection.add_transaction_record(
AfterCommitWrap.new { PaymentsService.charge!(user, order) }
)
end
end
つっつきボイス: 「モデル側にafter_commit
がなくても、こんなふうにトランザクションの外でadd_transaction_record
にafter_commit
的なものを仕込めるってことか: これはキワドイ」
「ところでRuby界隈ってVladimirって名前の人を複数見かける気がしません?」「ロシア系ですごく多い名前ですね: あだ名化するとVlad(ブラッド)」
バックグラウンドジョブのログをいい感じに取る(RubyFlowより)
# 同記事より
module WithJobLogging
def log_retryable_job(jid, job_type, user_id = nil)
create_async_job_log(jid, job_type, user_id) unless async_job_log(jid)
yield
mark_job_as_finished(jid)
end
def create_async_job_log(jid, job_type, user_id = nil)
AsyncJobLog.create(
jid: jid,
state: 'started',
job_type: job_type,
user_id: user_id
)
end
def async_job_log(jid)
AsyncJobLog.find_by(jid: jid)
end
def mark_job_as_finished(jid)
async_job_log(jid).finished!
end
end
つっつきボイス: 「ログってワーカーが複数になると混じっちゃうんで、テーブルに保存すればレコード単位になることは保証できる: たぶんそういうのをやりたいんだと思う」「まあfluentdとか使えば何の問題もなくできるやつ」
「ところがこれだとトランザクションが失敗したときみたいな異常時にログを取りようがないんですね」「なのでファイルに出すログも必要: 生ログを追うのは大変だけど」
isolator: DBトランザクションからアトミックでないやりとりを検出するgem
Introducing Isolator by @palkan_tula—a new tool for Ruby applications to detect “impure” operations within DB transactions (such as HTTP calls and BG jobs enqueueing)https://t.co/8vPJvLM0LM
— Evil Martians (@evilmartians) February 20, 2018
- リポジトリ: palkan/isolator
# 同リポジトリより
# HTTP calls within transaction
User.transaction do
user = User.new(user_params)
user.save!
# HTTP API call
PaymentsService.charge!(user)
end
#=> raises Isolator::HTTPError
# background job
User.transaction do
user.update!(confirmed_at: Time.now)
UserMailer.successful_confirmation(user).deliver_later
end
#=> raises Isolator::BackgroundJobError
つっつきボイス: 「SQLのトランザクション内で、HTTPアクセスみたいなSQLから外れるものがあったら検出してくれるということか」「raise
しちゃっていいんだろうか?検出だからCIで使うんだろうけど」「お、ここ↓で設定できる: よしよし」「なかなかよさそうなgem」
# 同リポジトリより
Isolator.configure do |config|
# Specify a custom logger to log offenses
config.logger = nil
# Raise exception on offense
config.raise_exceptions = false # true in test env
# Send notifications to uniform_notifier
config.send_notifications = false
end
「Everyday Rails - RSpecによるRailsテスト入門」が更新
- 元記事: Rails 5.1とRSpec 3.6に対応した「Everyday Rails - RSpecによるRailsテスト入門」をリリースしました - give IT a try
- 立ち読み: Everyday Rails - RSpecによるRailsテスト入門
つっつきボイス: 「RSpec 3.6やRails 5.1に対応したそうです」「RSpec本って当たりの本と、量が多い割に中身の薄いハズレの本があった気がするんだけど、これはどっちだったかな: 当たりの方だった!」「@jnchitoさんの翻訳本ですね」
私も以前買ってたので早速更新版PDFをダウンロードしました。
action_args: Railsコントローラが受け取るparamsをシグネチャ的に扱えるgem
8件のコメント https://t.co/Wlw5kw5d01 “ActionArgsが素晴らしい件 #Rails - Islands in the byte stream” https://t.co/feBG67Nknf
— すてぃお (@suthio_) February 19, 2018
- リポジトリ: asakusarb/action_args
# 同リポジトリより
class UsersController < ApplicationController
# the `page` parameter is optional
def index(page: nil)
@users = User.page(page).per(50)
end
end
つっつきボイス: 「はてブで反響呼んでますね」「ブコメにもあるけど、これはうまくハマるときれいだけど、そうじゃない場合は微妙かなーと思ってます」「これもブコメにありますが、Railsに最初からあればよかったのかも」
Active Adminの月間ダウンロード数が昨年の倍に(RubyFlowより)
つっつきボイス: 「Active Adminは割りと定番: ただデフォルトのままだとproductionで使いづらいのはどの管理画面gemでも変わらないですけどね」
text diffを%で得る(RubyFlowより)
- 元記事: Compare text differences between two contents (%) using Ruby on Rails
- リポジトリ: AnkurVyas-BTC/compare
以下のライブラリを使っているそうです。
- リポジトリ: threedaymonk/text
つっつきボイス: 「Levenshtein distance、聞いたことぐらいはあったかも: 実務じゃ使わないだろうけど」「このアルゴリズム知らなかった...Needleman/Wunschで文字単位diffやったことはあったけど」
「いろんなdiff距離がある: Healed
とSealed
がどれだけ似てるか↓みたいな感じ」「それにしてもtext
っていうgem名はググラビリティなさすぎw」「探して欲しくないんでしょうかね」
# threedaymonk/text
white = Text::WhiteSimilarity.new
white.similarity('Healed', 'Sealed') # 0.8
white.similarity('Healed', 'Help') # 0.25
FaktoryワーカーをAWS Fargateにデプロイする(Hacklinesより)
昨年末のウォッチで取り上げたFaktoryが流行りつつあるようです。
つっつきボイス: 「AWS Fargateはつい最近リリースされたサービスですね: ECSみたいに自前で建てなくてもコンテナだけで動かせる、GoogleのGKEに近いやつだったと思う」
参考: AWS Fargate -- サーバーやクラスターの管理が不要なコンテナの実行
参考: Google Kubernetes Engine -- Google Cloud 上の Kubernetes を利用してコンテナ化されたアプリケーションをデプロイ、管理、スケール
Railsアプリの「ハードモード」アップグレード(Hacklinesより)
この間ウォッチで紹介したUpgrading a Rails application incrementally(現在翻訳中)を先に読むと倍楽しめるそうです。
つっつきボイス: 「Railsのアップグレードは常にハードモードだけどな(キリッ」「Rails 3.2から4.2のアップグレードだと、大きい壁は2つぐらいあったかな」「これがRails 3.0だと、3.0と3.1の間にとてつもなく高い壁がある: アセットパイプライン周りとか」
「『rebase、rebase、rebase』...」「俺たちこんなにつらかったよ、っていうつらみレポート」
ActiveSupportとReactを使ったRailsチャットアプリを10分で作る(Ruby Weeklyより)
health_check: シンプルなヘルスチェックgem
- リポジトリ: ianheggie/health_check
昨日のBPS社内勉強会でリバースプロキシ絡みのヘルスチェックについて言及されたので貼ってみました。
curl localhost:3000/health_check
success
curl localhost:3000/health_check/all.json
{"healthy":true,"message":"success"}
curl localhost:3000/health_check/database_cache_migration.xml
<?xml version="1.0" encoding="UTF-8"?>
<hash>
<healthy type="boolean">true</healthy>
<message>success</message>
</hash>
つっつきボイス: 「ヘルスチェックのフォーマットがリバースプロキシと合うならこういうのを使ってもいいかも: ぶっちゃけ自分で書いたヘルスチェックの方がRackから直接返すからフットプリント小さいけど」
「ヘルスチェックの処理が重くてアプリサーバーまで遅くなると本末転倒だし、かといって頻度を下げると検出も遅れるのでそういう設定は悩みどころではある」
log_analyzer: CLIベースのRails簡易ログアナライザ(RubyFlowより)
- リポジトリ: igorkasyanchuk/log_analyzer
つっつきボイス: 「もしかして似たようなのがいっぱいあるのかなとは思いつつ貼ってみました」「お、悪くなさそう: 少なくともgrepで頑張って集計するよりはずっといい」「まともに運用で使うならNewRelicとか使うべきだけど、developmentで入ってれば使うかも」「常備薬的にとりあえず入れておいて損はない感じですね」
DHHツイートより
For every “best practice”, there’s a time when the opposite approach is superior. Once you stop looking for such openings, you stop growing. And plenty of “best practices” are either cargo-culted from a different time, language, or domain, and no longer service progress.
— DHH (@dhh) February 16, 2018
今回YouTubeチャンネルのシリーズを始めた動機はまさにそれ。中級プログラマーが「ベストプラクティス」を無批判に盲信することについて疑問を呈したい。
どんなベストプラクティスでも、それと真逆のアプローチの方が有効な場合がある。そういう方面を追求しなくなったら開発者の成長はそこで止まる。ベストプラクティスと呼ばれているものの大半は、別の時代や言語や分野から「カーゴカルト」的に(=よく吟味されずに)持ち込まれたものであり、そこにはサービスの進歩はない。
ツイートの大意
つっつきボイス: 「デザインパターンぐらいのレベルならベストプラクティスもありうるけど、もっと大きな設計になってくると何がベストかはそのときで違ってくるというのはありますね」
Ruby trunkより
MJITがらみのissue
- feature: #14489 MJIT needs a reusable cache -- 進行中
- bug: #14490 MJIT slows down Rails applications -- 進行中
RubyGems高速化のためにiseq読み込みやキャッシュをコアに置きたい
- feature #14492 iseq loading + caching should be in core -- 進行中
File#path.tainted?
とFile#to_path.tainted?
が元の汚染状態を反映していない -- 進行中
# 上より
#!/usr/bin/ruby -w
$SAFE = 1
path = './myfile.txt'
file = File.open(path, 'r')
File.exist?(file.path)
./to-path.rb:5:in `exist?': Insecure operation - exist? (SecurityError)
from ./to-path.rb:5:in `<main>'
つっつきボイス: 「taint
使ったことなかった」「へえぇこんなメソッドあるのか: しかもObject
だし」
参考: Object#taint
2.5.0の正規表現修正を2.4.3にもバックポート希望
puts RUBY_VERSION
p %w[+ é +].grep(/[[:punct:]]/)
2.3.5
[]
2.4.3
["+"]
2.5.0
["+", "+"]
つっつきボイス: 「é
のところでマッチがつっかえてる」「正規表現絡みはなー、いろいろツライ」
$
はus-asciiだと記号扱いでUTF-8だと記号扱いされないがいいか? -> 現状ママ
これも古いissueです。仕様レベルで違うということでrejectです。
# encoding: us-ascii
puts '$' =~ /\p{Punct}/ ? 'match' : 'no match'
# encoding: utf-8
puts '$' =~ /\p{Punct}/ ? 'match' : 'no match'
参考: POSIXでの定義
参考: Unicodeでの定義
Ruby
RubyGemに複数の脆弱性->修正済み(Ruby公式ニュースより)
Multiple vulnerabilities in RubyGems https://t.co/3lgvseF6oF
— Ruby Language (@rubylangorg) February 17, 2018
2.5のModule#private_constant
private_constantって奴いい機能っぽいのに今始めて使ったし使われてる場所も見たことない
— k0kubun (@k0kubun) February 18, 2018
つっつきボイス: 「privateって動詞か! こういうのを後から入れてくるのが何ともRubyらしい: 自分で自分を書き換えまくるような変更」
参考: Rubyリファレンスマニュアル Module#private_constant
name で指定した定数の可視性を private に変更します。
rubycritic: コードアナライザ gem(Awesome Rubyより)
- リポジトリ: whitesmith/rubycritic
まだ2.4.x対応だそうです。内部でReekやFlayなどを組み合わせているようです。
つっつきボイス: 「rubocopの競合というよりはコードアナライザというか静的解析に重点を置いている感じだから方向性は違うかな」
IO#close
のメッセージがRuby 2.5で改良されてうれしい(RubyFlowより)
#<Thread:0x00007f9cfc889370@io_ruby.rb:2 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
1: from io_ruby.rb:3:in `block in <main>'
io_ruby.rb:3:in `read': stream closed in another thread (IOError)
Traceback (most recent call last):
1: from io_ruby.rb:3:in `block in <main>'
io_ruby.rb:3:in `read': stream closed in another thread (IOError)
つっつきボイス: 「どのスレッドでこけたかがわかるようになったのは確かにうれしいっすね」
Rubyのネットワークセキュリティ関連ツール
Link: Ruby for Network Security: better than expected. - ruby https://t.co/cUWsSOYXN5
— Yukihiro Matsumoto (@yukihiro_matz) February 17, 2018
つっつきボイス: 「基本的にこの種のツールは実績で選びたいところ」
inspec: インフラのテストコードを書く(GitHub Trendingより)
- リポジトリ: chef/inspec
- サイト: https://www.inspec.io/
# 同リポジトリより
describe port(80) do
it { should_not be_listening }
end
describe port(443) do
it { should be_listening }
its('protocols') {should include 'tcp'}
end
つっつきボイス: 「いわゆるserver spec的なやつか: まあだいたいファイルの存在チェックとかポートのチェックになりますね」
LightIO: Ruby向け軽量スレッドライブラリ
- リポジトリ: socketry/lightio
Go言語のgoroutineやCrystal言語のfiberに似ているそうです。
つっつきボイス: 「RubyのFiberじゃなくてCrystalのfiberか」「green threadって聞いたことないなー」「造語かな?」「beamってのもある」「fiberより細いってことかも」
と思ったらありました。
グリーンスレッド(英: green threads)とは、コンピュータプログラミングにおいて、オペレーティングシステムではなく仮想マシン (VM) によってスケジュールされるスレッドである。グリーンスレッドはネイティブのOSの機能に依存せずにマルチスレッド環境をエミュレートする。グリーンスレッドはカーネル空間ではなくユーザー空間で管理されるため、ネイティブスレッドがサポートされていない環境でも動作する。
Wikipedia-ja: グリーンスレッドより
Rubyでsyntactic sugarメソッドを作る(Hacklinesより)
# 同記事より
person1 = Person.new
person1.name = "John"
array = [:foo, :bar]
array[1] # => :bar
hash = { :key => :foo }
hash[:key] # => :foo
hash[:key] = :value
つっつきボイス: 「シンタックスシュガーかと思ったらsyntactic sugarだそうです」「どうやら=
や[]
なんかをオーバーライドする話: ただあんまりやりすぎると単に読みにくいコードになるけど」「DSLとか書くときによく使うやつですね」
syntactic sugarとは、コードを読みやすくわかりやすくできるRubyのささやかなマジックのことです。Rubyではある種の記号やスペース文字を省略できるようにしたり、ヘルパー的な式を書いたりすることを指します。
同記事より大意
Rubyで形態素解析
【過去の記事】 テキストマイニングの初歩 Rubyで形態素解析を行う〜ruby-mecab https://t.co/K6Ss6X01cT #mecab #rails #Ruby
— scimpr blog (@scimpr) February 19, 2018
つっつきボイス: 「これはもうmecab叩いてるやつでしょう」「mecabって随分前からありますね」
Rubyのさまざまなコンカレンシーモデルを紹介(Random Rubyより)
- 元記事: Introduction to Concurrency Models with Ruby. Part I
- 元記事: Introduction to Concurrency Models with Ruby. Part II
つっつきボイス: 「parallelにthread、お、EventMachineも入ってるか、fiber、などなど一通り揃ってるかな」「このあたりを知らない人は読んでおくといいと思う」
OpalとFerroでDOMを叩くHTML抜きRuby Web開発(Ruby Weeklyより)
# 同サイトより
class Demo < FerroElementComponent
def cascade
# Add the title
add_child(
:title,
FerroElementText,
size: 4,
content: 'Title'
)
# Add the button
add_child(
:btn,
DemoButton,
content: 'Click me'
)
end
def rotate_title
# We have access to the 'title' instance variable
txt = title.get_text
title.set_text (txt[1..-1] + txt[0]).capitalize
end
end
class DemoButton < FerroFormButton
def clicked
# Every element knows its parent
parent.rotate_title
end
end
サイトの「Click me」ボタンでデモできます。
つっつきボイス: 「(見学の方へ)Opalっていう、RubyコードをJavaScriptに変換するのがあるんですね」「まだ対応付けみたいな感じでやってるんで、数値演算とかやったら結果はズレますが、ちょっとしたものなら作れる」
gemnasium.comがGitLabに買収される
つっつきボイス: 「何のサービスだろうと思って見てたらいきなり終了のお知らせ↓が表示されたので」「ということはこのサイトの機能がGitLabに追加されるのかな」
ときどき、言語に公式の自動フォーマッタが欲しくなる
プログラムの自動フォーマットは正解のない議論を終わらせてくれる上に、インデント数の異なるコピペが必要な時とかの作業も減らしてくれて超ありがたいので、p4fmtの登場も待ち望まれる。 https://t.co/w6ESg7NSos
— Kentaro Ebisawa (@ebiken) February 19, 2018
つっつきボイス: 「自分的には共感しちゃいます」「まあそれを推し進めるとPythonみたいに全部インデントでやるみたいになっちゃいそうですけどね」
追伸: こっちを貼るつもりだったのが漏れてました
そういえば去年こんな提案を書きかけてて、でもなんかいまいち練りが足りない感じでお蔵入りにしてたんでした。 https://t.co/OyeAmVM6uI
僕は、やっぱりそれなりの規模のチーム開発とかOSSだとこういう方向性の何かがほしいなぁ、と思ってます。— Akira Matsuda (@a_matsuda) February 16, 2018
rbcuda: Ruby向けCUDA
rbcuda - CUDA integration for Ruby https://t.co/0FCbhqUV7u
— C OSS (@oss_clang) February 18, 2018
CUDAは機械学習方面で初めて見かけました。
つっつきボイス: 「CUDAといえばNVIDIAのライブラリ」
RubyKaigi CFP募集開始
Hello, Rubyists! RubyKaigi 2018 CFP is now open! You can submit your tech talk proposals from now through the end of February.
Don't forget to submit (at least) one if you want to speak at the conference in the beautiful city of Sendai!https://t.co/HLNygIXWcK #rubykaigi— RubyKaigi (@rubykaigi) January 11, 2018
ラジオ: Matzが語るRuby(Awesome Rubyより)
30分です。
SQL
PostgreSQLのロックを理解すれば怖くない(Postgres Weeklyより)
つっつきボイス: 「ぽすぐれのロックと言えば確か3種類」「行とか列とかでしたっけ?」「あと悲観/楽観かな」
PostgreSQLだけでbump chartを生成する(Postgres Weeklyより)
つっつきボイス: 「こういうキモいのもぽすぐれによくある」
柔軟な全文検索の提案(Postgres Weeklyより)
ALTER TEXT SEARCH CONFIGURATION multi_en_de
ALTER MAPPING FOR asciiword, word WITH
CASE english_hunspell WHEN MATCH THEN KEEP ELSE english_stem END
UNION
CASE german_hunspell WHEN MATCH THEN KEEP ELSE german_stem END;
つっつきボイス: 「多言語検索↑が目についたので」「vectorに入れてるなら速そうではある」
JavaScript
polacode: コード部分だけスクショを撮るツール(GitHub Trendingより)
- リポジトリ: octref/polacode
つっつきボイス: 「これはポラロイドのpolaですね: 自分でトリミングしなくていいそうです」「おっと、これはVS Code専用みたい」「ソウダッタカ(´・ω・`)」
basicScroll: parallax scrollライブラリ(GitHub Trendingより)
See the Pen basicScroll Default Demo by Tobias Reich (@electerious) on CodePen.
つっつきボイス: 「こういう上下方向のときにもparallaxって言うんでしたっけ?」「ですね」「スクロールに追従して変わるのは総じてparallax: キライですけど」「まあ飽きられるのも早そう」
vuetify: Vue.jsでMaterial Design(JavaScript Weeklyより)
- リポジトリ: vuetifyjs/vuetify
- サイト: https://vuetifyjs.com/en/
つっつきボイス: 「ビューティファイ!」「とりあえず名前がいいなー」「名前大事」
オピニオン: JavaScriptのPromiseは中立とは言えない(JavaScript Weeklyより)
// 同記事より
function fn(resolve, reject) {
console.log('hello');
// ...
}
console.log('before');
const promise = new Promise(fn); // fn() is called immediately!
console.log('after');
- lazyではない
- キャンセルできない
- 同期的ではない
then()
はmap()
とflatMap()
のミックス
つっつきボイス: 「まあJSのPromiseって一種のシンタックスシュガー的なもので、見た目はそうでも中身はそうじゃないですしね」「カリー化とか頑張ればできるのかも知らんけど」
ass-js: JavaScriptで書かれたx86アセンブラ(JavaScript Weeklyより)
- リポジトリ: streamich/ass-js
# 同リポジトリより
(‿*‿)
Assembler.js
つっつきボイス: 「この名前とアイコンw」「此奴、狙ってるナ」「ウォッチに載せていいものかかどうか考えてしまった: 少なくともアイキャッチには入れられない~」「やってることは普通にアセンブラですね」
CSS/HTML/フロントエンド
デザインの参考になるUI/UXポートフォリオ
UI/UX デザイナーのポートフォリオがまとまったページ。300近く載ってる。いろんなデザイン事例を知るのに良い。
レジュメも載ってて、英語なので日本の市場では役立たないかもしれないけど、デザインの経験をどう簡潔に書くのかという点においては日本でも参考になりそう。https://t.co/VuB2VwkYTG— 灰色ハイジ / Haiji Namika (@haiji505) February 21, 2018
つっつきボイス: 「非デザイナーとしてはこういうサイトを用途に応じて使いこなすテクニックが知りたい」「確かにー: いろんなデザインはあってもどれを選んだらいいのやら」
CSS variable、これだけは知っておきたい(Frontend Focusより)
See the Pen Component Variations with CSS Variables by Ohans Emmanuel (@ohansemmanuel) on CodePen.
つっつきボイス: 「Sassなら変数アルヨ!」「ま、それを生CSSで書けるのがいいところ」
Jekyllを使って技術ブログ向けのSEOをする(RubyFlowより)
http://jekyllthemes.org/はJekyll CIとは別だったんですね。
つっつきボイス: 「Jekyllはとてもいいですよ: 何といってもGitHubが公式にサポートしてる」「知らなかった」「自分の手元にRuby環境がなくてもGitHubにプッシュすればデプロイまでやってくれて優秀」
どんな検索UIがあるかざっと集めてみた(RubyFlowより)
つっつきボイス: 「これの5倍ぐらいエントリがあればうれしいかなー」「まあ自分用のメモみたいなので」
その他
gitleaks: Gitリポジトリの秘密キーなどを検索(GitHub Trendingより)
- リポジトリ: zricethezav/gitleaks
つっつきボイス: 「おー、Gitのcommitログも検索してる!」「エグい」「これはpublicにさらす前とかに使うとか、CIに入れておくとよさそう」「CIに何でもやらせるとますます遅くなるけどな」
猫アバターの人のポッドキャスト
システムズプログラミングのポッドキャスト #tcfm 第6回を公開しました。今回も三浦さんとプログラミング言語の話をしてます。今回も編集しててちょっと笑ってしまったりとかしたので結構面白いです。お楽しみください。 https://t.co/aI8opLS50F
— Rui Ueyama (@rui314) February 18, 2018
まだ一度しか聴いてませんがすごく面白かったので。
本格暗号本PDFが無料で公開
.@herumiさんの暗号技術の本、驚異的によいのでは。これが全文PDF無償公開って一体なぜ?というレベル。 https://t.co/rUCVvHiEhV
— Rui Ueyama (@rui314) February 17, 2018
つっつきボイス: 「TeXフォーマットか」「楕円曲線とかめちゃガチな内容!」
番外
教会の尖塔をWi-Fiアンテナ設置場所に
これいいな。日本だとこういうの何になるんだろう? / “英国、教会の尖塔をWiFi接続に利用へ 政府と国教会が合意 写真1枚 国際ニュース:AFPBB News” https://t.co/vNXe4yFizS
— katsyoshi (@katsyoshi) February 19, 2018
避雷針は前からあるから心理的な抵抗は大したことないと思うけど、装置の雷対策も必要そうですね。
CSSでキーロガーは作れるか
- リポジトリ: maxchehab/CSS-Keylogging
今はリードオンリーになっています。実際には動かなかったらしいとも。
NHKの無料素材動画
加工も可能な動画素材です。
「シークワーサー」の表記ゆれ
構文図すごい! TikZか何かでもっときれいにできないかな https://t.co/UQcRyoLkIB
— Haruhiko Okumura (@h_okumura) February 23, 2018
科学写真コンテスト
Second SNSF Scientific #Image Competition! https://t.co/8WhTvfq2C2 @bielerfototage #photography #video #science #research #SwissScienceImage pic.twitter.com/41Qrn7qFzc
— SNSF (@snsf_ch) November 13, 2017
参考: 「原子1個」を捉えた画像。英国の科学写真コンペ優秀賞も納得です。 | ギズモード・ジャパン
むかしむかし
今週は以上です。Ruby25でお会いしましょう。
バックナンバー(2018年度)
週刊Railsウォッチ(20180216)Rails 5.1.5リリース、DHHのYouTubeチャンネルは必見、Ruby Toolboxが運営再開ほか
- 20180209 RubyにMJIT初マージ、高速JSON API gem、Railsにparallel-testingブランチほか
- 20180202 Rails 5.2.0 RC1と5.1.5.rc1リリース、Rails 6開発開始、メソッド絵文字化gemほか
- 20180126 Bootstrap 4登場でbootstrap_form gemが対応、PostgreSQLやnginxの設定ファイル生成サービスほか
- 20180119 derailed_benchmarks gem、PostgreSQLをGraphQL API化するPostGraphile、機械学習でモック画像をHTML化ほか
- 20180112 update_attributeが修正、ぼっち演算子
&.
はObject#try
より高速、今年のRubyカンファレンス情報ほか
今週の主なニュースソース
ソースの表記されていない項目は独自ルート(TwitterやRSSなど)です。