週刊Railsウォッチ(20180420)NGINX Unit正式リリース、Rubyをメモリリークさせてみる、美しいコード宇宙ほか

こんにちは、hachi8833です。記事を絞ろうと気張るのを諦めて単に絞ることにしました。

昨日のつっつきは、BPSの福岡拠点であるウイングドアの皆さまとZoomで画面共有しながら行いました。おかげさまでさらに盛り上がりました。ありがとうございます。

ところが何ということでしょう、録音を忘れていた私でした…😢今週のつっつき成分は少なめです。

というわけで、季節の変わり目のウォッチ、いってみましょう。

各記事冒頭には⚓でパーマリンクを置いてあります: 社内やTwitterでの議論などにどうぞ

Rails: 今週の改修

Rails 6になるmasterブランチから見繕いました。

先週取り上げたようなsplat外し的修正が目立ちます。86cafe7なんかもそうですね。

RedisCacheStore#delete_matchedでブロックが発生してタイムアウトしていたのを修正

# commitより
 def delete_matched(matcher, options = nil) 
   instrument :delete_matched, matcher do 
     case matcher 
     when String 
       redis.with { |c| c.eval DELETE_GLOB_LUA, [], [namespace_key(matcher, options)] } 
     else 
       raise ArgumentError, "Only Redis glob strings are supported: #{matcher.inspect}" 
     end 
   end 
 end 

つっつきボイス: 「Lua言語が使われてる部分があったんだ…」

参考: Lua - Wikipedia

javascript_include_tagヘルパーにnonce: trueオプションを追加

# actionview/lib/action_view/helpers/asset_tag_helper.rb#L
       def javascript_include_tag(*sources)
         options = sources.extract_options!.stringify_keys
         path_options = options.extract!("protocol", "extname", "host", "skip_pipeline").symbolize_keys
@@ -90,6 +95,9 @@ def javascript_include_tag(*sources)
           tag_options = {
             "src" => href
           }.merge!(options)
+          if tag_options["nonce"] == true
+            tag_options["nonce"] = content_security_policy_nonce
+          end
           content_tag("script".freeze, "", tag_options)
         }.join("\n").html_safe

つっつきボイス:nonceって前にもつっつきで扱った気が」「number used onceのことだったんかー↓」「同じようなCSP属性があったけど何だったかな」「ところで今ぐぐって見つけていただいたreference.hyper-text.orgってちょっといい感じのリファレンスサイトですね」

nonce
nonce 属性は、CSP(Content Security Policy)によって、文書内に読み込まれた script 要素や、style 要素の内容を実行するかを決定するために利用される nonce(number used once / ワンタイムトークン) を指定します。
reference.hyper-text.orgより

参考: nonce 属性 | HTML5 タグリファレンス | W3 Watch Reference

参考: CSP: script-src - HTTP | MDN

Content Security Policyでリクエストごとのnonceを1つだけにする

これもnonceですね。

# actionpack/lib/action_dispatch/http/content_security_policy.rb#L232
-      def build_directives(context)
+      def build_directives(context, nonce)
         @directives.map do |directive, sources|
           if sources.is_a?(Array)
             "#{directive} #{build_directive(sources, context).join(' ')}"
+            if nonce && nonce_directive?(directive)
+              "#{directive} #{build_directive(sources, context).join(' ')} 'nonce-#{nonce}'"
+            else
+              "#{directive} #{build_directive(sources, context).join(' ')}"
+            end
           elsif sources
             directive
           else
...

APIドキュメントの修正3種

# activemodel/lib/active_model/validations/inclusion.rb#L21
       #   class Person < ActiveRecord::Base
-      #     validates_inclusion_of :gender, in: %w( m f )
+      #     validates_inclusion_of :role, in: %w( admin contributor )
       #     validates_inclusion_of :age, in: 0..99
       #     validates_inclusion_of :format, in: %w( jpg gif png ), message: "extension %{value} is not included in the list"
       #     validates_inclusion_of :states, in: ->(person) { STATES[person.country] }

今どきgenderが男と女だけというのは古臭い感じかもですね。
そういえばだいぶ昔は「クライアント/サーバー」と言わずに「マスター/スレーブ」って言ってたんですよね。「主人と奴隷」はさすがに200年遡る感じです。


つっつきボイス: 「へー、LGBTコンシャスというか」「そういえばこの間はてブであがってたISO 5218が、まさにこうした用途のための国際規格ですよ」「知らなかったー!」

  • 0 = not known(不明)
  • 1 = male(男性)
  • 2 = female(女性)
  • 9 = not applicable(適用不能)

ブクマにyuguiさんのコメントを見つけました:

