週刊Railsウォッチ(20180827)Ruby Prize 2018募集開始、Interactor gemとReader Object、書籍『Real World HTTP』、Basecampのヒルチャート機能ほか

こんにちは、hachi8833です。今度はコードの未来で寝不足になってしまいました。

  • 各記事冒頭には⚓でパーマリンクを置いてあります: 社内やTwitterでの議論などにどうぞ
  • 「つっつきボイス」はRailsウォッチ公開前ドラフトを社内有志でつっついたときの会話です👄

今回のウォッチは社内つっつき会当日の台風接近が危ぶまれたので件数を抑えてかつ駆け足気味です。

お知らせ: 第2回「週刊Railsウォッチ 公開つっつき会」開催

現時点ではあと1名様の空きがあります。引き続き募集していますのでお気軽にご応募ください。

Rails: 先週の改修(Rails公式ニュースより)

Rails 6.0でWebpackerをデフォルト化する作業が進行中

カバレッジを手伝ってくれる人募集中だそうです。

#33079は少し前のウォッチでもどさくさに紛れて取り上げていました。

Rails 6ではデフォルトのJavaScriptコンパイラがWebpackerになり、以下の変更が生じる:

  • Webpacker gemがデフォルトでインストールされ、Railsのアプリジェネレータでwebpacker:installが実行されるようになる
  • Action Cableチャンネルのジェネレータは、CoffeeScriptのスタブではなくES6のスタブを生成する
  • Active Storage/Action Cable/Turbolinks/Rails-UJSは、デフォルトでapp/javascriptにあるapplication.jsパックによって読み込まれる(自分でオプトアウトしない限り)
  • Active Storage/Action Cable/Turbolinks/Rails-UJSのnpmモジュールはデフォルトのpackage.jsonの依存リストに自動で含まれる
  • Sprocketsで使われるすべてのJavaScript関連の追加機能(圧縮や難読化など)はデフォルトでは設定もインクルードもされなくなる
  • scaffoldジェネレータは今後デフォルトでJavaScriptのスタブを生成しなくなる


つっつきボイス:「WebpackerになればなったでJSエンジンが必要になってくるので、今度はインストール要件が増えるんですよね〜😅」「ファイル数も増えますね😢」「さしあたってRailsを初めてインストールする人の手順が増えるという😆」「yarnはパッケージの管理に使ってるんでしたっけ?」「ですね」

Cookieにpurposeメタデータが追加

まとめ
このPRはcookieにpurposeメタデータを追加することで、あるcookieの値を別のcookieにコピーして使えないようにする。

その他の情報
config.action_dispatch.use_cookies_with_metadataをオンにすると、expirypurposeメタデータが署名/暗号化済みcookieの内部に埋め込まれ、かつその署名/暗号化済みcookieの値がコピペされたかどうかを検証する。
従来のcookie設定(purposeexpiryメタデータを使わないもの)も引き続き使える。
同PRより大意

# actionpack/lib/action_dispatch/middleware/cookies.rb#L
+        def cookie_metadata(name, options)
+          if request.use_cookies_with_metadata
+            metadata = expiry_options(options)
+            metadata[:purpose] = "cookie.#{name}"
+             metadata
+          else
+            {}
+          end
+        end

つっつきボイス:「このpurposeメタデータの資料がググっても見当たらなくって」「見た感じRFCのものではなくてRails独自っぽい?🤔」

Array#extract!メソッドを追加

# activesupport/lib/active_support/core_ext/array/extract.rb#L3
+ class Array
+   # Removes and returns the elements for which the block returns a true value.
+   # If no block is given, an Enumerator is returned instead.
+   #
+   #   numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+   #   odd_numbers = numbers.extract! { |number| number.odd? } # => [1, 3, 5, 7, 9]
+   #   numbers # => [0, 2, 4, 6, 8]
+   def extract!
+     return to_enum(:extract!) { size } unless block_given?
+      extracted_elements = []
+      reject! do |element|
+       extracted_elements << element if yield(element)
+     end
+      extracted_elements
+   end
+ end
# 同PRより
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
odd_numbers = numbers.extract! { |number| number.odd? } # => [1, 3, 5, 7, 9]
numbers # => [0, 2, 4, 6, 8]

