週刊Railsウォッチ(20180330)春のリリースラッシュ: Rails 5.1.6/5.0.7とRuby 2.5.1など、Ruby 2.2は3月でメンテ終了ほか

こんにちは、hachi8833です。Rails Developers Meetup 2018が無事終了しましたね。終わった後は久々のスタミナゼロ状態でした。関係者の皆さま、本当にありがとうございました。

年度末の忙しさの中、桜咲く3月最後のウォッチ、いってみましょう。
今回からh2タグとh3タグにアンカーを付けました。

臨時ニュース

Rails 5.1.6と5.0.7リリース

Rails 5.2.0より先に既存の更新がリリースされました。railtiesのChangelogを見た感じでは、後述のRuby 2.2.10リリースを受けて出されたという一面もあるようです。


rubyonrails.orgより

Ruby 2.5.1リリース: バグ/セキュリティ修正中心(Ruby公式ニュースより)


ruby-lang.orgより

本体および標準ライブラリのバグやセキュリティ修正です。過去のバージョンにもバックポートされました。

記念写真というより証拠写真でしょうか。

中の人のブログ↓も公開されています。


つっつきボイス: 「webrickの脆弱性などなど」「webrickを本番で使う人はまずいないでしょうねー」「確かに」

いるのかな?

参考: ruby/webrick

#unpackって例のC言語のprintfみたいないやらしーやつでしたっけ」「16進まみれのw」「pack/unpackこの間しぶしぶ使ったけど、@指定できるとか知らんわー」

参考: Rubyリファレンスマニュアル String#unpack

Ruby 2.2系は3月いっぱいでメンテナンス期間終了

同じプレスリリースです。極めて重要なセキュリティ修正を除き、今後2.2は更新されなくなります。


つっつきボイス: 「Rubyは毎年リリースされているから終了も毎年あるわけですね: 3月はさよならのシーズンというか」「サポートなくても動くは動くけどなっ」「2.2以下のRuby、あのアプリとかこのアプリとかあったかなー」「それより先にRails 5にアップデートせいという感じか」「Rubyをアップグレードする方が楽かな」

Rails: 今週の改修

今回の公式情報はまとめ的な感じです。masterなので基本的にRails 6向けですね。
公式で紹介されている今回のコミットログはいつになくあっさりしているので、気軽に読めますね。

Active StorageでAWS S3 SDK認証オプションを完全サポート

# activestorage/lib/active_storage/service/s3_service.rb#L9
   class Service::S3Service < Service
     attr_reader :client, :bucket, :upload_options

-    def initialize(access_key_id:, secret_access_key:, region:, bucket:, upload: {}, **options)
-      @client = Aws::S3::Resource.new(access_key_id: access_key_id, secret_access_key: secret_access_key, region: region, **options)
+    def initialize(bucket:, upload: {}, **options)
+      @client = Aws::S3::Resource.new(**options)
       @bucket = @client.bucket(bucket)

       @upload_options = upload

つっつきボイス:**optionsで素直にまるっと渡せるようになったってことか」「渡しても全然大丈夫だったと」「パラメータで{}**が隣り合っていると一瞬ドキっとしちゃいます: どっちに落っこちるんだみたいな」「そんなんばっかしですよもうw」

MySQL2のサポート

# activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb#L6
-gem "mysql2", "~> 0.4.4"
+gem "mysql2", ">= 0.4.4", "< 0.6.0"

バージョン書き換えただけです。

i18nの@virtual_path置換え結果をメモ化

# actionview/lib/action_view/helpers/translation_helper.rb#L124
       private
         def scope_key_by_partial(key)
-          if key.to_s.first == "."
+          stringified_key = key.to_s
+          if stringified_key.first == "."
             if @virtual_path
-              @virtual_path.gsub(%r{/_?}, ".") + key.to_s
+              @_scope_key_by_partial_cache ||= {}
+              @_scope_key_by_partial_cache[@virtual_path] ||= @virtual_path.gsub(%r{/_?}, ".")
+              "#{@_scope_key_by_partial_cache[@virtual_path]}#{stringified_key}"
             else
               raise "Cannot use t(#{key.inspect}) shortcut because path is not available"
             end

