- Ruby / Rails関連
週刊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をデフォルト化する作業が進行中
Once Webpacker is the default in rails/master, we'll be unveiling the alpha version of a brand-new exciting framework for Rails 6.0 😄.
— DHH (@dhh) August 11, 2018
カバレッジを手伝ってくれる人募集中だそうです。
#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のスタブを生成しなくなる
Hahaha. It is not. Although, Active Reactive is a fun name 😄
— DHH (@dhh) August 11, 2018
つっつきボイス:「WebpackerになればなったでJSエンジンが必要になってくるので、今度はインストール要件が増えるんですよね〜😅」「ファイル数も増えますね😢」「さしあたってRailsを初めてインストールする人の手順が増えるという😆」「yarnはパッケージの管理に使ってるんでしたっけ?」「ですね」
⚓Cookieにpurpose
メタデータが追加
まとめ
このPRはcookieにpurpose
メタデータを追加することで、あるcookieの値を別のcookieにコピーして使えないようにする。その他の情報
config.action_dispatch.use_cookies_with_metadata
をオンにすると、expiry
とpurpose
メタデータが署名/暗号化済みcookieの内部に埋め込まれ、かつその署名/暗号化済みcookieの値がコピペされたかどうかを検証する。
従来のcookie設定(purpose
やexpiry
メタデータを使わないもの)も引き続き使える。
同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:cache
をrails dev:cache
に移動
- PR: Move `dev:cache` rake task to use Rails::Command by anniecodes · Pull Request #33559 · rails/rails
# 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さんの記事です。
つっつきボイス:「FayeやJuggernautよりはいいけれどと認めつつ『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より)
- リポジトリ: akabiru/fakerbot
- リポジトリ: stympy/faker
# 同リポジトリより
$ gem install fakerbot
$ fakerbot list
# Faker::BackToTheFuture
# ├── quote
# ├── date
# └── character
# Faker::Finance
# └── credit_card
# ....
つっつきボイス:「Fakerと言えばテストなんかで使う架空の名前を取れるヤツですね」「Fakerのどこに何があるのかをコマンドラインでさっと調べられるのか: しょっちゅう使うならこういう探し方したいのはワカル」「Fakerって日本語データもあった気が」「日本語ロケールあるし、こういう既存のデータで拡張もできますね↓😎」
ランダムな日本語のデータを生成するGemまとめ - Qiita
⚓go-on-rails: RailsアプリをGoコードに変換
Link: railstack/go-on-rails: Use Rails to Develop or Generate a Golang Application.: https://t.co/xbfLfoUXYs
— Yukihiro Matsumoto (@yukihiro_matz) August 21, 2018
つっつきボイス:「まだアルファ版っぽい感じで、よほど単純なRailsアプリじゃないと変換できなさそうな雰囲気でした: とりあえずオレオレRailsアプリを変換して生成されたgo_app↓を動かしてみると、普通のデフォルトRailsページが表示されました」
⚓「さようならImageMagick」
そういえばRailsはlibvipsを使う流れになってますね(ウォッチ)。
つっつきボイス:「ImageMagickの万能感はヤバいですからね: PDF生成もできるし、動画からの画像切り出しもできるし、GIFアニメーションも生成できるし、画像関係は本当にありとあらゆることができてしまうから💪」「守備範囲そんなに広かったのか😳」「この記事みたいに画像サムネイル作るだけなら明らかにImageMagickはオーバーキルだろうし、もっと軽いソリューションはあってもいいでしょうね」
「ImageMagickというと、gemでインストールしたときにC拡張のコンパイル時間かかるとか面倒という印象でしたが」「それはRMagicでインストールした場合でしょうね、たしか静的コンパイルしてたんじゃなかったかな: MiniMagickならコンパイル走らない(別途ImageMagickライブラリのインストールは必要ですが)」「そっか💦」
「ffmpegなんかもそうだけど、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が登場してたのを後から思い出しました💦。チェインできることと失敗時にロールバックできる点がポイントでした。
# 元記事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
- 元記事: Everyday Rails Testing with RSpec book updates for August 2018 | Everyday Rails -- 同書の英語版が更新されたそうです
なにか喋ります(( ⁰⊖⁰)/) - MedBeer -Rails開発での技術的負債との付き合い方- https://t.co/JpJsc3thrn #medbeer
— willnet (@netwillnet) August 22, 2018
⚓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実装
- リポジトリ: igrigorik/bloomfilter-rb
# 同リポジトリより
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)
というハッシュ並みの速度でデータの存在確認ができるアルゴリズムだそうです。
今はScalable Bloom Filterという強化版アルゴリズムもあるそうです。
参考: Scalable Bloom Filtersとは一体....? - Qiita
つっつきボイス:「ブルームフィルタをRubyで実装したと」「Rubyの実装はだいぶ前のものみたい」「ブルームフィルタみたいな、特定条件において速いアルゴリズムは探すと結構ありますね」「業務で使えそうでしょうか?」「通常の業務ロジックでここまでカリカリにチューニングすることはまずなさそうかなー😎」「スペルチェックを実装する時なんかには便利らしいです」「そういうふうに大量のデータの中に存在するかどうかだけをチェックするにはいいでしょうね」
⚓wavefile: Rubyで音声ファイルを扱う
- サイト: WaveFile Gem
- リポジトリ: jstrait/wavefile
# 同リポジトリより
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」募集開始
未受賞の個人が対象で、自薦もありだそうです。
真面目な話をすると、前から活動していた人でもここ数年の活動が目立っているような人がいましたらご推薦を https://t.co/7iwysFHwjK https://t.co/bY9VQjj8UE
— Shugo Maeda (@shugomaeda) August 17, 2018
⚓tty-pie_chart: キャラクタベースの円グラフ
- リポジトリ: piotrmurach/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
tmuxから出て作業したくないので全てのIDEはCUIで作り直されてほしい
— k0kubun (@k0kubun) August 22, 2018
⚓クラウド/コンテナ/インフラ/Linux/Serverless
⚓AWSのT3とNitro
- 元記事: New T3 Instances – Burstable, Cost-Effective Performance | AWS News Blog
- 元記事: Amazon EC2 アップデート – インスタンスタイプの追加、Nitro システム、CPU オプション | Amazon Web Services ブログ
つっつきボイス:「結局NitroだとAMIがそのままでは動かない: ドライバが必要になる」「今更ですみませんがNitroってそもそも何でしたっけ?🙇」「NitroはAWSが独自開発したハードウェアですね: Nitro版システムではストレージ周りでこれが使われていて、Hypervisorのドライバが違います」「なるほど😃」「なので単にインスタンスタイプを変更しただけではドライバが認識されないので起動しない😆」「つまりAMIを作り直す必要がある?」「ですね: それか頑張って何とかモジュールをロードするとか、Hypervisor部分だからそんなに深刻ではないけど面倒w」「新しくAMIを作るならNitroにしてもよさそう」「テストはされてるはずだし大丈夫じゃないかな☺️: Nitroの登場は割と最近で、割安かつスペックが高いのがメリット💰: クラウドは世代が新しいほどコスト対性能比がよくなっていくものなので」
参考: AWSの「Nitro System」(ナイトロシステム)とは? ベアメタルサーバ実現の裏側 |ビジネス+IT
参考: ハイパーバイザ - Wikipedia
⚓FunctionShield: サーバーレスアプリをポリシーで保護(Serverless Statusより)
- 元記事: FunctionShield: A Free Serverless Protection Library to Help Harden Your Serverless Apps
- サイト: PureSec FunctionShield
// 同サイトより: 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で動くグラフデータベース
- 元記事: On the release of RedisGraph v1.0 Preview | Redis Labs
- サイト: Redis Graph - a graph database module for Redis
- リポジトリ: RedisLabsModules/redis-graph/
- リポジトリ: RedisLabs/redisgraph-rb -- Rubyバインディング
↓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、恐ろしい子...!」
「ブルームフィルタのモジュールもあるし」「cthulhuっていうモジュールもいい名前❤️」「クトゥルー😆」「RedisからJSを呼べるみたい: 何でこの名前にしたのか知らんけど😆」
⚓JavaScript
⚓Vue CLI 3ではVueをTypeScriptで書けるようなった
- 元記事: Vue CLI 3
- リポジトリ: vuejs/vue-cli
つっつきボイス:「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』⭐
「Real World HTTP」が出版されます! https://t.co/gaR7C48vgv
— 渋川よしき (@shibu_jp) May 17, 2017
- 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の資料アップしました。100人にいいね!って言ってもらうよりも、5人にめちゃいいね!って言われるのを目標にしたので、95%の人は面白くないと思います。 #go111party https://t.co/mMUFQa3ktv
— 渋川よしき (@shibu_jp) August 22, 2018
Go 1.11 Release Party in Tokyo - connpassで発表された資料です。
なおGo 1.11は昨日リリースされました🎊。
つっつきボイス:「こちらが渋川さんのスライドです: Goって中身がほぼ空っぽのソースでもバイナリサイズが1MBぐらいになってしまうので、WebAssemblyだとサイズのデカさが不利になりがちです😢」「GCとかいろいろ機能を内包しているからしょうがないですね: shared libraryにリンクってできます?」「一応できます」
「スライドにあった『GoはリポジトリのURLとパッケージが密結合してる』これねー: Goの仕様を最初に見たときにこれ大丈夫か?って思ったけど、意外とみんな使ってるから大丈夫なのかな?」「いやー大丈夫じゃないですね💦: パッケージの依存関係管理はdepというツールに収束しそうではあるものの今も大変で、RubyのBundlerって本当に偉いなと思います」「そこでGoが見せてくれる夢はわかるけど、スライドにもあるようにローカルのプライベートパッケージまでやり始めると大変だろうなーとは思う☺️」「そうなんですよ~😢」
参考: 依存関係管理ツールdep(golang) - Qiita
⚓その他
⚓GoogleのCloud AutoMLで自分のテキスト学習モデルを育成できるようになった
- 元記事: AutoML Translation | AutoML Translation | Google Cloud
- サイト: Cloud AutoML - カスタム機械学習モデル | Google Cloud
つっつきボイス:「自分が持っている原文訳文を大量に食わせることで、機械翻訳なんかの学習モデルを自分で育成できるんだそうです: 週末遊んでみようかなと」「データを大量に持ってる人ならいいかもねー☺️」
参考: Google、Cloud AutoMLでテキスト分析と翻訳に対応、認知系AIサービスも強化:Google Cloud Next ’18 - @IT
⚓Basecamp「ヒルチャート」機能でプロジェクトの問題を直感的に理解する
つっつきボイス:「ヒルチャートって初めて知ったんですけどちょっとよさそうだなと思って」「ふむぅ、進捗管理とかでヒルを超えてないタスクがどのぐらいあるかをわかりやすく見せる感じ?」「ひと目でわかるのがいいなと思いました😋」「プロジェクト管理向きかも」
参考: New in Basecamp: See where projects really stand with the Hill Chart
⚓番外
⚓世界の中心はオレ
これ全部ラムセス2世だし、中にも延々とラムセス2世並んでるし、隣の奥さん用の神殿にもなぜかラムセス2世4体で奥さん2体を挟んでるという異常なまでの自己顕示欲っぷり
自撮りごときで自己承認欲求ガーとか笑ってる場合ではない、神殿を作れ#エジプト大冒険記 pic.twitter.com/6HCaHPqWnF— すいか (@cuamur) August 22, 2018
つっつきボイス:「これも渋川さんのリツィートからです」「今日は宇宙じゃなくて古代にw」「お、早めに終わったので台風が来る前に撤収〜」
今回は以上です。
バックナンバー(2018年度後半)
週刊Railsウォッチ(20180820)Railsで構築されたサイト40選、Deviseはつらいよ、ARのスコープとクラスメソッドの使い分けほか
- 20180813 Rails 5.2.1リリース、sanitize_sql_arrayは5.2からpublicだった、Dev.toがRailsアプリのソースを公開ほか
- 20180806 Rails 5.2.1.rc1リリース、Railsガイド日本語版が5.1に対応、Regexp#match?ほか
- 20180723 Railsdm Day 3 Extremeを後追い、PSDにはZeplin.io、好みの分かれるJSX、負荷テストツール比較ほか
- 20180709 Rails Developers Meetup Day 3 Extreme今週末開催、RailsのSTI/キャッシュ/添付ファイル/Redis/PDF出力、ECMAScript 2018、プロフェッショナルIPv6ほか
- 20180702 Ruby 2.2メンテ正式終了、Ransackがつらくなるとき、書籍『Domain-Driven Rails』、GitHubの高可用MySQLほか
- 20180622 Railsの需要未だ巨大、Unicode 11.0リリース、WebDriverがW3Cで勧告、Flutter.io、2封筒問題ほか
- 20180615 TTY gemとHTTPClient gemは優秀、Rubyの謎フリップフロップ、ちょいゆるRubyスタイルガイドほか
- 20180608 特集「RubyKaigi 2018後の祭り」、
Enumerable#index_with
は優秀、コントローラから@
を消し去るほか
今週の主なニュースソース
ソースの表記されていない項目は独自ルート(TwitterやRSSなど)です。