つっつきボイス:「RubyのArray#select!とどう違うのかなと思って」「探してみたけど!なしのArray#extractはないみたい」「ちなみに破壊的メソッドはだいたいメモリ消費が少なめではありますね」

実際に動かしてみました。どちらも破壊的メソッドですが、変更時にselect!はselfを改変してそれを返すのに対し、extract!は抽出した配列を返し、selfにはその残りが置かれるということですね。

## select!の場合
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
#=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
odd_numbers = numbers.select! { |number| number.odd? }
#=> [1, 3, 5, 7, 9]
numbers
#=> [1, 3, 5, 7, 9]

## extract!の場合
class Array
  def extract!
    return to_enum(:extract!) { size } unless block_given?
    extracted_elements = []
    reject! do |element|
      extracted_elements << element if yield(element)
    end
    extracted_elements
  end
end

numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
odd_numbers = numbers.extract! { |number| number.odd? }
#=> [1, 3, 5, 7, 9]
numbers
#=> [0, 2, 4, 6, 8]

参考: instance method Array#select! (Ruby 2.5.0)

ブロックが false を返した要素を自身から削除します。 変更があった場合は self を、 変更がなかった場合には nil を返します。

a = %w{ a b c d e f }
a.select! {|v| v =~ /[a-z]/ }   # => nil
a # => ["a", "b", "c", "d", "e", "f"]

ブロックが与えられなかった場合は、自身と select! から生成した Enumerator オブジェクトを返します。
docs.ruby-lang.orgより

rake dev:cacherails dev:cacheに移動

# railties/lib/rails/commands/dev/dev_command.rb#L3
+ require "rails/dev_caching"
+  module Rails
+   module Command
+     class DevCommand < Base # :nodoc:
+       desc "Toggle development mode caching on/off"
+       def cache
+         Rails::DevCaching.enable_by_file
+       end
+     end
+   end
+ end

つっつきボイス:「またひとつrakeコマンドが非推奨になりました」「dev:cacheって割と最近入った機能だった気がする」「そうだったかも」

↓これでした。

[Rails 5] rails dev:cacheコマンドでdevelopmentモードでのキャッシュを簡単にオン・オフできる

numericalityバリデータがカスタムgetterから影響されないよう修正

ここからはコミットリストから見繕いました。

# activemodel/lib/active_model/validations/numericality.rb#L21
       def validate_each(record, attr_name, value)
         came_from_user = :"#{attr_name}_came_from_user?"
         if record.respond_to?(came_from_user) && record.public_send(came_from_user)
          raw_value = record.read_attribute_before_type_cast(attr_name)
+         elsif record.respond_to?(:read_attribute)
+           raw_value = record.read_attribute(attr_name)
        end
        raw_value ||= value
          if record_attribute_changed_in_place?(record, attr_name)
           raw_value = value
         end

つっつきボイス:「確かにgetterを自前で書いていればこれ必要そう: getterがattributeに既にあるならそっちを使うべきだろうし」「numericalityっていかにも造語っぽい」「これはバリデーションのオプションですね↓」

参考: numericality - リファレンス - - Railsドキュメント

Active Storageフォームでsubmitボタンを複数サポート

# activestorage/app/assets/javascripts/activestorage.js#L857
  var processingAttribute = "data-direct-uploads-processing";
+   var submitButtonsByForm = new WeakMap;
  var started = false;
  function start() {
    if (!started) {
      started = true;
+       document.addEventListener("click", didClick, true);
      document.addEventListener("submit", didSubmitForm);
      document.addEventListener("ajax:before", didSubmitRemoteElement);
    }
  }