つっつきボイス:@virtual_pathとな?やってることはメモ化だけど」「あ、#tのあたりか!: どこでどうなってるのかようわからんやつ」

参考: ActionView::Helpers::TranslationHelper#translate#tはこれのエイリアスです

「ついでに質問しちゃいますけど、ActionViewにあるRails備え付けのビューヘルパーと、自分で書いたビューヘルパーって、どこかで一箇所に集まっちゃうというかまとめてグローバルになっちゃうんですよね?」「そうですね、同じところというかview_contextっていうのがあって、レンダリングではそいつが大もとみたいな感じになってるんですよ」「あー」「そしてそいつにヘルパーどもがインクルードされまくってるんですよ」「なるほどねー!」「自分でビューヘルパーひとつも書いてなくても、既にヘルパーが大家族状態ってことか」

参考: view_context

「ActionViewヘルパーの他にもActionController::HelpersやらAbstractController::Helpersやらもあって、そういうのが大挙してview_contextに押し寄せてる感じなんですよ(爆)」「やべー」「やべー」「インスタンス変数とかもこいつにどんどんアサインされていって居座るし」「おとろしい…」

「Railsでコントローラに書いたインスタンス変数をビューで参照できるなんて、裏でこっそり何かやってないとできるはずがないですからね」「そうそう、その設計思想がどうもなー: ビューに渡したいものがあったら自分で書きたいわ」「ビューに渡したくないインスタンス変数だってあるのに、全部渡されちゃう」「でインスタンス変数を増やすとだんだんわけわからなくなってくると」

追伸

morimorihogeさんから補足情報をいただきました。オプションで変えられるということです。

参考: views_assigns

ActionDispatch::StaticのパスをUS-ASCIIからASCII-8BITに変更

さようなら.htmlのような日本語ファイル名も使えるようにということのようですが、極力したくないかも。

# actionpack/lib/action_dispatch/middleware/static.rb#L37
       if match = paths.detect { |p|
-        path = File.join(@root, p.dup.force_encoding(Encoding::UTF_8))
+        path = File.join(@root, p.b)
         begin
           File.file?(path) && File.readable?(path)
         rescue SystemCallError
           false
         end

       }
-        return ::Rack::Utils.escape_path(match)
+        return ::Rack::Utils.escape_path(match).b
       end
     end

つっつきボイス: 「static/とかのhtmlファイルなんかが対象ってことですかね」「fixtureにあるactionpack/test/fixtures/公共/foo/さようなら.htmlの「公共」ってsharedのことなんでしょうけど、日本人のセンスではなさそう」

Active JobでQu gemのサポートを廃止

4年も更新のないQuがRails 5.1と互換性がなくなったためで、互換性が戻ることがあればまた追加するようです。

# activejob/test/integration/queuing_test.rb#L84
   test "should supply a provider_job_id when available for immediate jobs" do
-    skip unless adapter_is?(:async, :delayed_job, :sidekiq, :qu, :que, :queue_classic)
+    skip unless adapter_is?(:async, :delayed_job, :sidekiq, :que, :queue_classic)
     test_job = TestJob.perform_later @id
     assert test_job.provider_job_id, "Provider job id should be set by provider"
   end

参考: bkeepers/qu

Ruby 2.6ではURI#unescapeにモンキーパッチを当てない

これは自分で見繕いました。

# activesupport/lib/active_support/core_ext/uri.rb#L3
 require "uri"
 str = "\xE6\x97\xA5"
-parser = URI::Parser.new

-needs_monkeypatch =
-  begin
-    str + str != parser.unescape(str + parser.escape(str).force_encoding(Encoding::UTF_8))
-  rescue Encoding::CompatibilityError
-    true
-  end
-
-if needs_monkeypatch
+if RUBY_VERSION < "2.6.0"
   require "active_support/core_ext/module/redefine_method"
   URI::Parser.class_eval do
     silence_redefinition_of_method :unescape

つっつきボイス: 「Rubyでunescapeをちゃんとできるようになったから、バージョンを見てパッチをやめるってことですね」

Rails

ダウンタイムなしでスキーマ変更するには(Ruby Weeklyより)