システムで「性別」の情報を扱う前に知っておくべきこと – Qiita

「入力して何の役に立つの?」という最重要ポイントを読み落とさないでほしい。医療かマーケか戸籍処理か本人確認か、用途に応じて入力させるべきかも提示選択肢も入力欄ラベルも自ずと定まり、難しいことはない

2018/04/13 06:55

参考: システムで「性別」の情報を扱う前に知っておくべきこと - Qiita — これ必読ですね

遠い昔、子どもの頃の遠足で訪れたお寺で他の子が「観音様って男?女?」と質問すると、お寺の管理人さんが「観音は 男にあらず 女にあらず」と迷いなく答えたのをふと思い出しました。典拠を探そうと思ってググると新興宗教系サイトがわらわら出てきた…


# actionview/lib/action_view/context.rb#L10
   # Action View contexts are supplied to Action Controller to render a template.
   # The default Action View context is ActionView::Base.
   #
-  # In order to work with ActionController, a Context must just include this module.
-  # The initialization of the variables used by the context (@output_buffer, @view_flow,
-  # and @virtual_path) is responsibility of the object that includes this module
-  # (although you can call _prepare_context defined below).
+  # In order to work with Action Controller, a Context must just include this
+  # module. The initialization of the variables used by the context
+  # (@output_buffer, @view_flow, and @virtual_path) is responsibility of the
+  # object that includes this module (although you can call _prepare_context
+  # defined below).

つっつきボイス: 「クラス名としてはActionControllerだけど名称としてはAction Controllerが正式ってことなんでしょうか?」「んー、というより冒頭にAction Viewって書いてあるから単にそれと書式を合わせたってことなんじゃ?」「あなるほど、ドキュメントのローカルレベルでの統一というか」

くっついてる方が検索しやすいかなとちょっぴり思ったりしました。


# guides/source/_welcome.html.erb#L18
 <% end %>
 <p>
 The guides for earlier releases:
+<a href="http://guides.rubyonrails.org/v5.2/">Rails 5.2</a>,
 <a href="http://guides.rubyonrails.org/v5.1/">Rails 5.1</a>,
 <a href="http://guides.rubyonrails.org/v5.0/">Rails 5.0</a>,
 <a href="http://guides.rubyonrails.org/v4.2/">Rails 4.2</a>,

つまりRuby on Rails 5.2 Release Notesが正式になったということですね。Railsガイドの翻訳の優先順位上げます。ご期待ください。


railsguides.jpより

サーバーIP指定時のHOST環境変数のサポート廃止

# 
-            ENV.fetch("HOST", default_host)
+
+            if ENV["HOST"] && !ENV["BINDING"]
+              ActiveSupport::Deprecation.warn(<<-MSG.squish)
+                Using the `HOST` environment to specify the IP is deprecated and will be removed in Rails 6.1.
+                Please use `BINDING` environment instead.
+              MSG
+
+              return ENV["HOST"]
+            end
+
+            ENV.fetch("BINDING", default_host)

SuSeSUSEでは$HOSTがデフォルトで設定され、$HOSTNAMEと等しくなっている。
https://www.suse.com/documentation/sled11/book_sle_admin/data/sec_adm_variables.html
従って、デフォルトではlocalhostではなくhostnameにバインドされる。これはデフォルトの振る舞いとしてはふさわしくないように思える。
この環境変数名の利用を避けるために、環境変数をHOSTからBINDINGに変更する。
同コミットより


つっつきボイス: 「お、これ大事な修正ですね: Rails 6.1からはHOSTS環境変数のサポートが削除されるのでBINDING環境変数を使うように、と」

「話逸れますが(逸れてばっかり)、昔いた会社のヨーロッパ系社員がSuSeSUSEを「ズーゼ」ってドイツ語っぽく発音してて、最初何のこと?って思っちゃいました」「へー、SuSeSUSE Linuxって日本ではなぜかそれほど知名度ないけど、ヨーロッパでは長い間ずっと主流ですね」「シンボルカラーが緑色だったのだけ覚えてます: 今もそうなのかな?」


suse.comより

storageフォルダに.keepファイルを追加する条件を修正