+   function didClick(event) {
+     if (event.target.tagName == "INPUT" && event.target.type == "submit" && event.target.form) {
+       submitButtonsByForm.set(event.target.form, event.target);
+     }
+   }

つっつきボイス:「これはJavaScriptの修正、と」「複数のsubmitボタンというと、縦長のページのトップとボトムに同じボタンがあったりとか」「GitLabのこういうボタン↓なんかもそうですね」

Rails

ActionCableも臭うのか?(Ruby Weeklyより)

Noah Gibbsさんの記事です。


つっつきボイス:「FayeJuggernautよりはいいけれどと認めつつ『ActionCableって必要?』というそもそも論っぽい」「まあよく言われる話ではある: サブスクライバをサーバーでやると複雑になりがちだし、pub/subをアプリケーションサーバーでやるより切り離しちゃえば?というのももっともだけど、Railsでまとめてやりたいということなんだろうし、モデルで扱いたいというニーズもあるだろうし☺️」

Punditのベストプラクティス(Ruby Weeklyより)

# 同記事より
class PostPolicy < ApplicationPolicy
  # ジェネレータで生成されたアプリケーションポリシースコープを継承する
  class Scope < Scope
    def resolve
      if user.admin?
        scope.all
      else
        scope.where(published: true)
      end
    end
  end

  def update?
    user.admin? or not record.published?
  end
end

つっつきボイス:「Punditは個人的に肌に合わないけど」「cancancanが好きって言ってましたね」「割と普通のことを書いてるかな: スコープ↑を理解する話とか、コントローラでrescue_from使って認証エラーを拾う↓話とかもあるけど」「Scope < Scopeってナニソレ?😳」「こんな書き方ができるのね😆」

# 同記事より
class ApplicationController < ActionController::Base
  protect_from_forgery
  include Pundit

  rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized

  private

  def user_not_authorized
    policy_name = exception.policy.class.to_s.underscore

    flash[:error] = t "#{policy_name}.#{exception.query}", scope: "pundit", default: :default
    redirect_to root_path
  end
end

Fakerbot: Fakerが手放せない人に(Ruby Weeklyより)

# 同リポジトリより
$ gem install fakerbot
$ fakerbot list
# Faker::BackToTheFuture
# ├── quote
# ├── date
# └── character
# Faker::Finance
# └── credit_card
# ....

つっつきボイス:「Fakerと言えばテストなんかで使う架空の名前を取れるヤツですね」「Fakerのどこに何があるのかをコマンドラインでさっと調べられるのか: しょっちゅう使うならこういう探し方したいのはワカル」「Fakerって日本語データもあった気が」「日本語ロケールあるし、こういう既存のデータで拡張もできますね↓😎」

ランダムな日本語のデータを生成するGemまとめ - Qiita


stympy/fakerより

go-on-rails: RailsアプリをGoコードに変換


同リポジトリより


つっつきボイス:「まだアルファ版っぽい感じで、よほど単純なRailsアプリじゃないと変換できなさそうな雰囲気でした: とりあえずオレオレRailsアプリを変換して生成されたgo_app↓を動かしてみると、普通のデフォルトRailsページが表示されました」

「さようならImageMagick」

そういえばRailsはlibvipsを使う流れになってますね(ウォッチ)。


つっつきボイス:「ImageMagick万能感はヤバいですからね: PDF生成もできるし、動画からの画像切り出しもできるし、GIFアニメーションも生成できるし、画像関係は本当にありとあらゆることができてしまうから💪」「守備範囲そんなに広かったのか😳」「この記事みたいに画像サムネイル作るだけなら明らかにImageMagickはオーバーキルだろうし、もっと軽いソリューションはあってもいいでしょうね」