つっつきボイス: 「後半ぐらいから『こうだったらいいのに』みたいな雰囲気ですね」「マイグレーション内のafter_deployってRailsのメソッドか?と思ったら見当たらないから手作りというか、こんなのが欲しいってことなんでしょうね」「何をもってしてafter_deployを判断するんだろか?」「マイグレーションにそういうフックがあったとしても怖くて使えないw」

「コメント欄の方も気になっちゃって: こんな条件付きマイグレーション↓ができたらすごくうれしいんだけど方法が見当たらない…と」「それたぶんコントロールしきれないと思うヨ: おとなしく移行のバッチなりrakeタスクなりでやった方がええんではないかしら」「マイグレーション、ただでさえ複雑なのに」

# コメント欄より
class RemoveColumn < ActiveRecord::Migration[7.0]
  on_next_deploy_after RenameColumn
  # ↑こういうのとか↓こういうのとか
  when RenameColumn, deployed_for: 1.week

  def up
     remove_column :posts, :name
  end
end

RailsとTDDとDHHと


つっつきボイス: 「ツイートでリンクされていた永和システムマネジメントさんのブログ記事がとても面白かったので: かの有名なt_wadaさんとの対談シリーズですね」


twop.agile.esm.co.jpより

「『テスト駆動開発自体が自己目的化してしまった』とか」「手段と目的が入れ違ってというか」「何がしたかったのか思い出せなくなったというか」「このあたりとか考えさせられます↓」

だけど、先鋭化したテスト駆動開発や、例えばクリーンアーキテクチャーのような依存を逆転させて清潔にしたレイヤリングとRuby on Railsの強みは明らかに対立関係にあったんですね。
同対談より

「クリーンアーキテクチャってたしかこれ↓じゃ?」「あーそうだった!: morimorihogeさんが勉強会で見せてくれてた」


https://8thlight.com/blog/uncle-bob/2012/08/13/the-clean-architecture.htmlより

「こうしてみるとRailsは元々プロトタイプを素早く作る感じで、そもそもクリーンアーキテクチャとは目指すものが違うというか、だいたいコントローラにアクションが全部集まってるし」「この間のSOLID記事にも反してるし: まあ記事書いた人は反してないって言ってますけどw」「『ここは俺の家だ!』みたいな」

「でDHHが『TDDは死んだ』と宣言してセンセーションを巻き起こしたと」「たしかその当時、ケント・ベックマーティン・ファウラーとDHHの対談がストリーミングで流れてて、『どうしてこうなった』みたいな話をしてましたね」「お、探します」

↓こちらです。Part IVまであってめちゃ長いのでPart Iのみです。

「ところで教条主義って言葉は私の年だと微妙に懐かしいんですけど、これって昔の学生運動のときによく使われた言葉だったんですよね: 『この教条主義者ガー』みたいな感じで」

書籍『Refactoring』(Martin Fowler)第二版がリリース

同書はJava向けですが、Ruby向けのRefactoring for Rubyも定番です。惜しくも日本語版は割とすぐに絶版かつ中古で高値が付いています


つっつきボイス: 「ちょうどそのMartin Fowlerさんの本ですね」「日本語の『リファクタリング:Rubyエディション』、中古で8000円かよ!」「これ、社内に1冊あったはず」「(社内の図書管理システムを参照して)お、あったあった」「これは借りなきゃ損損」「お、図書記録にhachi8833さんが『翻訳がとてもよい』って書いてるゾ」「(忘れてた…)」

Railsで双方向関連付けをテストする(Hacklinesより)