# railties/lib/rails/generators/rails/app/templates/gitignore.tt
 <% unless skip_active_storage? -%>
 # Ignore uploaded files in development
 /storage/*
-
+<% if keeps? -%>
+!/storage/.keep
 <% end -%>
+<% end -%>
+
 <% unless options.skip_yarn? -%>
 /node_modules
 /yarn-error.log

最初にRailsを触ったときに、空のフォルダに入っている.keepって何だろう?と思ったのを思い出しました。


つっつきボイス: 「ははぁ、.gitignore/storage/.keep登録しちゃってたのか: そりゃ直さなきゃ!」「空ディレクトリにファイルが何もないとディレクトリがGitに登録されないんで、.keepが置かれてるんですね」「そうそう、前に教えてもらって知りました」

Rails

Action Policy: Ruby/Rails向けauthorizationフレームワーク


元記事より

authorizationの訳語でいつも悩んでます。「認証(authentication)」と対にして「認可」「承認」とされることが多いのですが、認可でも何かこうしっくりこない…リソース管理とかリソースのアクセス権の扱いなんかがauthorizationなんですよね。


つっつきボイス: 「これもEvil Martiansさんがスポンサーになってる: Evil MartiansさんのブログはTechRachoの翻訳記事にときどき使わせてもらってるんですが、こうやってちょっと先を行くようなgemのスポンサーになっているのをちょくちょく見かけるので」「action_policy gemはEvil Martiansのリポジトリとは別の場所なのか: それにしてもevil-seedとかevil-clientとか、RailsのGemfileとかで見かけたらドキーッっとしそうw」「徹底しているというか、旗色は鮮明ですね」

# 同リポジトリより
class PostPolicy < ApplicationPolicy
  # everyone can see any post
  def show?
    true
  end

  def update?
    # `user` is a performing subject,
    # `record` is a target object (post we want to update)
    user.admin? || (user.id == record.user_id)
  end
end

「で、このaction_policyはコントローラ側に寄せた設計のようだ」「以前から悩んでるところなんだけど、authorizationってPundit式にモデルに寄せるべきか、cancancan式にコントローラというかURL側に寄せるべきか、どっちだと思う?」「そうなんすよねぇ…モデル側の方がライブラリとしておさまりはいいのかなと思ったりもしますが、複雑になってくるとつらくなってくるし、果たしてモデルの責務なんだろうかという疑問も残るし」「自分は何となくだけど、コントローラ側の方が自然な気がするんだけどなー」「cancancanは機能が多すぎて逆にツライ: コントローラでauthorize!ってできればもうそれでいいのっ!w」「住処が定まらない感じですね」

新しいRailsフロントエンド開発(1)Asset PipelineからWebpackへ(翻訳)

NGINX Unit正式リリース

新しいRubyアプリサーバー「NGINX Unit」を調べてみた(翻訳)


つっつきボイス: 「どうも思い違いされていることが多いみたいなんですが、NGINX UnitはNGINXとは別物なんですよねー」「どちらもNGINX社の製品なのにそうなんですね: 紛らわしい…」



nginx.comより

社内Slackより: 悪例サンプルコードづくりは難しい

SOLID Principles #4 - Interface Segregation Principle  | Netguru Blog on Ruby/Ruby on Railsを翻訳したときに、サンプルコードについて社内Slackでかなり議論になりました。
私も訳していて、原著者が非常に苦しみながら書いていることを痛感しました。

# 同記事の悪例コード
class Computer 
  def turn_on; end
  def type; end
  def replace_cpu; end
  def change_user_password; end
end

class ComputerUser
  def initialize
    @computer = Computer.new
  end
end

class Programmer < ComputerUser
  def write_code
    @computer.turn_on
    @computer.type
  end
end

class Administrator < ComputerUser
  def update_user
    @computer.turn_on
    @computer.change_user_password
  end
end

class Technician < ComputerUser
  def fix_computer
    @computer.replace_cpu
    @computer.turn_on
  end
end

記事として練り直しを考えているところです。Slackでの指摘をまとめると以下のような感じでした。

  • サンプルコードの修正前と修正後の差が大きすぎて、ISPにフォーカスしにくい
  • そもそも修正前のコードがいろいろひどすぎて、そっちに気を取られてしまう
  • 可能なら修正したいところだけど、 ユースケースが見えない

推測ですが、教科書にありがちな哺乳類だの何だのという浮世離れしたクラスではなく、何とかして現実的なクラスにしようとしたように思えます。

ISPを説明するのに向いたサンプルコードがあれば著者もぐっと楽になりそうです。手頃な素材がどこかにないものでしょうか。

RailsでのExplicit Contract

# 同記事より
class StudentsController < ApplicationController

  # ...

  def pull
    pulled_student_list = third_party_contract.fetch_students['students']

    pulled_student_list.each do |pulled_student|
      student = Student.new
      student.name = pulled_student['name']
      student.age = pulled_student['age']
      student.save!
    end
  end

  private

  def third_party_contract
    Rails.configuration.x.third_party_contract
  end
end

つっつきボイス: 「third party contract? どうやら法律用語から来てるっぽい?わからんけど」「httpartyっていうHTTPクライアントgem使ってますね: ★5,000近い」

# 同リポジトリより
# Use the class methods to get down to business quickly
response = HTTParty.get('http://api.stackexchange.com/2.2/questions?site=stackoverflow')

puts response.body, response.code, response.message, response.headers.inspect

# Or wrap things up in your own class
class StackExchange
  include HTTParty
  base_uri 'api.stackexchange.com'

  def initialize(service, page)
    @options = { query: { site: service, page: page } }
  end

  def questions
    self.class.get("/2.2/questions", @options)
  end

  def users
    self.class.get("/2.2/users", @options)
  end
end

stack_exchange = StackExchange.new("stackoverflow", 1)
puts stack_exchange.questions
puts stack_exchange.users

「httpartyで思い出したけど、herっていうgemもなかなかよくできてますヨ(前にも話したけど)」

# 同リポジトリより
User.all
# GET "https://api.example.com/users" and return an array of User objects

User.find(1)
# GET "https://api.example.com/users/1" and return a User object

@user = User.create(fullname: "Tobias Fünke")
# POST "https://api.example.com/users" with `fullname=Tobias+Fünke` and return the saved User object

@user = User.new(fullname: "Tobias Fünke")
@user.occupation = "actor"
@user.save
# POST "https://api.example.com/users" with `fullname=Tobias+Fünke&occupation=actor` and return the saved User object

@user = User.find(1)
@user.fullname = "Lindsay Fünke"
@user.save
# PUT "https://api.example.com/users/1" with `fullname=Lindsay+Fünke` and return the updated User object

ChromebookでRailsが動く?

参考: ChromebookのFile Systemへの書込み制限を解除する方法 ― Write-Protect-Screwの外し方 C300MA編 | Chrome速報

Chromebrew(crewコマンド)というのを入れると様々なシステムを簡単にインストールできる。EmacsもNodeも簡単にインストールできた。Sinatraも使えたのでWebアプリ開発もできてしまう。頑張ればRailsも動きそうである。(crewだとコケたが個別インストールすれば大丈夫そう)


つっつきボイス: 「ポイントは、Chromebookのフタを外してプロテクトスイッチを解除することみたいです」「DockerがChromebookで動けばいいんじゃね?そしたらもう何でも動くよ♥」

その他記事など


つっつきボイス:AssetSyncはAWSのS3と同期するgemだけど、Azureにも対応したのか」

参考: Microsoft Azure Cloud Computing Platform & Services

Ruby trunkより

IRBのパーサーをRipperにした


同パッチより

===match?より遅い

# 同issueより
# ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-darwin17]

require 'benchmark/ips'

def run_benchmark(title, **benchmarks)
  puts '', title, '=' * title.size, ''

  # Validation
  benchmarks.each do |benchmark_name, benchmark_fn|
    puts "#{benchmark_name} result: #{benchmark_fn.call()}"
  end

  puts

  Benchmark.ips do |bm|
    benchmarks.each do |benchmark_name, benchmark_fn|
      bm.report(benchmark_name, &benchmark_fn)
    end

    bm.compare!
  end
end

regex = /foo/
# => /foo/
string = 'foobarbaz'
# => "foobarbaz"

run_benchmark('=== vs match? - 2.5.1',
  '===':    -> { regex === string },
  'match?': -> { regex.match? string }
)

=== vs match? - 2.5.1
=====================

=== result: true
match? result: true

Warming up --------------------------------------
                 ===   173.435k i/100ms
              match?   233.124k i/100ms
Calculating -------------------------------------
                 ===      3.174M (± 1.6%) i/s -     15.956M in   5.029027s
              match?      5.626M (± 2.5%) i/s -     28.208M in   5.016991s

Comparison:
              match?:  5626170.1 i/s
                 ===:  3173659.6 i/s - 1.77x  slower

つっつきボイス: 「まず===match?って同一なんだっけ違うんだっけ?」「ほむほむ、match?は位置を指定できるのと、例の特殊変数を更新しないところが違う、と↓」「特殊変数を更新してたらその分遅くなりそうですね」「$~とか使うとRubyがPerlチックになるんで好きじゃないなー」「私も」

  • Regexp#===: 文字列 string との正規表現マッチを行います。 マッチした場合は真を返します。string が文字列でもシンボルでもない場合には false を返します。このメソッドは主にcase文での比較に用いられます。
  • Regexp#match?: 指定された文字列 str に対して 位置 pos から自身が表す正規表現によるマッチングを行います。 マッチした場合 true を返し、マッチしない場合には false を返します。また、$~ などパターンマッチに関する組み込み変数の値は変更されません
    Rubyリファレンスマニュアルより

[Ruby] Kernelの特殊変数をできるだけ$記号なしで書いてみる

Windowsで削除の制御文字が期待どおりに動かない

ruby -e 'puts "Hello world!\e[D\e[D\e[K\nWhat is up?"'
ruby -e 'puts "Hello world!\e[D\e[D\e[0K\nWhat is up?"'
ruby -e 'puts "Hello world!\e[D\e[D\e[1K\nWhat is up?"'

# 期待
Hello worl
Whats up?
Hello worl
Whats up?
           !
Whats up?

# 実際
          d!
What is up?
          d!
What is up?
          d!
What is up?

つっつきボイス: 「普段Web開発しているとほとんどやらないけど、Windowsの生の環境でRubyを使ってる人って、実は結構いるんじゃないかしら: 社内業務改善の手作りツールとかで」「それ私マジでやってました: Excelがバージョンアップするたびに手作りVBAが動かなくなるのが嫌になって、ExcelをRubyで制御する拡張をインストールして動かしたのがRubyとの最初の出会い」「WindowsユーザーのサポートはRubyのありがたい点」

どうやったかもう思い出せませんが、require 'win32ole'的にやったのかもしれません。確かRubyのバージョンは1.9だったはず。

参考: Rubyist Magazine - VBA より便利で手軽 Excel 操作スクリプト言語「Ruby」へのお誘い (前編)

rangeの終わりを「無指定」にできるようになる

今日見つけたツイートです。

ary[1..]   # [1..-1] と同等

その後#14700で早速バグ上がってました。

Ruby

Rubyでメモリーリークを引き起こす方法(Ruby Weeklyより)

# 同記事より
a = []
b = {}

loop {
  sleep(1)

  10_000.times { a << "abc" }

  puts GC.stat(b)[:heap_live_slots]
}

つっつきボイス: 「おー、漏れてる漏れてる」「sleep(1)って必要なんだろうか?」「単に見やすくしてるんでしょうかね」「C拡張がリークするのは不思議でも何でもないw」「heap_live_slotsか…情報どこかにあるか?」「つ↓」

参考: Understanding Ruby GC through GC.stat

型あり言語からRubyに来た人の心理学

2004年なのですごく古いですが、どうやら有名みたいです。

# 同書き込みより
# こうなりがち
   def date=(val)
     class="keyword">case val
     when Date
       @date = val
     when Time
       @date = Date.new(val.year, val.month, val.day)
     when String
       if val =~ /(\d{4})\s*[-\/\\]\s*(\d{1,2})\s*[-\/\\]\s*(\d{1,2})/
         @date = Date.new($1.to_i,$2.to_i,$3.to_i)
       else
         raise ArgumentError, "Unable to parse #{val} as date"
       end
     when Array
       if val.length == 3
         @date = Date.new(val[0], val[1], val[2])
       end
     else
       raise ArgumentError, "Unable to parse #{val} as date"
     end
   end

そして筆者の考えるダックタイピングの真髄はこうだそうです。

# year、month、dayメソッドに応答するオブジェクトを取る
attr_accessor :date

つっつきボイス: 「クラスチェックしたくてcaseで分岐しちゃうやつねー」「でもActiveSupportとかでこういう分岐、普通に見かけますよw」「どっひゃー」「if val行の正規表現はつらそう…」

参考: 静的型と OO というものははじめから… - Oh, you `re no (fun _ → more) — ここから辿りました

「ゴッドクラス」というアンチパターン

Gobyのst0012さんに教わって知りました。

巷では、OOPでは大量のメソッドを保有する万能クラス (ゴッドクラス) を作ってはいけないらしい。また、1メソッドあたり3行程度であるべきで、長いメソッドを書くのはオブジェクト指向的ではないらしい。そういうコードを書くやつはオブジェクト指向がわかっていないのだそうだ。
Qiita記事より


つっつきボイス: 「↑1メソッドあたり3行!来たなー」「引数縦に並べるとそれだけで3行終わっちゃいます」「自分も5行まで!なんて言ったりするけど基本ジョークジョークw」「20行までなら許して欲しい」「50行は多いかな?」「Rubocopのデフォルトって何行まで許されるんでしたっけ?」「コメント除いて10行みたいです」

【保存版】Rubyスタイルガイド(日本語・解説付き)総もくじ

🌟Code Galaxies Visualization🌟


同サイトより

Ruby、もちろんあります。美しすぎる。Go Conference 2018で知りました。


つっつきボイス: 「HomebrewやDebianパッケージまであるし」



同サイトより

宇宙船操作マニュアルとか気分出ますね(Hキーで表示できます)。
今週の🌟を贈呈します。おめでとうございます。

rdl: Rubyで型チェック

# 同リポジトリより
file.rb:
  require 'rdl'
  extend RDL::Annotate

  type '(Integer) -> Integer', typecheck: :now
  def id(x)
    "forty-two"
  end

つっつきボイス:->こういう型宣言する関数型言語、あった気がする」「Ruby 3.0だとコメントに記述する形(アノテーション)で型チェックが入りそうなんでしたっけ」「dry-validationみたいなライブラリレベルの型チェックでいい気がする…」

# dry-rb.orgより
schema = Dry::Validation.Form do
  required(:name).filled
  required(:age).filled(:int?, gt?: 18)
end

schema.("name" => "Jane", "age" => "30").to_h
# => {name: "Jane", age: 30}

schema.("name" => "Jane", "age" => "17").messages
# => {:age=>["must be greater than 18"]}

Rails: dry-rbでForm Objectを作る(翻訳)

その他記事など


つっつきボイス:redoって確かYARVがらみで見かけた気が」

追伸: いわゆるJUMP命令ってパイプラインはstallするけど1 instructionなのでそりゃ早いみたいな話でした(morimorihoge)。

参考: YARV: Yet another RubyVM / Instruction Table

SQL

PostgreSQLで大規模データを処理する(Postgres Weeklyより)


つっつきボイス: 「まだ中身読んでなかった」「ふむふむ、parallelismにパーティショニングにVACUUM FREEZEにFDW…、普通にぽすぐれででかいデータを扱う記事ですね」「(ぽすぐれで計算処理やらせるのかとおもた…)」

PostgreSQL 11に入る「Covering Index」

-- 同記事より
=# CREATE TABLE new_example (a int, b int, c int);
CREATE TABLE
=# INSERT INTO new_example
     SELECT 3 * val, 3 * val + 1, 3 * val + 2
     FROM generate_series(0, 1000000) as val;
INSERT 0 1000001
=# CREATE UNIQUE INDEX new_unique_idx ON new_example(a, b)
     INCLUDE (c);
CREATE INDEX
=# VACUUM ANALYZE;
VACUUM
=#  EXPLAIN ANALYZE SELECT a, b, c FROM new_example WHERE a < 10000;
                       QUERY PLAN
-----------------------------------------------------
 Index Only Scan using new_unique_idx on new_example
     (cost=0.42..116.06 rows=3408 width=12)
     (actual time=0.085..2.348 rows=3334 loops=1)
   Index Cond: (a < 10000)
   Heap Fetches: 0
 Planning Time: 1.851 ms
 Execution Time: 2.840 ms
(5 rows)

つっつきボイス: 「え?Covering Indexってぽすぐれになかった?: MySQLにはずうっと前からあるのに」「ほんとだ、ググるとMySQLばっかり出てくる」

参考: インデックスのみのスキャン: テーブルアクセスを避ける

インデックスのはたらきによって、テーブルアクセスしなくても良かった場合のことを、 カバリングインデックスと言います。これは、インデックスの機能であるかのような響きがあるので、誤解されやすい用語です。インデックスのみのスキャン、という言い方の 方が、実行計画の操作であることを明白に示しています。
上記ブログより

つっつきでMERGE JOINの話にもなったのですが展開思い出せず…

EdgeDBって何じゃろう

Rich Harrisさんって有名な人みたい。

JavaScript

async/awaitヘルからの脱出(JavaScript Weeklyより)

// 同記事より
async function selectPizza() {
  const pizzaData = await getPizzaData()    // async call
  const chosenPizza = choosePizza()    // sync call
  await addPizzaToCart(chosenPizza)    // async call
}

async function selectDrink() {
  const drinkData = await getDrinkData()    // async call
  const chosenDrink = chooseDrink()    // sync call
  await addDrinkToCart(chosenDrink)    // async call
}

(async () => {
  const pizzaPromise = selectPizza()
  const drinkPromise = selectDrink()
  await pizzaPromise
  await drinkPromise
  orderItems()    // async call
})()

// Although I prefer it this way 

(async () => {
  Promise.all([selectPizza(), selectDrink()]).then(orderItems)   // async call
})()

TypeScriptの記法を理解する(JavaScript Weeklyより)

interface Array<T> {
  concat(...items: Array<T[] | T>): T[];
  reduce<U>(
    callback: (state: U, element: T, index: number, array: T[]) => U,
    firstState?: U): U;
  ···
}

つっつきボイス: 「TypeScriptはいいと思う: ただねー、環境の準備がめんどいw」「誰か準備してくれるならTypeScriptにしたい」「そういえばこの中にひとり、TypeScript勢いませんでしたっけ?」「ワイ?| ゜Θ゜)<そうでもないよ」

参考: TypeScript - JavaScript that scales.


typescriptlang.orgより

これで全部終わらそうかという勢いのオンラインドキュメント: Front-End Developer Handbook 2018(JavaScript Weeklyより)


frontendmasters.comより

JS/CSS/HTML…と、新しいフロントエンド絡みのドキュメントを親の仇のように集約しています。


つっつきボイス: 「先週のrubyreferences.github.ioといい、このフォーマットのドキュメントテンプレ流行ってるのかなと思って」「というよりみんなGitHub Pages使ってるからじゃないすか?」「あそっか」「ともあれ、どこまできちんと書かれているかはちゃんと読むまでわからないですけどねw」

追伸: フォーマットの話はGitBookの方ですね。 github.io ドメイン使ってる場合はGitHub Pages連動もしてるでしょうが(morimorihoge)。


frontendmasters.comより

「お、とってもいい地図見つけた↑」「サイトの作りというか、フロントエンドはこれをこういう順に学べという道案内ですね」「同じページの『↓これは学ぶなリスト』にCoffeeScriptが…😢」「SASSも!?」

A short word of advice on learning. Learn the actual underlying technologies, before learning abstractions. Don’t learn jQuery, learn the DOM. Don’t learn SASS, learn CSS. Don’t learn HAML, learn HTML. Don’t learn CoffeeScript, learn JavaScript. Don’t learn Handlebars, learn JavaScript ES6 templates. Don’t just use Bootstrap, learn UI patterns.

「SASSじゃなくて素のCSSにしろと言われてもなー」「PostCSSあたりはどうだろう?」


github.com/postcssより

こちらにも星あげたい気持ちしてきました。

追伸: 落ち着いて読み直してみたら、基礎を学んでから応用のCoffeeScriptなりを学べという文脈でした。

CSS/HTML/フロントエンド

Unicodeコンソーシアムの絵文字募集フォーム


unicode.orgより

Turing Complete FMの文字コードの回でも、絵文字の寿司にバリアントがいっぱいあるのにピザがそうじゃないのはどうよとか楽しい話があった気がします。


つっつきボイス: 「次は2020年に採択されるそうです」「文字だけのリストだとわかりにくいなー」「TechRachoのシンボルマークしれっと出したら案外通ったりして?」「(爆)」

Rubyの内部文字コードはUTF-8ではない…だと…?!

出会えてうれしいCSSベスト3

Rubyのメソッドなんかでもこういうのやってみようかな。


つっつきボイス: 「flexboxが人気」「calcも多いですね」

Service Workerとは


同記事より

Go言語

grapi: gRPC APIサーバー&ジェネレーター


つっつきボイス: 「Go Conference 2018でgRPCの登場率高かったです」「gRPCのようなミドルウェア的なものはGoが得意そうっすね」

Go言語がWebAssemblyをサポートへ

Gobyちゃんがブラウザでするっと動く日が来るかなと思って。ちなみにこの記事の情報源は基本的に#18892でした。

Goで学ぶTCP/IPスタック


つっつきボイス: 「そうそう、Goに限らずTCP/IPスタックのコードは一度は読んでおくと勉強になりますヨ」

// 同リポジトリより
// GetTCPProbe returns the TCPProbeFunc if installed with AddTCPProbe, nil
// otherwise.
func (s *Stack) GetTCPProbe() TCPProbeFunc {
    s.mu.Lock()
    p := s.tcpProbeFunc
    s.mu.Unlock()
    return p
}

// RemoveTCPProbe removes an installed TCP probe.
//
// NOTE: This only ensures that endpoints created after this call do not
// have a probe attached. Endpoints already created will continue to invoke
// TCP probe.
func (s *Stack) RemoveTCPProbe() {
    s.mu.Lock()
    s.tcpProbeFunc = nil
    s.mu.Unlock()
}

Go格言集とGo Conference 2018

先週紛れ込んだGo Conference 2018で知りました。元記事には詳しい説明へのリンクがあります。雑に訳してみました。


  • メモリ共有で通信するのも、通信でメモリ共有するのもまかりならぬ
  • コンカレンシーは並列(parallelism)にあらず
  • チャンネルは協調動作(オーケストレーション)のためのもの、ミューテックスはシリアライズのためのもの
  • インターフェイスが肥大化するほど抽象化の度合いが落ちる
  • ゼロ値を有用なものにせよ
  • interface{}それ自身は何の情報ももたらさない
  • gofmtのスタイルを好きなやつなど誰もいない、だからこそgofmtは好かれる
  • 依存をわずかでもこしらえるくらいなら、コピーしてしまえ
  • syscallは常にビルドタグで保護しなければならぬ
  • cgoは常にビルドタグで保護しなければならぬ
  • cgoはGoにあらず
  • 安全でないパッケージを使ったが最後、何の保証もありはしない
  • 巧みなコードを書くより、明確なコードを書くがよい
  • リフレクションが明確になることなどありえぬ
  • エラーとは値のことであり、それ以外の何ものでもない
  • エラーをチェックするだけでは足りぬ、丁重に処理せよ
  • アーキテクチャを設計し、コンポーネントに命名し、詳細をドキュメントに書け
  • ドキュメンテーションはユーザーのためのものである
  • panicは使うな(「うろたえるな」のダジャレ)

こういうのって言語の思想を手っ取り早く知るのに便利ですね。

つっつきボイス: 「Goの格言、( ・∀・)イイ!!こういうの大事だし、”Concurrency is not parallelism.”とかごもっとも」

「ところでこのページのGopherくんの絵、このユルさがもうたまらないw」「この雑なライトセーバーみたいなやつ↓、測ってないけど45度としか思えないw」


go-proverbs.github.ioより


Go Conference 2018をすごーく手短にまとめると、以下が印象に残っています。多すぎてここには到底盛り込めないので。

  • Goのmap(Rubyで言うハッシュ)は本質的にスレッドセーフにならないし、しない
  • Go界隈ではマイクロサービスの普及がだいぶ進んでいる(少なくともRails Developers Meetupでの挙手数と比べれば)
  • 一方モノリスのよさも見直されつつあったりするらしい: GCPといえども下手にサービスを割るとオーバーヘッドにつながるとか
  • Goは公式資料がエクストリームに充実しているので、野良ブログより先にこちらを最初にあさるべし
  • GoでORMするならActiveRecordのことは忘れること — 「ActiveRecordの完成度はやっぱり凄い」という率直な感想も

参考: Go Conference 2018 Spring - 資料一覧 - connpass

開発チームを苦しめるマイクロサービス(翻訳)

その他

同人誌「現代Webフロントエンドデザインパターン」


つっつきボイス: 「BPSのアプリチームには技術書典の常連がいるらしいという噂」「どかっと積み上げてくれるのかな( ^ω^)ワクワク」

大物の独自路線: Microsoftの独自LinuxカーネルとAmazonの独自ブラウザ


つっつきボイス: 「あーこれねw」「Amazonの独自ブラウザの名前がInternetって…」「誰に挑戦してるんだろうか」

参考: Amazonが容量わずか2MBの軽量版インターネットブラウザ、その名も「Internet」をリリース - GIGAZINE

GCP BigQueryの東京リージョン開始


つっつきボイス: 「お、今まで東京リージョンなかったのか」

クラウド業界でAWSのサービス名の命名センスが他にも広がってるような気が個人的にしています。

その他のその他



番外

英国BBCのGitHubリポジトリ


つっつきボイス: 「仕事中にたまたま見つけてくれた人がいたので」「本物なんですね」「BBCはこういうのをけっこうちゃんとやってますね」

↓動画は直接BBCとは関係ありませんが。

手計算だったし

そこまで精度上がったか

ビルの窓ガラスの振動を外からレーザー光線で測定して音声を盗聴するという技術を思い出しました。


つっつきボイス: 「おお、この手の技術は実は結構前からあるんですよ」「PLCって?」「まさに電力線搬送通信(Power Line Communication)で、屋内の電源コードを使ってデータ通信する技術」「へー!」「ちなみにPLCやるときはデータをPLC経由では屋外に出せないんですよ」「出せないっていうのは、法律的に?」「そう: 厳しく制限されている」「そっかー、日本は電波法厳しいし」

参考: 電力線搬送通信 - Wikipedia
参考: 電波法 - Wikipedia

複合原子層作製システム


iis.u-tokyo.ac.jpより

参考: 東大、シート状の原子層を自在に積み重ねるロボットシステムを開発 | マイナビニュース

日本沿岸で全世界数百年分のレアメタル鉱床が見つかる


つっつきボイス: 「どうやって掘り出すかが問題ですからねー」「何しろ海の底なんで」


今週は以上です。

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

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

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

Rails公式ニュース

Ruby Weekly

RubyFlow

160928_1638_XvIP4h

Postgres Weekly

postgres_weekly_banner

Frontend Focus

frontendfocus_banner_captured

JavaScript Weekly

javascriptweekly_logo_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の書いた記事

BPSアドベントカレンダー

週刊Railsウォッチ

インフラ

ActiveSupport探訪シリーズ