「ImageMagickというと、gemでインストールしたときにC拡張のコンパイル時間かかるとか面倒という印象でしたが」「それはRMagicでインストールした場合でしょうね、たしか静的コンパイルしてたんじゃなかったかな: MiniMagickならコンパイル走らない(別途ImageMagickライブラリのインストールは必要ですが)」「そっか💦」

ffmpegなんかもそうだけど、ImageMagickってコマンドラインであらゆることをできるようにした結果ものすごいものになったソフトウェアの象徴みたいなところがありますね😆」「😆」

[Rails] MiniMagickでPDFのページ数を取得するときはフォントエラーに注意!


ImageMagickより

InteractorとReader Object(Hacklinesより)

Railsのパターン記事2本です。

# 記事1より
class ReplyToSurvey
  include Interactor::Organizer

  organize CreateResponse, AddRewardPoints, SendNotifications
end

class CreateResponse
  include Interactor

  def call
    responder = context.responder

    survey_response = responder.survey_responses.build(
      response_text: context.answers[:text],
      rating: answers[:rating]
      survey: context.survey
    )

    if survey_response.save
      context.survey_response = survey_response
    else
      context.fail!(errors: survey_response.errors)
    end
  end
end

つっつきボイス:「InteractorってService Object的なもの?」「これもクリーンアーキテクチャ系の設計パターンのひとつかも: ビジネスロジックでService Objectに相当する口の部分をInteractorと呼ぶ人たちもいたと思う」「😃」

そういえば以前の翻訳記事↓にもInteractor gemが登場してたのを後から思い出しました💦。チェインできることと失敗時にロールバックできる点がポイントでした。

Railsコードを改善する7つの素敵なGem(翻訳)

# 元記事2より
# app/readers/user_reader.rb
class UserReader
    include Enumerable

    def initialize(params = {})
        @params = params
    end

    def each(&block)
        User.all.each(&block)
    end

    private

    attr_reader :params
end

つっつきボイス:「こちらはReader Objectというやつだそうです」「パターン名として見たことはないけど、どうやら参照専用のコレクションマッパーでしょうねこれは」「それも知らなかった💦」「Readerという名前を付けて渡すことで参照のみであることを強調する: ActiveRecordだと更新削除もできてしまうので」「ふむぅ」「Query Objectとはまた違う感じかな…参照のみの検索フォームで使うForm Objectにやや近い位置づけのようにも見える」

参考: データマッパー

元記事2の後半ではpagy gem↓をReader Objectと組み合わせています。

Rails:「Pagy」gemでRailsアプリを高速ページネーション(翻訳)

その他Rails


Ruby trunkより

利用頻度の低い関数にcold属性を指定してパフォーマンスを改善


つっつきボイス:「gccのcold属性!」「じわっと改善されたみたいですね😋」

参考: Function Attributes - Using the GNU Compiler Collection (GCC)coldについて記載あり

引数のarray生成を減らしてパフォーマンスを向上

# 同issueより
def rest_method(*args) #-> arrayが2つ生成される
end

def post_method(*args,last) #-> arrayが3つ生成される
end

つっつきボイス:「このarrayってどのarrayなんでしょう?」「Rubyの内部処理でしょうね」「やっぱりC言語のarrayでしたか」

Ruby

bloomfilter-rb: ブルームフィルタのRuby実装

# 同リポジトリより
require 'bloomfilter-rb'

bf = BloomFilter::Native.new(:size => 100, :hashes => 2, :seed => 1, :bucket => 3, :raise => false)
bf.insert("test")
bf.include?("test")     # => true
bf.include?("blah")     # => false

bf.delete("test")
bf.include?("test")     # => false

# Hash with a bloom filter!
bf["test2"] = "bar"
bf["test2"]             # => true
bf["test3"]             # => false

bf.stats
# => Number of filter bits (m): 10
# => Number of filter elements (n): 2
# => Number of filter hashes (k) : 2
# => Predicted false positive rate = 10.87%

Matzのコードの未来に載っていて今頃知りました。データ量が少ないのにO(1)というハッシュ並みの速度でデータの存在確認ができるアルゴリズムだそうです。