# 同記事より
associations.each do |assoc|

  # stuff from previous example
  if too_hard
    next

  # self join (model has an association to the same model)
  elsif assoc.klass == model
    assert assoc.options[:inverse_of].present?, "Only half of a self-join association is defined in app/models/#{model.to_s.underscore}.rb. The inverse of :#{assoc.name} is not defined."
    assert model.first.respond_to? assoc.options[:inverse_of], "The inverse of :#{assoc.name} is not functioning correctly. Check app/models/#{model.to_s.underscore}.rb."

  # Explicitly defined inverse association. Must have an inverse defined in both models.
  elsif assoc.options[:inverse_of].present?
    assert associated_object = assoc.klass.to_s.singularize.camelize.constantize.first, "#{assoc.name.to_s.camelize} not present in fixtures. Check test/fixtures/#{assoc.name.to_s.pluralize.underscore}.yml.\nAssociation name: #{assoc.name}\nAssociated object: #{assoc.klass}"
    model_method = assoc.options[:inverse_of].to_s
    assert associated_object.respond_to?(model_method) || associated_object.respond_to?(model_method.pluralize), "#{associated_object.class.to_s.camelize} is not properly associated with #{model.to_s} via :#{model_method}. Check for the correct association in app/models/#{model.to_s.underscore}.rb."

  # Using an alias to reference another model. Should probably have inverse relationships explicitly defined.
  elsif assoc.name != assoc.klass
    assert associated_object = assoc.klass.to_s.singularize.camelize.constantize.first, "#{assoc.name.to_s.camelize} not present in fixtures. Check test/fixtures/#{assoc.name.to_s.pluralize.underscore}.yml"
    model_method = model.to_s.underscore
    assert associated_object.respond_to?(model_method) || associated_object.respond_to?(model_method.pluralize), "#{associated_object.class.to_s.camelize} is not properly associated with #{model.to_s} using :#{model_method} as the inverse of :#{assoc.name}. Check for the correct associations and :inverse_of attributes in app/models/#{assoc.klass.to_s.underscore}.rb and app/models/#{model.to_s.underscore}.rb."

  # Normal bidirectional association
  else
    # do the stuff from earlier
  end
end

つっつきボイス: 「な、何だこれはw」「こんなにしてまでアソシエーションが抜けてないかどうかをテストする意味ってあるんだろか?」「コード書き終わったらいらないですよね、確かに」「テスト残す価値ないわ」「文章まだ読んでませんが、もしかしてたとえば外注先のコード品質が信用できなくて、怒りに任せてこういうテストを書いてから発注したとかですかね?」「テストファーストの匂いがする」

「ApplicationRecordにだったらこれっぽいのを書きたいかなと思ったりしますね: cancancanにあるcheck_authorizationなんかそうですけど、これをApplicationRecordに書いておくと、継承先でauthorizeを呼んでないときにエラーになる」「おー!」

「つかアソシエーションがあるかどうかをrespond_to?でテストするのが一番楽じゃないっすか?」「確かにー」「Railsチュートリアルにも確かそんな感じで書いてありましたよ: respond_to? childrenみたいに」「そうじゃなくてもモデル名使えばいいのに」

[翻訳]RailsチュートリアルがRails 5.0に完全対応しました!(第4版)?

コールバックとインスタンス変数

# 『3年以上かけて培ったRails開発のコツ集大成(翻訳)』2.より
class UsersController
  before_action :load_resource

  def index
    # @usersで何かする
  end

  def show
    # @userで何かする
  end

  def create
    # @userで何かする
  end

  def update
    # @userで何かする
  end

  def destroy
    # @userで何かする
  end

  private
    def load_resource
      case params[:action].to_sym
      when :index
        @users = paginate(apply_filters(User.all, params))
      when :create
        @user = User.new(create_params)
      when :show, :update, :destroy
        @user = User.find(params[:id])
      end
    end
end

つっつきボイス: 「以前のTechRacho記事『3年以上かけて培ったRails開発のコツ集大成(翻訳)』でダントツで疑問が多く寄せられた『2. コントローラにload_resourceを書く』です」「うん、これキライ: indexしかないとかならまあわからんでもないけど、caseとかまで書いちゃうのはなぜ?みたいな」「厳密にスコープを分けたいとか常に何らかのスコープを通したいときとかなんですかね:気持ちはワカルけど」「全アクションに業務ロジックを書きたくないとか」「でもたとえばindexがいなくなったら台無し」「DRYに書こうとしすぎた感じですかね」

「怖いのは、新人くんとかにこれを盲目的にやられてしまうことかな」「あーたしかに」「何だかこう、コピペの匂いがするんですよね: これコピペしてやっとけって指導するみたいな」「これならコピペで動いちゃいますからね」
「このコードだとindexをpagenateしてるけど、後で特定のindexでpagenateを使わないように変えようとすると詰む」「CSV出力みたいに、indexをページネーションしないとかざらにありますしね」

3年以上かけて培ったRails開発のコツ集大成(翻訳)

(社内雑談より)Railsの設計で崩れやすいのは例外処理とロギング

