- Ruby / Rails関連
週刊Railsウォッチ(20180918)ビューテンプレート探索が高速化、mini_scheduler gem、レガシコントローラのリファクタリングほか
こんにちは、hachi8833です。先日の大江戸Ruby会議 07の白眉は、Rubyのキーワード引数分離についての議論↓と、Aaron PattersonさんのAsakusa.rb 10周年のお祝いメッセージが特濃だった(tenderlove/allocation_sampler)ところでした。Asakusa.rb10周年おめでとうございます!🎉🎉
@yukihiro_matz ruby-dev各位、今日のキーワード引数分離の課題をまとめた資料です。ご査収ください。https://t.co/zlolBwLs3Y
追って英語化します。
— Yusuke Endoh (@mametter) September 13, 2018
- 各記事冒頭には⚓でパーマリンクを置いてあります: 社内やTwitterでの議論などにどうぞ
- 「つっつきボイス」はRailsウォッチ公開前ドラフトを社内有志でつっついたときの会話です👄
今回のエントリは少なめです🙇。
⚓Rails: 先週の改修(Rails公式ニュースより)
つっつき時点では公式の更新情報がなかったのでコミットログなどから見繕いました。
⚓ビューテンプレート探索を高速化
かなり速くなったようです。
# actionview/lib/action_view/template/resolver.rb#L368
- exts = EXTENSIONS.map do |ext, prefix|
- if ext == :variants && details[ext] == :any
- "{#{prefix}*,}"
- else
- "{#{details[ext].compact.uniq.map { |e| "#{prefix}#{e}," }.join}}"
+ def find_template_paths_from_details(path, details)
+ # 可能なパスをすべてチェックするのではなく、他のglobと同様、正しいprefixを持つファイルを検索する
+ query = "#{escape_entry(File.join(@path, path))}*"
+ regex = build_regex(path, details)
+ Dir[query].uniq.reject do |filename|
+ # この正規表現は、(prefix以外にも)詳細部分にもマッチするファイルの探索と、
+ # 大文字小文字を区別しないファイルシステム向けのフィルタという2つの役割を担う
+ !filename.match(regex) ||
+ File.directory?(filename)
+ end.sort_by do |filename|
+ # ファイルを1つずつチェックするのではなくディレクトリを探索しているので、
+ # そのままでは戻り値の順序が一定しない
+ # この正規表現でのマッチ結果を用いて詳細部分をインデックスでソートする
+ match = filename.match(regex)
+ EXTENSIONS.keys.reverse.map do |ext|
+ if ext == :variants && details[ext] == :any
+ match[ext].nil? ? 0 : 1
+ elsif match[ext].nil?
+ # No match should be last
+ details[ext].length
+ else
+ found = match[ext].to_sym
+ details[ext].index(found)
+ end
+ end
+ end
- end.join
+ end
# 修正前
Warming up --------------------------------------
lookup users/show 6.000 i/100ms
Calculating -------------------------------------
lookup users/show 61.302 (± 4.9%) i/s - 306.000 in 5.011577s
# 修正後
Warming up --------------------------------------
lookup users/show 353.000 i/100ms
Calculating -------------------------------------
lookup users/show 3.845k (± 5.3%) i/s - 19.415k in 5.064962s
つっつきボイス:「globって何だろうと思ったらDir.glob
のことでした」「そういえばglob
ってあった」「コメントの日本語は🤔?」「あ、私が取り急ぎ訳しました」「今回の改善は著しいですね😍前よりコード量増えてるのに20倍近く速くなってる」「👍も30超えてるし」「ベンチマークではlookup_context.find_template
を調べてるのか↓」「裏方の改善だから何もしなくても恩恵が得られるヤツ😎」
# 同PRより
require './config/environment'
Benchmark.ips do |x|
x.report "lookup users/show" do
ApplicationController.new.lookup_context.find_template("users/show", [], false, {}, {})
end
end
参考: Dir.glob と Find の違い - Qiita
⚓ActionDispatch::IntegrationTest
にTestHelper
をインクルード
DHHのあげた#33838への対応です。
つっつきボイス:「これは小物かなと思いつつ」「integration testにTestHelper
がデフォルトでインクルードされたのか」「ActionMailer::TestHelper
には何が入ってるのかな...↓assert_*
系のメソッドか」「RSpecなんかだとこういうのを自分でインクルードしたりしますね」「せっかくテスト用ヘルパーがあるんだからデフォルトで入れてやろうぜってことなんでしょうね」「minitestですけどね☺️」
「今さらですけど、integration testはシステムテストとはまた別なんですよね?」「RSpecで言うとfeature testに相当するのがintegration testでしょうね: integration testはやったことないんですが」「そういえばintegration testでCapybaraは使われてるのかな?」「integration testはずっと前からRailsにあるんでCapybaraとは別でしょうね」「integration testはRailsフレームワーク自身のテスト用ですしね」「システムテストはCapybaraと共に導入されているし、間違いなくCapybaraと連携してる」
⚓Integer#multiple_of?
の高速化
riganiさんのアバターにしばし見とれてしまいました。
# activesupport/lib/active_support/core_ext/integer/multiple.rb#L10
def multiple_of?(number)
number != 0 ? self % number == 0 : zero?
number == 0 ? self == 0 : self % number == 0
end
zero?
より== 0
が速く、!=
より==
が速いんだそうです。
つっつきボイス:「Integer#multiple_of?
なんてのがあったの?」「倍数かどうかの判定ですね」「どれだけ速くなったのかな...1.33倍」「引数がゼロのときはこのぐらい速くなると」「ゼロ以外のときはそうでもない感じ」「numberが1のときもtrue
?😆」
「アバター自分で描いてるっぽい❤️」「この方、Nim言語というのもやってますね」「これそのうちウォッチで取り上げようかな😋(忘れないようにしないと💦)」
⚓ActiveRecordにfilter_attributes
属性を追加
59cae07を追っているうちにfilter_attributes
属性がつい最近追加されたことに気づきました。config.filter_parameters
を設定してあっても、誤って#inspect
されてログに出てしまうことがあったのを修正するためだそうです。
# activerecord/lib/active_record/core.rb#L129
+ # #inspect呼び出しで公開されたくないカラムを指定する
+ class_attribute :filter_attributes, instance_writer: false, default: []
# activerecord/lib/active_record/core.rb#L495
def inspect
filter_attributes = self.filter_attributes.map(&:to_s).to_set
# 初期化されていないオブジェクトが割り当てられている場合にwarningを生成しないよう
# defined?(@attributes)をチェック
inspection = if defined?(@attributes) && @attributes
self.class.attribute_names.collect do |name|
if has_attribute?(name)
- "#{name}: #{attribute_for_inspect(name)}"
+ if filter_attributes.include?(name) && !read_attribute(name).nil?
+ "#{name}: #{ActiveRecord::Core::FILTERED}"
+ else
+ "#{name}: #{attribute_for_inspect(name)}"
+ end
end
end.compact.join(", ")
else
"not initialized"
end
"#<#{self.class} #{inspection}>"
end
参考: ActiveRecord::Core::ClassMethods#filter_attributes
つっつきボイス:「filter_parameters
は確かに昔からありますね」「↓こうすると内部でinspect
が呼ばれてログに出てしまう」
# 同記事より
@account = Account.find params[:id]
payload = { account: @account }
logger.info "payload will be #{ payload }"
参考: Rails4でfilter_parametersのネスト - Qiita
「rails new
すると、"password"
というカラム名がフィルタされる設定がconfig/initializers/filter_parameter_logging.rbに書き込まれるんですね: フィルタしたいカラム名をこのファイルに追加できる」「Railsのログに[FILTERED]
って出ているとすげ~って思う💪: いつの間にって感じ」
「そういえばfilter_parameters
でフィルタするカラム名はシンボルや文字列で指定できるんですけど、たとえばうっかり:name
とか指定してしまうと、nameを含むカラム名と部分一致してことごとくフィルタされちゃったりするんですよね😅」「ありそう〜」「シンボルだからカラム名と完全一致しないとフィルタされないだろうと思うじゃないですか、でもそうじゃない: シンボルも文字列も実はカラム名と部分一致する😭」「😆」「だからフィルタが間違って効きすぎないようにするには、シンボルや文字列じゃなくて、正規表現を使って始まりと終わりもびしっと指定しないといけないんですよ」「まあpasswordという文字を含むカラム名は原則ログに出しちゃあかんというのはワカル: だからこそpassword_confirmation
とかもフィルタされるし」「安全側に倒すという意味ではそういう作りになるのはしょうがないのかも」「親切設計なんですけど、その親切を理解してないとつまらないワナを踏んじゃう」
参考: Railsのlogに出したくない情報をちゃんと出さないようにする - Qiita
Edgeguidesには「パラメータは正規表現の部分一致でフィルタされる」とあります。日本語版Railsガイドにはまだ反映されていませんが、現在作業中です。
なお、このPRでedgeapi.rubyonrails.orgというサイトがあることを今頃知りました。
「edgeapiはmasterブランチのRails APIをいち早く見ることができるサイトですね」「へぇえ〜、これちょっといいかも😋」
archive.orgで調べたらedgeapiは2010年からあるんですね💦。
⚓DatabaseLimits
で使われてないメソッドを非推奨化
column_name_length
table_name_length
columns_per_table
indexes_per_table
columns_per_multicolumn_index
sql_query_length
joins_per_query
つっつきボイス:「kamipoさんが『このメソッドたち絶対使わないっしょ』ということで非推奨にしたようです」「DatabaseLimits
って何だろそもそも?🤔」「たとえばsql_query_length()
なら、クエリの長さがこれ以上増えると実行できないから実行時に動的に調べる...やらねーよそんなこと😆」「😆」「遅くなるだけだし」「PRメッセージを見ると、単に使われてないだけじゃなくて、ほぼほぼテストされてないってありますね😵」「まあたとえばマイグレーションでクエリがすごく長くなって落ちる前に、ちょっと気の利いたメッセージを出すとかクエリを調整するとかしたい、なんて使いみちならあるかも?やらないだろうな〜やっぱり😆」
参考: Ruby on Rails 5.2 / ActiveRecord::ConnectionAdapters::DatabaseLimits — DevDocs
追いかけボイス: 「DatabaseLimits
、SQLを文字列として生成しているコードなんかではWHERE文のサイズが爆発してMySQLのmax_allowed_packet
を超過しちゃうということは割とあるので、その辺を見るメソッドだったんだろうなあと思った: AR/Arelで吸収して欲しいから使わないけど」「"WHERE hoge IN (#{bigger_ar_obj.pluck(:id).join(',')})"
とかやると溢れる」
⚓Rails
⚓Knapsackでテストを高速安定実行(RubyFlowより)
Knapsackは以前のウォッチでも取り上げましたが一応。同記事で紹介されているスライド↓は、その名もRUG::BというベルリンのRubyユーザーグループが主催した9月のミートアップ発表されたものです。
⚓mini_scheduler: Sidekiqで反復ジョブを登録するgem(Ruby Weeklyより)
- リポジトリ: discourse/mini_scheduler
# 同リポジトリより
class MyHourlyJob
include Sidekiq::Worker
extend MiniScheduler::Schedule
every 1.hour
def execute(args)
# some tasks
end
end
Discourseのgemです。
discourse.orgより
つっつきボイス:「every 1.hour
って書けるのね😲」「daily at: 12.hours
という書き方もできるみたいです」「役に立ちそうなgemでしょうか?」「使ってみないとわからないけど、こうやって表現できるのはいいことじゃないかな?」「Sidekiqでさっとスケジューリングしたいときにはいいのかも😋」
これとはあまり関係ありませんが、最近Railsdm Podcast #3↓に登場したy-yagiさんもactivejob-cancelというgemを作っています。
「ジョブのキャンセルってやっぱり面倒なんでしょうか?」「ジョブが動き出す前でもそもそもキャンセルしていいのかを判断しないといけないし、動き出してからだとキャンセル処理で原状復帰しないといけないし」「50%進めちゃったけどキャンセルしてよいのそれ?みたいなところを考えないといけないし、タイミングによってはシビアになるだろうし」
⚓sourcemaking.com: デザパタ/アンパタ/リファクタ/UMLを網羅した解説サイト
自著の販売促進サイトのようです。以下の3冊が紹介されています。
つっつきボイス:「たまたま見つけたんですが、デザパタもアンチパターンもリファクタリングもUMLもカバーしているサイトです」「ほほ〜?」「サイトのコンテンツのまとまりがとても良くて、おっと思いました: アンチパターンも開発アンチパターンにアーキテクチャアンチパターンにプロジェクト管理アンチパターン、リファクタリングもコードの臭いとリファクタリング手法と分かれています↓」「おー、デザパタのあたりを見てるけど、コード例にJavaとかPHPとかDelphiとかはあるけどRubyは入ってないか(残念!)」「アンチパターンはあまりコードを使わずに説明しているっぽい」「シングルトンパターンは雑にやるとマルチスレッドに対応できないとかちゃんと書いてあるのがエライ😋」
「Martin Fowlerさんのサイトとかの方が一次情報ですし内容も濃いと思うんですけど、あまりに雑然としていて追うのが大変なので😭」「😆」「Wolf ticketとか、知らないアンチパターンもありますね🤔」「こんなにいろいろあったかなと」「そういえばアンチパターンって凝った言い回しが多くて日本語にするのに四苦八苦します」
wolf ticketは「空約束」「看板に偽りあり」的な意味のようです。
⚓Rails OOP上級編(RubyFlowより)
# 同記事より
# lib/quote_connector.rb
require 'httparty'
class QuoteConnector
URL = 'https://talaikis.com/api/quotes/random/'.freeze
# since this is constant, we REALLY don't want to mutate it
def initialize(adapter: HTTParty)
@adapter = adapter
end
def call
adapter.get(URL).body
end
private
attr_reader :adapter
end
つっつきボイス:「記事の中に『DHHはDIを信じない』(2013年の記事)↓ってリンクがあるけど、知らなかった💦」「DIは基本的にJavaの問題解決手法だし、DHHがRubyでDIするか〜?っていう気持ちになるのはワカル」
参考: Dependency injection is not a virtue in Ruby (DHH)
「記事に出てくるinline bundler syntaxって何だろう?と思ったら、↓こういうふうにコードの中でbundlerを呼び出すのか😲」
# bundler.ioより
require 'bundler/inline'
gemfile do
source 'https://rubygems.org'
gem 'json', require: false
gem 'nap', require: 'rest'
gem 'cocoapods', '~> 0.34.1'
end
puts 'Gems installed and loaded!'
puts "The nap gem is at version #{REST::VERSION}"
「こういう書き方って再現コードとかでよく使われてたと思います: gemがなくてもREPLでその場で動かしたいコードとか」「へ〜!😳」「たとえばActiveRecordのバグを再現するときとかに、こうやってbundlerでこのgemとこのgemを読み込んで、ActiveRecordのテーブルはメモリ展開しておくとか」「確かに説明のためにRailsをフルでセットアップしてられないし」「プレゼンのときにも便利そう」「Gemfileを用意しなくてもいいですしね😎」
⚓レガシコントローラをSOLIDパターンでリファクタリング(Hacklinesより)
# 同記事より
module Api
module Admin
module Analytics
class ProductsController < V1::ApiController
def top_sold
raise ParamsMissing, 'params missing' if params_missing
raise InvalidDateInterval, 'range of days is not allowed' unless check_date_interval
response = perform(
merchant_id: current_merchant.id,
url: analytics_params[:url]
start_date: analytics_params[:start_date],
end_date: analytics_params[:end_date]
)
render json: ::Analytics::FormatService.top_product_format(response['metrics']), status: :ok
rescue RestClient::Exception => ex
render json: JSON.parse(ex.response), status: :unprocessable_entity
rescue => ex
render json: { message: ex.message }, status: :unprocessable_entity
end
...
...
...
end
end
end
end
end
つっつきボイス:「リファクタリング前↑はやたらraiseとかrescueとかしまくっててごちゃごちゃしてる」「よく起こりがちなコード👓」「ざっとしか見てないけど、リクエストとレスポンスの処理を分けつつ、エラーハンドリングやバリデーションを切り出してそこに委譲する感じかな〜」
# 同記事より
module Anaylytics
class Request
module ErrorsHandler
include AcctiveSupport::Concern
include ActiveSupport::Rescuable
included do
rescue_from RequestError, with: :deny_access
end
protected
class RequestError < StandardError
...
...
...
end
private
def deny_access
...
...
end
end
end
end
「ぱっと見Railsと関係ないコードかな?っと思ったけど、rescue_from
↑が出てくるのはもうRailsのコードに間違いない😋」
参考: Ruby on Rails 5.2 / ActiveSupport::Rescuable::ClassMethods#rescue_from
— DevDocs
「最終的に以下のようにErrorsHandler
をインクルードすればRequest.get
でエラー処理ができるようになる感じかな」「よしよし☺️: 本線の処理とエラーの処理は別にしたいし」
# 同記事より
...
...
include Analytics::Request::ErrorsHandler
def top_sale
response = Anaylytics::Request.get(:top_sale, params: {
merchant_id: current_merchant.id,
start_date: analytics_params[:start_date],
end_date: analytics_params[:end_date]
})
render json: response, status: response.code
end
...
...
⚓Ruby
⚓ネイティブ拡張を使うgemを書く(Ruby Weeklyより)
- 元記事: Writing a Gem with native extensions | Tristan Penman's Blog
- リポジトリ: tristanpenman/simple-clipboard
#include <ruby.h>
#include <libclipboard.h>
#include "extconf.h"
static clipboard_c *cb = NULL;
VALUE set_text(VALUE _self, VALUE val) {
Check_Type(val, T_STRING);
VALUE result = Qnil;
char *text = clipboard_text(cb);
if (NULL != text) {
result = rb_str_new(text, strlen(text));
free(text);
}
if (false == clipboard_set_text(cb, StringValueCStr(val))) {
rb_raise(rb_eRuntimeError, "Failed to write to clipboard.");
}
return result;
}
VALUE get_text(VALUE _self) {
VALUE result = Qnil;
char *text = clipboard_text(cb);
if (NULL != text) {
result = rb_str_new(text, strlen(text));
free(text);
}
return result;
}
void Init_simple_clipboard() {
cb = clipboard_new(NULL);
if (NULL == cb) {
rb_raise(rb_eRuntimeError, "Failed to create clipboard context.");
}
VALUE mod = rb_define_module("SimpleClipboard");
rb_define_module_function(mod, "get_text", get_text, 0);
rb_define_module_function(mod, "set_text", set_text, 1);
}
つっつきボイス:「いわゆるやってみた系の記事かなと思いますが」「お、クリップボードを扱うのか」「クリップボードの中身を取り出すにはどこかでシステムにアクセスしないといけないからC拡張でやったんでしょうね」「素のRubyからクリップボードを扱うのは大変そう」
後でclipbordというそれ用のgemがあるのを見つけました。
- リポジトリ: janlelis/clipboard
⚓RubyとRustでそれぞれパスワード生成してみた(Ruby Weeklyより)
# 同記事より
Options.number.times do
password = Options.length.times.map do
dict.sample(random: SecureRandom)
end.join(Options.separator)
puts password
end
# 同記事より
use std::iter::repeat_with;
let mkpass = || {
repeat_with(|| rng.choose(&dict).expect("dictionary shouldn't be empty"))
.take(opts.length)
.map(|s| *s)
.collect::<Vec<&str>>()
.join(&opts.separator)
};
⚓Redisでインメモリのブルームフィルタを実装する(Ruby Weeklyより)
記事では、当初は先月のウォッチでも扱ったbloomfilter-rbを使ったのが、コンカレンシーの問題と更新の遅さを解決するため自分たちで再実装したとのことです。
# 同記事より
temporary_bloom_filter = TemporaryBloomFilter.new(user)
temporary_bloom_filter.insert(['user3@example.com', 'user4@example.com', 'user5@example.com'])
temporary_bloom_filter.count
# => 5
temporary_bloom_filter.include?('user5@example.com')
# => true
temporary_bloom_filter.include?('user6@example.com')
# => false
参考: What is a Bloom Filter Pattern? | Redis Labs -- Redisでサポートされているrebloomというデータ型(記事では使わなかったとのこと)
つっつきボイス:「ブルームフィルタはfalse positiveはあってもfalse negativeはないんだそうです」「つまり間違って『ある』と判定する可能性はあっても間違って『ない』とは判定しないってことね😋」
⚓bindef: Rubyで書かれたバイナリ生成DSL(Ruby Weeklyより)
# 同記事より
# 以後の文字列エンコードをUTF-32にする
pragma encoding: "utf-32"
str "hello"
str "there"
# 以後の文字列エンコードをUTF-8にする(デフォルト)
pragma encoding: "utf-8"
str "utf-8!"
# pragmaにブロックを渡してスコープを絞れる
pragma endian: :big do
# このブロック内ではビッグエンディアンのみを出力
# Rubyの名前空間と定数は通常どおり機能することと、
# `bindef`は`f32`と`f64`でfloatを使うことに注意
# of `f` and `d`.
i64 0xFF00FF00
f64 Math::PI
f32 Float::INFINITY
end
つっつきボイス:「ビンデフ?」「pragma
とか出てくるとCとかC++みたい」「pragma
ってAda言語が元だったのか」「AdaというとAda Lavelaceから命名されたという古典ネタをつい思い出してしまいました」
参考: C言語 プリプロセッサ
参考: Ada について話します - Qiita
⚓クラウド/コンテナ/インフラ/Linux/Serverless
⚓AWS System Managerにsshなしでコンソールログインできる「Session Manager」機能登場
- 元記事: New – AWS Systems Manager Session Manager for Shell Access to EC2 Instances | AWS News Blog
- ドキュメント: AWS Systems Manager Session Manager - AWS Systems Manager
つっつきボイス:「ssh鍵なしでブラウザからコンソールが使えるのはありがたいかも☺️」「それがいいのかというのはさておいて😆」「自分のPCがない客先とか旅行先でも使えるし」
参考: SSH不要時代がくるか!?AWS Systems Manager セッションマネージャーがリリースされました! | Developers.IO
⚓SQL
⚓PostgreSQLのchar
型に使いみちはあるか(Postgres Weeklyより)
xof=# select length(c) from chars;
length
--------
1
(1 row)
xof=# select substring(c from 8 for 1) = ' '::char(1) from chars;
?column?
----------
t
(1 row)
xof=# select substring(c from 8 for 1) = ' '::varchar(1) from chars;
?column?
----------
f
(1 row)
xof=# select length(substring(c from 8 for 1)) from chars;
length
--------
0
(1 row)
xof=# select c || 'y' from chars;
?column?
----------
xy
(1 row)
つっつきボイス:「char
を使っても節約できるのはたかが知れてるし、挙動も何だか謎なので、長さが1より大きいならvarchar
かtext
でいいんじゃね?という話のようです」「' '::char(1)
だとtrueだけど' '::varchar(1)
だとfalse...」「char
はやっぱり固定幅なのね」「使わないかな〜」「使わないですね」
追いかけボイス: 「DBMSのchar型は、アラインメントを合わせたりできるのでカリカリにチューニングするDBAな人達とかは結構神経質にやってる人もいると思う: DBAがいるようなプロジェクトでないとあまり見ないけど」
⚓ZomboDB: PostgreSQLをElasticsearchと連携(Postgres Weeklyより)
-- 同リポジトリより
CREATE EXTENSION zombodb;
CREATE TABLE products (
id SERIAL8 NOT NULL PRIMARY KEY,
name text NOT NULL,
keywords varchar(64)[],
short_summary text,
long_description zdb.fulltext,
price bigint,
inventory_count integer,
discontinued boolean default false,
availability_date date
);
CREATE INDEX idxproducts
ON products
USING zombodb ((products.*))
WITH (url='localhost:9200/');
つっつきボイス:「★1600超え」「普通にElasticsearchを使えばいいのかな?と思いつつ」「PostgreSQLで一貫して使いたい人向けなんでしょうね」「↑上みたいにCREATE EXTENSION zombodb;
してUSING zombodb
とすると使えるようになると」「WITH (url='localhost:9200/')
は全文検索サーバーのURLを指定するってことなのかな?🤔」「するとこんなふうに==>
でElasticsearch風なクエリを書ける↓と」「アプリ層からは普通にSQL叩いているように見えるのはちょっとうれしいかも」「この追加クエリ部分はSQLじゃないですけどね🤣」「ちなみにまだベータ版だそうです」
SELECT *
FROM products
WHERE products ==> '(keywords:(sports OR box) OR long_description:"wooden away"~5) AND price:[1000 TO 20000]';
当初Elasticsearchがなくても使えるのかなと思ったのですが、system requirementで5.6.xか6.xと指定されていました。
⚓その他SQL
⚓CSS/HTML/フロントエンド/テスト
⚓Priority Hints
- 元記事: HTML要素からHTTP/2優先度を指定する Priority Hints が動いた - ASnoKaze blog
- W3C仕様(まだWICG): Priority Hints
<img src="img/1.png" importance="high">
<img src="img/2.png" importance="low">
<img src="img/3.png" importance="low">
<img src="img/4.png" importance="high">
つっつきボイス:「importance="high"
とか書けるのっていい!😍」「何だか夢みたいじゃないですか😆」
⚓HTTP発展小史
- HTTP 0.9
- HTTP/1.0
- HTTP/1.1
- HTTP/2
つっつきボイス:「HTTP 0.9なんてのがあったんですねっ😆」「😆」「HTTP/1.1ってどんだけ長く使われてるんだと」「この日進月歩の時代に☺️」「このサイトにはHigh Performance Browser Networking (O'Reilly)を掲載しているようですが何だか丸ごと載せてるみたい」「太っ腹🤩」
⚓言語よろずの間
⚓日本語Wikipediaエンティティベクトル
公開して頂きありがとうございますm(_ _)mhttps://t.co/oFK7lpPakW
— 五島僚太郎 | ryotaro goto (@510_five) September 11, 2018
同記事より(CC BY-SA 4.0)
つっつきボイス:「比較的シンプルな処理でいい感じにできるのがいいなと思って: 『ヤマハ』と『ヤマハ発動機』の類似度の違いとか、北海道の札幌に相当するのは沖縄県のどこか、とか」「おぉ〜面白い☺️」
⚓その他言語よろず
読みたい #golang / “https://t.co/iv0XzY98BQ: Go言語による並行処理: Katherine Cox-Buday: Book” https://t.co/aU99o2tbsy
— mattn (@mattn_jp) September 13, 2018
⚓その他
⚓イノベーションのジレンマ
今の状況が良くまとまってて、分かりやすい良記事。
日本のロボット業界は今、「イノベーションのジレンマ」に陥りかけている 森山和道の「ロボット」基礎講座|ビジネス IT https://t.co/qfeFK3kgYt #sbbit @bitsbbitさんから— m_kawabe (@mkawabe7) September 5, 2018
⚓Inbox by Gmailが消える?
Google is Killing Its 4-Yr-Old Inbox Email App https://t.co/rSsWnxgbzz
— Slashdot (@slashdot) September 12, 2018
つっつきボイス:「個人的にちょっとショックだったので😭」「これも消えるんですね〜: Gmailに注力するって書いてあるみたいだし」「一瞬使ってたけど☺️」「これだけ大きい企業なのにあっさりやめるあたりが、上の『イノベーションのジレンマ』の逆を行ってる感😆」「Google、Pixelは日本で出さないのに...😢」「そういえば今度Pixelを日本で発売するとかしないとかでざわついてますね↓」
参考: Google、新型スマホのティーザーサイト公開 「Pixel 3」日本発売か - ITmedia NEWS
⚓番外
⚓メイドイン軌道の高性能光ファイバー
- 元記事: Optical fibre made in orbit should be better than the terrestrial sort - Manufacturing in space -- 要サブスクライブ
- Reddit: Optical fibre made in orbit should be better than the terrestrial sort - fewer flaws and longer lengths. : space
参考: 史上初の宇宙製品は地球産の100倍高性能な光ファイバーかもしれない - GIGAZINE
今回は以上です。
バックナンバー(2018年度後半)
週刊Railsウォッチ(20180910)公開つっつき会#2、RSpecは何を参考にするか、イベントソーシング、marginalia gem、負荷テストツールvegetaほか
- 20180903 次世代アップローダーgem「Shrine」、RSpecをどこまでDRYに書くか、Rubyのmainオブジェクトの秘密、GitLabのCookie利用許諾機能はエライほか
- 20180827 Ruby Prize 2018募集開始、Interactor gemとReader Object、書籍『Real World HTTP』、Basecampのヒルチャート機能ほか
- 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など)です。