参考: ブルームフィルタ - Wikipedia

今はScalable Bloom Filterという強化版アルゴリズムもあるそうです。

参考: Scalable Bloom Filtersとは一体....? - Qiita


つっつきボイス:「ブルームフィルタをRubyで実装したと」「Rubyの実装はだいぶ前のものみたい」「ブルームフィルタみたいな、特定条件において速いアルゴリズムは探すと結構ありますね」「業務で使えそうでしょうか?」「通常の業務ロジックでここまでカリカリにチューニングすることはまずなさそうかなー😎」「スペルチェックを実装する時なんかには便利らしいです」「そういうふうに大量のデータの中に存在するかどうかだけをチェックするにはいいでしょうね」

wavefile: Rubyで音声ファイルを扱う

# 同リポジトリより
require 'wavefile'
include WaveFile

FILES_TO_APPEND = ["file1.wav", "file2.wav", "file3.wav"]

Writer.new("append.wav", Format.new(:stereo, :pcm_16, 44100)) do |writer|
  FILES_TO_APPEND.each do |file_name|
    Reader.new(file_name).each_buffer do |buffer|
      writer.write(buffer)
    end
  end
end

つっつきボイス:「音声ファイルをこんなふうにコードで結合できるのが面白いですね」「.wavファイルのデータ形式はとっても単純だから、こうやって雑にappendしても動く😉」「ファイルのどこから読んでも大丈夫なんでしょうね」「出だしとか末尾が少々壊れてても読み取れるし」

参考: WAV - Wikipedia

コードの振る舞いをlambdaでスッキリさせる(Hacklinesより)

# 同記事より
def qname(qname)
  ->(message, _protocol = nil) do
    eq_case_insensitive(message.qname, qname)
  end
end

つっつきボイス:「Rubyでは普通によく使われる書き方ですね☺️: JSとかでもできますし」「😃」

「Ruby Prize 2018」募集開始

未受賞の個人が対象で、自薦もありだそうです。

tty-pie_chart: キャラクタベースの円グラフ

# 同リポジトリより
require 'tty-pie_chart'
data = [
  { name: 'BTC', value: 5977, color: :bright_yellow, fill: '*' },
  { name: 'BCH', value: 3045, color: :bright_green, fill: 'x' },
  { name: 'LTC', value: 2030, color: :bright_magenta, fill: '@' },
  { name: 'ETH', value: 2350, color: :bright_cyan, fill: '+' }
]
pie_chart = TTY::PieChart.new(data: data, radius: 5)
print pie_chart


同リポジトリより


つっつきボイス:「前回取り上げたchartと打って変わったオールドスタイルがちょっとかわいかったので❤️」「ザ・デコレーターという感じ☺️」

その他Ruby


クラウド/コンテナ/インフラ/Linux/Serverless

AWSのT3とNitro


つっつきボイス:「結局NitroだとAMIがそのままでは動かない: ドライバが必要になる」「今更ですみませんがNitroってそもそも何でしたっけ?🙇」「NitroはAWSが独自開発したハードウェアですね: Nitro版システムではストレージ周りでこれが使われていて、Hypervisorのドライバが違います」「なるほど😃」「なので単にインスタンスタイプを変更しただけではドライバが認識されないので起動しない😆」「つまりAMIを作り直す必要がある?」「ですね: それか頑張って何とかモジュールをロードするとか、Hypervisor部分だからそんなに深刻ではないけど面倒w」「新しくAMIを作るならNitroにしてもよさそう」「テストはされてるはずだし大丈夫じゃないかな☺️: Nitroの登場は割と最近で、割安かつスペックが高いのがメリット💰: クラウドは世代が新しいほどコスト対性能比がよくなっていくものなので」

参考: AWSの「Nitro System」(ナイトロシステム)とは? ベアメタルサーバ実現の裏側 |ビジネス+IT
参考: ハイパーバイザ - Wikipedia