つっつきボイス: 「この間タバコ吸いながらそういう話題になったので」「経験上、例外処理もロギングもまったく念頭にないまま書かれた素人さんコードに、後からそれを足そうとして詰む、みたいなのがよくあるかな」「ロギングはともかく、例外の方はそもそも正常系がぜんぜんちゃんとしていなかったりすると例外の拾いようがなくなって作り直す方が早かったり」「エラーの扱いが全然一貫してなかったりとか」「true/falseで返すなよ、とか」

「ボクが例外処理が好きなのは、異常時にガード的にどんどん終わってくれるからコードがシンプルになるところ: if書かなくていいし」

Rubyスタイルガイドに『例外処理を制御フローに使わないこと』ってあったのを思い出しました」「そりゃやっちゃダメですよねw」「いわゆるgoto的に使うもんじゃない」

参考: Avdi Grimm氏の有名な「Exceptional Ruby」のスライドです。


Exceptional Rubyより

参考: Exceptional Ruby — 同氏の著作です。


exceptionalruby.comより

その他記事など

Ruby trunkより

桁数が多いときにFloat#round(n)の結果がずれる(継続)

# 同issueより
3.0e-31           #=> 3.0e-31
3.0e-31.round(31) #=> 3.0000000000000003e-31

つっつきボイス:Rational#to_fで回避する、と」「Floatって忘れた頃につまずきますよね」

Rationalがデフォルトだったらいいのになんて思ってしまいました。