FunctionShield: サーバーレスアプリをポリシーで保護(Serverless Statusより)

// 同サイトより: JSの場合
var AWS = require('aws-sdk');
const FunctionShield = require('@puresec/function-shield');
FunctionShield.configure(
{
    policy: {
        // 'block' mode => active blocking
        // 'alert' mode => log only
        // 'allow' mode => allowed, implicitly occurs if key does not exist
        outbound_connectivity: "block",
        read_write_tmp: "block", 
        create_child_process: "block"
    },
    token: process.env.FUNCTION_SHIELD_TOKEN
 });

exports.hello = async (event) => {
    // ... // your code
};

つっつきボイス:「ほー、AWS Lambdaで使えるアクセス保護か」「ラッパーではないと書かれてますね」「Lambdaで実装するときに思わぬところにリクエストが飛ばないようにポリシーで制限をかけるということのようだ: 『/tmp/へのアクセスを無効にできる』とかもそうで、これはLambdaで一応できるけど確かにあまりよろしくないヤツ」「お?」「Lambdaへの個別のリクエストは同じハードウェアで動く可能性があって、そのときに/tmpもリクエスト間でかぶる可能性があるので、特に固定値を置くとアブナイ」「ははー😲」「子プロセスを実行できないようにするポリシーもある: チームでLambdaコードを書くならとりあえずこのソフトウェアをインストールしておくのは悪くなさそう❤️」「オープンソースですしね😃」

H2Oサーバーの作者Kazuhoさんのスライド


つっつきボイス:「最近H2Oってどうなってるかなと思って探してたら見つけました」「おーTCPでパケットロスしたときの影響はHTTP/2の方が大きいと: 確かにー」「HTTP1.1はマルチスレッドだけどHTTP/2はシングルスレッド(正確にはTCPのフローとかセッションですが)というのがよくわかる絵↓😆」「😆」「HTTP/2の仕組みを理解していれば納得の内容😋」


同スライドより

「ところでこの『パケロス2%』↓は相当ひどいw」「2%は悪いんでしょうか?」「(カンファレンス会場の無線LANとかを別にすれば)普通ありえないですね: そんなネットワークがあったらヤバい💀」


同スライドより

「そして結論は『場合による』☺️」

参考: HTTP/2 サーバープッシュ : H2OとRuby on Rails 5.2beta、HTTP 103 EarlyHintsでページ高速化 - Qiita
参考: HTTP の新しいステータスコード 103 Early Hints | blog.jxck.io

その他


つっつきボイス:「内容はともかく、『個人的には、ほとんどの案件においてRed Hat Enterprise LinuxかCentOSしか使わないので』という記述があって、普段Red Hat Enterpriseをめったに見かけないのでちょっと気になりました」「Red Hat Enterprise Linuxは何度か使ってますけど、高いからなー😆」「どういうところで使うんでしょうか?」「主に有料サポートの付いたOSでないと導入が認められない組織ですね: SIer向け」「やはり」

「ちなみにCentOSの中身はRed Hat Enterprise Linuxと基本一緒で、有料ソフトウェアの違いぐらい」「そういえばそうでしたね」「ただセキュリティパッチなんかはRed Hatが投稿しているのでその分早く使えたりします🕶: CentOSはあくまでオープンソースソフトウェアなので」

参考: CentOS - Wikipedia
参考: Red Hat Enterprise Linux - Wikipedia

SQL

RedisGraph: Redisで動くグラフデータベース


oss.redislabs.comより

↓Dockerでデモを動かせます。

docker run -p 6379:6379 -it --rm redislabs/redisgraph
$ redis-cli
127.0.0.1:6379> GRAPH.QUERY MotoGP "CREATE (:Rider {name:'Valentino Rossi'})-[:rides]->(:Team {name:'Yamaha'}), (:Rider {name:'Dani Pedrosa'})-[:rides]->(:Team {name:'Honda'}), (:Rider {name:'Andrea Dovizioso'})-[:rides]->(:Team {name:'Ducati'})"
1) (empty list or set)
2) 1) Labels added: 2
   2) Nodes created: 6
   3) Properties set: 6
   4) Relationships created: 3
   5) "Query internal execution time: 0.399000 milliseconds"


同記事より


つっつきボイス:「グラフ理論のグラフ↑ですね」「Redisってモジュール入れられるのかー😳: しかも他にもいろいろあるし↓」「Redisってもう単なるKeyValueストアじゃないですね」「Redisは最早SQLではない何か🧞‍♂️」「Redis、恐ろしい子…!」


redis.ioより

ブルームフィルタのモジュールもあるし」「cthulhuっていうモジュールもいい名前❤️」「クトゥルー😆」「RedisからJSを呼べるみたい: 何でこの名前にしたのか知らんけど😆」

参考: クトゥルフ - Wikipedia

JavaScript

Vue CLI 3ではVueをTypeScriptで書けるようなった


cli.vuejs.orgより


つっつきボイス:「Vue CLIそのものは開発ツールなんですね」「みなさんやっぱりTypeScriptに向かってるらしき☺️」「社内にもTypeScript使いたい勢がいますね」「自分も生JSはヤダ😆」

yarn global add @vue/cliしてプロジェクトを作ってみました↓。

参考: Vue CLI 3.0 で TypeScript な Vue.js プロジェクトをつくってみる - Qiita

たった1行のJSコードでパフォーマンスが激悪化(Frontend Weeklyより)


同記事より


つっつきボイス:「頑張って診断してる」「以下が犯人だったそうです↓」「JSON.stringifyねー: deep cloneしてたら確かにそれは遅くなる🧐」

return JSON.parse(JSON.stringify(this._data));

CSS/HTML/フロントエンド/テスト

待てる応答時間

これも本日のBPS社内勉強会で登場した定番記事です。

  • 0.1sec: 遅延なしで操作できると感じられる上限
  • 1.0sec: ユーザーの思考を中断しない上限
  • 10sec: ユーザーが注意を維持できる上限

つっつきボイス:「1993年の記事なので、コマンドラインベースの端末しかなかったような時代の話ですけどね😆: Webになるともっと厳し目になるし」

上の続編としてWebサイトの応答時間についての考察記事もありました。

HTTPSは僻地でのネットアクセスに不利(Frontend Weeklyより)


つっつきボイス:「HTTPSにしたことで少々遅くなるのは珍しくないだろうけど?」「お、『geosynchronous-satellite internet access』での話か」「衛星経由だったかー」「それだけでめちゃめちゃ不利」

著者はウガンダの農村部でソフトウェア開発を教えていて、そこでは衛星インターネット以外のアクセス手段がほとんどなく、Wikipediaを開くだけでも往生するそうです。遅さを緩和するためにローカルキャッシュサーバーを立てたのに、そこの環境だとほぼまったくHTTPSページのキャッシュが効かず困り果てています。

↓記事と直接関係ありませんが、ウガンダのスーダン難民キャンプでのインターネット接続の改善を訴える動画です。

⭐書籍『Real World HTTP』⭐

  • HTTP/1.0 のシンタックス:基本となる 4 つの要素
  • HTTP/1.0 のセマンティクス:ブラウザの基本機能の裏側
  • Go 言語による HTTP/1.0 クライアントの実装
  • HTTP/1.1 のシンタックス:高速化と安全性を求めた拡張
  • HTTP/1.1 のセマンティクス:広がる HTTP の用途
  • Go 言語による HTTP1.1 クライアントの実装
  • HTTP/2 のシンタックス:プロトコルの再定義
  • HTTP/2 のセマンティクス:新しいユースケース
  • Go 言語による HTTP/2、HTML5のプロトコルの実装
  • セキュリティ:ブラウザを守るHTTPの機能
  • クライアント視点で見るRESTful API
    同記事より