コロンを変なところに置くと落ちる->(#14261と重複)

def a(x)
  case x
  when A
    :      # これ
  when B, C
  end
end

つっつきボイス: 「おー、これで落ちるのか」「『よくぞ見つけた』みたいなこと書いてる」「と思ったら#14261で修正されてた」「nobuさん、凄っ」

(提案)ハッシュで特定のキーへの最短パスを取るメソッドが欲しい(継続)

# 同issueより
{
  :a => {
    :name => "abc"
  },
  :b => {
    :name => "xyz"
  },
}
deep_key(:name) => [:a]

つっつきボイス: 「これは欲しいときあるかも」「Rubyのハッシュキーの順序が保証されていなかったら大変そうですね」「『他の言語にあるからRubyでもやろうよ』というアピールは効きそう」「たしかPythonも最近順序が保証されるようになってた」

参考: Rubyリファレンスマニュアル Hash

Ruby

k0kubunさんのbenchmark/driver

ベンチマークの別記事も見つけました。


つっつきボイス: 「k0kubunさん今回は英語ブログだけ書いてるみたいですね: 両方書くのは大変だからかな」「そういう境地になりたいw」「ちょうど昨日derailed_benchmarksのREADME翻訳を出したところでした↓」

Rails: 多機能ベンチマークgem「derailed_benchmarks」README(翻訳)

あまり知られてないっぽいRubyのフック系メソッドたち



つっつきボイス:includeじゃなくてincludedみたいに過去分詞というか受動態というか」「たとえばincludedは、includeしたときに発動するコールバックみたいな感じですね」「この名前、コールバックっぽく見えないなぁ: on_includeとかなら…」「でも何度も見かけるうちにわかるようになっちゃいましたねw」「method_removedとかmethod_undefinedとか他にもまだまだあるんですね」

「そういえばincludeされるに呼ばれるフックとかもあった気がする: んーと、append_featuresだ↓」「こりゃすげえ」「こんなことまでできちゃうの?って正直びっくりでしたね」「呼び出しコスト大丈夫なのかしらん?」

参考: append_features

「フレームワーク的なものを作るときに欲しいやつで、業務で使ったらヤバイ」「includedは、言ってみればRailsのconcernsみたいなものだし、ありかな」「おー、concernsをそうやって説明してもらったら何だか腑に落ちた(気がする)」

参考: ActiveSupport::Concern

Browser: Rubyでブラウザ情報を検出するライブラリ(Ruby Weeklyより)

# 同リポジトリより
...
browser.device
browser.device.id
browser.device.name
browser.device.blackberry_playbook?
browser.device.console?
browser.device.ipad?
browser.device.iphone?
browser.device.ipod_touch?
browser.device.kindle?
browser.device.kindle_fire?
browser.device.mobile?
browser.device.nintendo?
browser.device.playstation?
browser.device.ps3?
browser.device.ps4?
browser.device.psp?
browser.device.silk?
browser.device.surface?
browser.device.tablet?
browser.device.tv?
browser.device.vita?
browser.device.wii?
browser.device.wiiu?
browser.device.xbox?
browser.device.xbox_360?
browser.device.xbox_one?
...

つっつきボイス: 「Wii UとかXboxまであるじゃないですか」「何だかスゴイ」
「遠い昔に、当時の同僚であらゆるブラウザのUAヘッダをコレクションしてた人がいて、新しい携帯を買うたびにヘッダ取らせろってせがまれたのを思い出した」「今だともうコンプリート不可能ですね」

Module.class_execLiquidを動かす(RubyFlowより)

Object.instance_execModule.class_execは似ているけどちょっと違うみたいです。翻訳リクエストしてみます。

GnuPGをRubyで実装した話(RubyFlowより)

multi.rbって使われてる?

# 元記事より
require 'rubygems'
require 'multi'
multi(:fact, 0) { 1 }
multi(:fact, Integer) { |n| n * fact(n-1) }

for i in (0..5)
  puts "fact(#{i}) ==> #{fact(i)}"
end

Matzのプログラミングのおきてをネットでけちけち読んでいて「マルチメソッド」という見慣れない言葉を見つけたので探してみました。


つっつきボイス: 「マルチメソッドって有名なんですか?」「知らないー」「(コードを見て)ほほう、なるほどー❤️」「おーなるほどー❤️」「すみません、面白みのところ教えてください🙇」

「普通だったらfactメソッド作ってifで分岐するところだけど、Haskell的にifなしで書ける: 0が来たときは1つめのmulti、それ以外が来たときは2つ目のmultiが動くみたいな」「あー!言われてみればすごく数式っぽい: 数学的帰納法みたいな形」「関数型っぽいすね」
「まあでもこの書き方だと、パラメータの違う同じメソッドを複数定義するから、定義があちこちで増えたときにどれに解決するのかとかいろいろ面倒そう」「業務では使わないだろうなー」「処理として2つのmultiがあるところが自分的には残念: その間に何を実行されるかわからないでしょ?」「おー確かに」「処理とは別に定義としてこういうのを書けるんだったらきっと好き」

そういえば日本語記事にも「おもしろいんだがあまり使い勝手は良くなかった」って書いてありました。

プログラミングと直接関係ありませんが、引用したWikipediaにこんなことが書いてあります。

なお、数学的「帰納」法という名前がつけられているが、数学的帰納法を用いた証明は帰納ではなく、純粋に自然数の構造に依存した演繹論理の一種である。2 により次々と命題の正しさが”伝播”されていき、任意の自然数に対して命題が証明されていく様子が帰納のように見えるためこのような名前がつけられたにすぎない。
同Wikipediaより強調

100年遅いですが、個人的には数学的帰納法(mathematical induction)は「数学的誘導法」と訳して欲しかった…

その他記事など

SQL

データベースの「トップN」問題を解決する(Postgres Weeklyより)

CitusData社のpostgresql-topnツールを紹介しています。


つっつきボイス: 「トップN問題って、N+1クエリみたいなアンチパターンとは違いますよね」「たぶんだけど、『トップ5の項目をすべてのカテゴリについて取る』みたいなやつなのかな: それなら確かに面倒かも」「Ruby側で処理すると効率悪いっすね」「DB側でできるんだとしたら便利かもー」

pg_repack: PostgreSQLデータベースのテーブル再編成を最小のロックで

公開しそびれた翻訳記事で紹介されていたので。CLUSTERやVACUUM FULLと違って処理中のテーブルの排他ロックを維持せずにできるそうです。

Awesome PostgreSQL: 精選ソフトウェア/ライブラリ/ツール/リソースリスト(Postgres Weeklyより)

Awesome MySQLを見て作ったそうです。どちらも参考になりそうです。

JavaScript

Vue.jsをRailsのフロントエンドとして使う(Ruby Weeklyより)

// 同記事より
import TurbolinksAdapter from 'vue-turbolinks';
import Vue from 'vue/dist/vue.esm'
import App from '../app.vue'

Vue.use(TurbolinksAdapter)

document.addEventListener('turbolinks:load', () => {
  const app = new Vue({
    el: '#hello',
    data: {
      message: "Can you say hello?"
    },
    components: { App }
  })
})

Conditioner.js: プログレッシブエンハンスメントをストレートに実現するJSライブラリ(JavaScript Weeklyより)

プログレッシブエンハンスメントは、核となるコンテンツを最重要視するウェブデザイン戦略である。この戦略では、エンドユーザーのブラウザーやインターネット接続に合わせて、プレゼンテーション面や機能面で微妙に異なる内容や技術的に困難な内容をコンテンツに漸次追加していく。この戦略の利点として挙げられるのは、すべてのユーザーが任意のブラウザーまたはインターネット接続を用いてウェブページの基本的なコンテンツと機能性にアクセスできることと、より高度なブラウザーソフトウェアまたはより広帯域の接続を有するユーザーには同じページの拡張バージョンを提供できることである。
Wikipedia-jaより

参考: Wikipedia-ja プログレッシブエンハンスメント

(動画)Vue.jsコンサルタントが本当は教えたくない7つの秘密パターン(JavaScript Weeklyより)

その他記事など

CSS/HTML/フロントエンド

VisualInspector: 開発とデザインの齟齬をなくすCanvasFlip社のサービス(Hacklinesより)


sitepoint.comより

チーム開発でレイアウトをピクセル単位でびしっと決められるそうです。この種のサービスが最近増えてきているように思えるので。

display: contentsのしくみ(Frontend Weeklyより)


同記事より

CSSのdisplay: contentsの解説記事です。

参考: MDN display

CSSの「Typed Object Model」について(Frontend Weeklyより)

Typed OMに関するGoogleの技術ブログです。文字列の代わりにオブジェクトベースのAPIを使ってJavaScriptからCSSを制御できるようです。

// 同記事より
el.attributeStyleMap.set('padding', CSS.px(42));
const padding = el.attributeStyleMap.get('padding');
console.log(padding.value, padding.unit); // 42, 'px'

記事の真ん中あたりにデモがあります(マウスオーバーすると四角形が回転する)が、私のChrome 65.0.3325.181では動かず、Chrome Canary 67.0.3383.0だと動きました。なお、今BPS社内ではbabaさんのおすすめでCanary版もインストールするのが流行中です。


developers.google.comより

最初わかってませんでしたが、CSS Object Model(CSSOM)を拡張したのがTyped OMという位置づけだと教えてもらいました。

CSSOM値の文字列を意味のある型付きJavaScript表現に変換(および逆変換)するとパフォーマンス上のオーバーヘッドが大きい。本仕様では、CSSの値を型付きJavaScriptオブジェクトとして公開することで効率よく操作できるようにする。
www.w3.org/TR/css-typed-om-1のAbstractより大意

参考: W3C CSS Typed OM Level 1

デモでついこのジャケットを思い出してしまいました↓。

その他

OracleとGoogleのJavaライセンス裁判

日本語記事です。とてもよくまとまってて助かります。ちょっと前に「GoogleがC#に乗り換えるかも?」みたいな記事を見かけたのですがうまく見つけられませんでした。

ワイのLinux環境で使ってるツールを晒す(2018年度版)

知らないツールもいろいろあって楽しめます。「後はMacのAlfredみたいなランチャーやFenêtreみたいなピクチャ・イン・ピクチャ的ツールがLinuxにもあれば…」だそうです。


www.alfredapp.comより

ReactiveX — Observableパターンのライブラリ

社内アプリチームがRxSwiftなどで盛り上がっているので。


つっつきボイス: 「ReactiveXって、何だかActiveXみたいな名前」「Rxなんちゃらのすべての元祖みたいなやつですね」「Observablesパターンが多用されるらしいんですけど」「Operatorsのページ見るとわかるけど、膨大なオペレーターがあるんですよね↓」「ほんとだー」


reactivex.ioより

参考: Rubyリファレンスマニュアル Observable

「ところでRubyでObservableパターンってよく使います?」「そういえば、確かそのものズバリのObservableってモジュール↓がありますね: #changedでフラグを立てて、notify_observersを呼ぶと、フラグの立っているクラスでupdateメソッドを呼ぶ形で通知する、みたいな」「おー」「かっけー」

# docs.ruby-lang.org: Observableより
require "observer"

class Ticker          ### 定期的に株価をフェッチ
  include Observable

  def initialize(symbol)
    @symbol = symbol
  end

  def run
    last_price = nil
    loop do
      price = Price.fetch(@symbol)
      print "Current price: #{price}\n"
      if price != last_price
        changed       # オブザーバーに通知
        last_price = price
        notify_observers(Time.now, price)
      end
      sleep 1
    end
  end
end

factory_botとかのコールバックでこのライブラリが使われてたような覚えがあります: after(:create)あたりとか」

# https://github.com/thoughtbot/factory_bot/blob/master/GETTING_STARTED.md より
factory :user do
  after(:create) { this_runs_first }
  after(:create) { then_this }
end

[保存版]人間が読んで理解できるデザインパターン解説#3: 振舞い系(翻訳)

C言語のfor文が変わる?

// リンク先より
        static inline int f (void) {
            for (int i = 0; ; ) {
                long i = 1;   // CではできるがC++では無効
                // ...
                return i;     // (おそらく期待に反して) Cでは1が返る
            }
        }

つっつきボイス: 「次のC?」「どういうこったろ?」「うお、for文の中でlong i = 1なんて書いてる: Cって今までこんな書き方できてたの!」「あれ、そもそもCでfor (int i = 0; ; )みたいな書き方許されてたんだっけか?int i = 0の部分をforより前に書かないとダメだった気がするけど: C言語ワカラン」「時間ないので次へー」

「関係ないんですけど、どの回だったかな、例のTuring Complete FM聞いてたら、『Cの関数宣言の何がイヤって、最初に型書くから途中まで読み進めないとそれが関数定義なのかどうかがわからないところ』って話があったんですよ」「ワカルー」「最近多くの言語が型を後ろに書くようになったのって、きっとそれなんでしょうね」

その他記事など

番外

自分の声で


つっつきボイス: 「自分の声ってたいてい聞きたくないやつですけど」「これちゃんとした日本のメーカーじゃないですか」「自分の声をそっくりに出せるのって、アリバイ工作とかに使えたりして?」「他にもアレやらコレやら(略」

宇宙を閉じ込めたような球体

地味に思われがちな固体物理

請負の翻訳でやらせてもらえないやつ

どこかで見たような…

たぶんこれかな。


今週は以上です。

バックナンバー(2018年度)

週刊Railsウォッチ(20180323)Rails 5.2.0 RC2リリース、「サーバーレスなRubyが欲しい」、capybara風JSテストフレームワークCypressほか

今週の主なニュースソース

ソースの表記されていない項目は独自ルート(TwitterやRSSなど)です。

Ruby 公式ニュース

Rails公式ニュース

Ruby Weekly

Awesome Ruby

RubyFlow

160928_1638_XvIP4h

Hacklines

Hacklines

Postgres Weekly

postgres_weekly_banner

Frontend Weekly

frontendweekly_banner_captured

Frontend Focus

frontendfocus_banner_captured

JavaScript Weekly

javascriptweekly_logo_captured

Github Trending

160928_1701_Q9dJIU

Ruby on RailsによるWEBシステム開発、Android/iPhoneアプリ開発、電子書籍配信のことならお任せください この記事を書いた人と働こう! Ruby on Rails の開発なら実績豊富なBPS

この記事の著者

hachi8833

Twitter: @hachi8833、GitHub: @hachi8833 コボラー、ITコンサル、ローカライズ業界、Rails開発を経てTechRachoの編集・記事作成を担当。 これまでにRuby on Rails チュートリアル第2版の半分ほど、Railsガイドの初期翻訳ではほぼすべてを翻訳。その後も折に触れてそれぞれ一部を翻訳。 かと思うと、正規表現の粋を尽くした日本語エラーチェックサービス enno.jpを運営。 実は最近Go言語が好き。 仕事に関係ないすっとこブログ「あけてくれ」は2000年頃から多少の中断をはさんで継続、現在はnote.muに移転。

hachi8833の書いた記事

週刊Railsウォッチ

インフラ

BigBinary記事より

ActiveSupport探訪シリーズ