つっつきボイス:「実はGo 1.11 Release Party in Tokyoに行ってきまして、そこで最後にお話しされていた渋川さんの本です」「おー、これ結構よさそうな本じゃないですか❤️今こういう本を出すことに意義がありますね」「😃」「HTTPの本って古いのしかなかったし、HTTP 1.1は拡張に次ぐ拡張を繰り返してきたから、今どうなっているのかがわかる本は貴重💎」「目的を絞り込んでいるのもよさそうですね」「それもあるし、HTTP/2が当たり前に使われるようになった後の時代にマッチしていますね😋」

「HTTPのRFCを読むというのは?」「現実にはすべて読みこんで理解するのは不可能ですね😤」「ありゃ」

遅ればせながら今週の⭐を進呈いたします。おめでとうございます。

言語よろずの間

Goのバイナリサイズを小さくするテクニック

Go 1.11 Release Party in Tokyo - connpassで発表された資料です。

なおGo 1.11は昨日リリースされました🎊。


つっつきボイス:「こちらが渋川さんのスライドです: Goって中身がほぼ空っぽのソースでもバイナリサイズが1MBぐらいになってしまうので、WebAssemblyだとサイズのデカさが不利になりがちです😢」「GCとかいろいろ機能を内包しているからしょうがないですね: shared libraryにリンクってできます?」「一応できます」

「スライドにあった『GoはリポジトリのURLとパッケージが密結合してる』これねー: Goの仕様を最初に見たときにこれ大丈夫か?って思ったけど、意外とみんな使ってるから大丈夫なのかな?」「いやー大丈夫じゃないですね💦: パッケージの依存関係管理はdepというツールに収束しそうではあるものの今も大変で、RubyのBundlerって本当に偉いなと思います」「そこでGoが見せてくれる夢はわかるけど、スライドにもあるようにローカルのプライベートパッケージまでやり始めると大変だろうなーとは思う☺️」「そうなんですよ~😢」


bundler.ioより

参考: 依存関係管理ツールdep(golang) - Qiita

その他

GoogleのCloud AutoMLで自分のテキスト学習モデルを育成できるようになった


つっつきボイス:「自分が持っている原文訳文を大量に食わせることで、機械翻訳なんかの学習モデルを自分で育成できるんだそうです: 週末遊んでみようかなと」「データを大量に持ってる人ならいいかもねー☺️」

参考: Google、Cloud AutoMLでテキスト分析と翻訳に対応、認知系AIサービスも強化:Google Cloud Next ’18 - @IT

Basecamp「ヒルチャート」機能でプロジェクトの問題を直感的に理解する



同記事より


つっつきボイス:「ヒルチャートって初めて知ったんですけどちょっとよさそうだなと思って」「ふむぅ、進捗管理とかでヒルを超えてないタスクがどのぐらいあるかをわかりやすく見せる感じ?」「ひと目でわかるのがいいなと思いました😋」「プロジェクト管理向きかも」

追いかけボイス:

参考: New in Basecamp: See where projects really stand with the Hill Chart


m.signalvnoise.comより

番外

世界の中心はオレ


つっつきボイス:「これも渋川さんのリツィートからです」「今日は宇宙じゃなくて古代にw」「お、早めに終わったので台風が来る前に撤収〜」


今回は以上です。

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

週刊Railsウォッチ(20180820)Railsで構築されたサイト40選、Deviseはつらいよ、ARのスコープとクラスメソッドの使い分けほか

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

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

Rails公式ニュース

Ruby Weekly

Hacklines

Hacklines

Serverless Status

serverless_status_banner

Frontend Weekly

frontendweekly_banner_captured

デザインも頼めるシステム開発会社をお探しならBPS株式会社までどうぞ 開発エンジニア積極採用中です! 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ウォッチ

インフラ

ActiveSupport探訪シリーズ