週刊Railsウォッチ(20180126)Bootstrap 4登場でbootstrap_form gemが対応、PostgreSQLやnginxの設定ファイル生成サービスほか

こんにちは、hachi8833です。ついに東京都のインフルエンザ流行が警報を超えました。剣呑剣呑。

1月最後のRailsウォッチ、いってみましょう。

Rails: 今週の改修

今週も主に最近のcommitから見繕いました。

assert_changesが式の変更を認識するよう修正

# activesupport/lib/active_support/testing/assertions.rb#159
-        if to == UNTRACKED
-          error = "#{expression.inspect} didn't change"
-          error = "#{message}.\n#{error}" if message
-          assert before != after, error
-        else
+        error = "#{expression.inspect} didn't change"
+        error = "#{error}. It was already #{to}" if before == to
+        error = "#{message}.\n#{error}" if message
+        assert before != after, error
+
+        unless to == UNTRACKED

つっつきボイス:assert_changesに評価前の値が渡ってたということか」

nil/falseチェックをtrue/falseチェックに修正

activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb#86
       def initialize(connection, logger, connection_options, config)
         super(connection, logger, config)

-        @active     = nil
+        @active     = true
         @statements = StatementPool.new(self.class.type_cast_config_to_integer(config[:statement_limit]))
       end
...
       def active?
-        @active != false
+        @active
       end

つっつきボイス: 「これは直したいやつ: SQLite3ってまず使わないけど」「そういえばSQLite3ってもうRailsのデフォルトから外れてる?」「まだデフォルトはSQLite3ですね」

ActionMailer::Base.defaultのprocの引数の個数(アリティ)を1に戻した

# actionmailer/lib/action_mailer/base.rb#901
+      def compute_default(value)
+        return value unless value.is_a?(Proc)
+
+        if value.arity == 1
+          instance_exec(self, &value)
+        else
+          instance_exec(&value)
+        end
+      end

もしかしてarityって、binaryとかunaryとかtrinaryの「-ary」から来てるんでしょうか。とても造語っぽい。


つっつきボイス:Proc#arityって可変長の場合マイナスの値を返すのか!」「でも確かにRubyとしてはここでInteger以外の値を返したくないだろうな」「arityはプログラミング業界の造語っぽいですねー」「私の手元にある英語辞書串刺し検索でも類似のもの出てこないです」

参考: Ruby 2.5.0リファレンスマニュアル Proc#arity
参考: Wikipedia-ja アリティ

has_many :through関連付けでレコードがdestroyされてない状態でカウンタキャッシュを更新しないよう修正

# activerecord/lib/active_record/associations/has_many_through_association.rb#145
           case method
           when :destroy
             if scope.klass.primary_key
-              count = scope.destroy_all.length
+              count = scope.destroy_all.count(&:destroyed?)
             else
               scope.each(&:_run_destroy_callbacks)
               count = scope.delete_all

つっつきボイス: 「ふむう、scope.destroy_all.lengthの返す値がタイミングによって適切でなかったってことなのかな」

参考: ActiveRecord::Relation#destroy_all

JRuby向け: opt = options.dupを追加

# railties/lib/rails/generators/app_base.rb#316
       def convert_database_option_for_jruby
         if defined?(JRUBY_VERSION)
-          case options[:database]
-          when "postgresql" then options[:database].replace "jdbcpostgresql"
-          when "mysql"      then options[:database].replace "jdbcmysql"
-          when "sqlite3"    then options[:database].replace "jdbcsqlite3"
+          opt = options.dup
+          case opt[:database]
+          when "postgresql" then opt[:database] = "jdbcpostgresql"
+          when "mysql"      then opt[:database] = "jdbcmysql"
+          when "sqlite3"    then opt[:database] = "jdbcsqlite3"
           end
+          self.options = opt.freeze

元のPR #31641では、frozen_string_literalを外してどうにかしようとしていたのをy-yagiさんが「外さない方がいい」とdupでやる方法を勧めてこうなったようです。

changes_appliedのパフォーマンス低下を修正

PR #30985 Move Attribute and AttributeSet to ActiveModelで低下したパフォーマンスをkamipoさんが修正しました。

Before:

Warming up --------------------------------------
create_string_columns
                        73.000  i/100ms
Calculating -------------------------------------
create_string_columns
                        722.256  (± 5.8%) i/s -      3.650k in   5.073031s

After:

Warming up --------------------------------------
create_string_columns
                        96.000  i/100ms
Calculating -------------------------------------
create_string_columns
                        950.224  (± 7.7%) i/s -      4.800k in   5.084837s

つっつきボイス: 「変更量多かったので結果を貼ってみました」「変更内容は繰り返し多いですけどね: 無駄な参照を減らして毎回総ナメしなくていいようにするなどして高速化したように見える」

# activerecord/lib/active_record/attribute_methods/dirty.rb#113
       # Alias for +changed+
       def changed_attribute_names_to_save
-        changes_to_save.keys
+        mutations_from_database.changed_attribute_names
       end

HasOneThroughAssociation#build_recordを修正

最新のRails 5.2 (と5.1も)で、HasOneThroughAssociation#build_recordメソッドを使ってHasOneThroughAssociationを手動でビルドできない。
再現用のサンプルアプリでこのメソッドを呼ぶと以下がraiseされる:

NameError: undefined local variable or method `through_association' for #
<ActiveRecord::Associations::HasOneThroughAssociation:0x007fa209d2f7a0>

HasOneThroughAssociationでは、(HasManyThroughAssociationオブジェクトと異なり)#build_recordメソッドでのThroughAssociationミックスインに必要な#through_associationが定義されてないっぽい。
#31762より大意


つっつきボイス: 「ま、HasOneみんなあんまり使ってないけど」「たまに必要ー」

bulk_change_table<< procs#concatに変更

# activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb#375
             if respond_to?(method, true)
               sqls, procs = Array(send(method, table, *arguments)).partition { |v| v.is_a?(String) }
               sql_fragments << sqls
-              non_combinable_operations << procs if procs.present?
+              non_combinable_operations.concat(procs)
             else
               execute "ALTER TABLE #{quote_table_name(table_name)} #{sql_fragments.join(", ")}" unless sql_fragments.empty?
               non_combinable_operations.each(&:call)

つっつきボイス: 「修正は純粋な高速化」「そういえばこのbulk_change_tableってkamipoさんが最近何か追加したんじゃなかったかな?」「そういえばごく最近のウォッチ↓で扱った#31331ですね」

週刊Railsウォッチ(20180112)update_attributeが修正、ぼっち演算子`&.`は`Object#try`より高速、今年のRubyカンファレンス情報ほか

リレーションに渡していたassociation引数を削除

# activerecord/lib/active_record/association_relation.rb#3
module ActiveRecord
   class AssociationRelation < Relation
-    def initialize(klass, table, predicate_builder, association)
-      super(klass, table, predicate_builder)
+    def initialize(klass, association)
+      super(klass)
       @association = association
     end

associationはまず要らないだろうということで削除されました。


つっつきボイス: 「他の引数から辿れるならassociationなくてもいいな」「お、こうやってちゃんとキーワード引数使って修正してる↓: 修正前のは古い書き方」「{}は残ってるけど、superに渡したりするかもだしインターフェイス変えるわけにはいかないか」

# activerecord/lib/active_record/relation.rb#25
-    def initialize(klass, table, predicate_builder, values = {})
+    def initialize(klass, table: klass.arel_table, predicate_builder: klass.predicate_builder, values: {})

Rails

Bootstrap 4がついに正式リリース

先週のウォッチを公開した直後にリリースされました。


getbootstrap.comより


つっつきボイス: 「もうね、どんだけ待たされたのかと」「Bootstrapのトップページが変わってから半年経たずにリリースだから早い方かな」「4のテンプレートもとっくに販売されてますしね」

bootstrap_form gemがBootstrap 4に対応(Awesome Rubyより)

<!-- リポジトリより -->
<%= bootstrap_form_for(@user, layout: :inline) do |f| %>
  <%= f.email_field :email, hide_label: true %>
  <%= f.password_field :password, hide_label: true %>
  <%= f.check_box :remember_me %>
  <%= f.submit %>
<% end %>

つっつきボイス:bootstrap-rubyって人たちがいるのか: 本家Bootstrapのリポジトリとは別なのかな?」「どうやら本家のはtwbsにあるtwbs/bootstrap-rubygemですね: ということはbootstrap-rubyは公式ではないと」「なかなかややこしい」

このgemではDry-rbのDry-auto_injectを使っています。

Ruby: Dry-rb gemシリーズのラインナップと概要

kan: 軽量な認証/承認ライブラリ(Awesome Rubyより)

# リポジトリより
class Post::AdminAbilities
  include Kan::Abilities

  register :read, :edit, :delete { |user, _| user.admin? }
end

class Comments::Abilities
  include Kan::Abilities

  register 'read' { |_, _| true }
  register 'edit' { |user, _| user.admin? }

  register :delete do |user, comment|
    user.id == comment.user_id && comment.created_at < Time.now + TEN_MINUTES
  end
end

つっつきボイス: 「カン、って読むのかな?」「もしかするとCanCanCanのもじりか」「確かにCanCanCanっぽい匂いを感じる気がする」「まあこういうのって一度は作りたくなるんですよ: 既存のものがうまく合わないときとか」「モデルにアタッチするというよりAbilityregisterしていく、どっちかというとコントローラに結合させていく感じですかね」

rack-cache: HTTPキャッシュやバリデーションを行うRackミドルウェア(Awesome Rubyより)

# リポジトリより
# config/application.rb
config.action_dispatch.rack_cache = true
# or
config.middleware.use Rack::Cache,
   verbose:     true,
   metastore:   'file:/var/cache/rack/meta',
   entitystore: 'file:/var/cache/rack/body'

つっつきボイス:nginxの設定ファイルをRubyで書きたい人向けなのかな?」「全部Rubyで書きたい気持ちはわかる: nginxの設定ファイルの記法って結構特殊だし」「そういえば最近はnginxの設定ファイルを自動生成するサービスがありますね↓: 最終的には自分で仕上げないといけないですが」


nginxconfig.ioより

「rack-cacheが欲しい人がいるとすれば、ミドルウェアのないJava Serveletみたいな世界から来た人たちが直接下のレイヤをチューニングしたい、とかかも」

acts_as_votable: 投票機能に特化したActiveRecord向けgem(Awesome Rubyより)

# リポジトリより
class Post < ActiveRecord::Base
  acts_as_votable
end

@post = Post.new(:name => 'my post!')
@post.save

@post.liked_by @user
@post.votes_for.size # => 1

つっつきボイス: 「voteとかvotableって、最初パターンの名前か何かと思ったら違うみたいでした」「文字どおりの機能です: こういうモジュール化は割りと簡単に書けるから皆さんもぜひ一度やってみるといい: 特にメタプロの練習には絶好」「機能がここまで簡素で特化していれば大してバグらないだろうし」「きっと自分のプロジェクトで機能をgemに切り出して、せっかくだから公開したとかそういうノリなんでしょうね」
「そういえばRails 3ぐらいの頃はこういう↓acts asなんちゃらみたいなモジュール名がとても流行ってましたね: 今は流行ってないけど」

【Rails】acts_as_paranoid uniquenessでハマる

Railsでフィールドのキャッシュが無効になる問題をDSLで解決する

# 同記事より
class User < ActiveRecord::Base
  include Touchable
  touch :tasks, in_case_of_modified_fields: [:first_name, :last_name]
...
end
class Task < ActiveRecord::Base
  has_one owner, class_name: :User
end

つっつきボイス: 「キャッシュを明示的にクリアしないと残っちゃう的な問題ですね」「キャッシュを頻繁に更新したいことって多いんですか?」「多いですよー: 生成にすごく時間のかかるものとか、リクエストが来てからレンダリングしてたら到底間に合わないんで、こうやって変更時に明示的にtouchするとかしないと」

Paypal PayoutsをRailsで使う(RubyFlowより)

既存のMass Payは今後非推奨になるそうです。


cookieshq.co.ukより


つっつきボイス: 「PayPalのインターフェースって数が多すぎてマジでわからなくなったりするんだよなー」「Mass Payってちょいダサいネーミングな気が」「一括処理らしさは伝わるかな」

Rails + Reduxアプリを作ってみた


hackernoon.comより


つっつきボイス:SPA的なアプリやるならこういう構成でしょうね」

Railsのバックグランドジョブにsucker_punchを使う(RubyFlowより)

sucker_punchはメモリ上に展開するので非常に速い代わりに、ジョブキューが非常に多い場合には不向きだそうです。


つっつきボイス: 「sucker_punch、すごい名前w」「Redisサーバーとかを立てないでやりたいときにいいのかな」「昨年末のRails勉強会@Tokyoで、sucker_punchは最近メンテされてなさげって聞いた気がします」

sucker punch: いきなりのパンチ[殴打]、不意打ち、急襲

plan.io: Redmineのセキュリティチェックサービス


plan.ioより

ファクトリーで注意すべき点(Ruby Weeklyより)

# 同記事より
it "downcases the location on save" do
  user = create(:user, location: "Boston", first_name: "Joël")

  expect(user.location).to eq "boston"
end

つっつきボイス: 「ファクトリーでどこまでやるかというのはある」「ファクトリーって基本はデフォルト値の置き場かなー」「そう思う」「テストデータを一番簡単に作るやつ」「has manyとか増えてくると条件がどんどんややこしくなって結局自分でビルダー作る方が早かったり」

「Railsのfind_byにSQLインジェクションの脆弱性」に異議が唱えられる

** DISPUTED ** SQL injection vulnerability in the ‘find_by’ method in Ruby on Rails 5.1.4 and earlier allows remote attackers to execute arbitrary SQL commands via the ‘name’ parameter. NOTE: The vendor disputes this issue because the documentation states that this method is not intended for use with untrusted input.
nvd.nist.govより

参考: JVNDB-2017-011712

** 未確定 ** 本件は、脆弱性として確定していません。
jvndb.jvn.jpより


つっつきボイス:find_byにインジェクション…だと?」「disputed: 係争中ですね」「そもそもfind_byって信頼できるものしか渡さないでしょ普通」「そういえばSQLインジェクションをいっぱい集めたサイトありますよね↓」「そうそう、この辺の話」

# rails-sqli.orgより
params[:id] = "admin = 't'"
User.find_by params[:id]

巨大なRailsアプリでRubocopをパスするには

$ rubocop --format offences
11010 Metrics/LineLength
3140 Style/StringLiterals
2201 Style/FrozenStringLiteralComment
1891 Style/Documentation
…and thousands of rare offences
1 Style/ZeroLengthPredicate
 — 
26154 Total

つっつきボイス: 「あるある、後からRubocopかけるとこういうエグいのが出てくる↑」「そっ閉じするヤツw」「rubocop -aで最近ヒアドキュメントが壊れたりする」「『inherit_from: .rubocop_todo.ymlするな』ってのは正しい: やったら絶望できる」「少しずつ項目を増やすのが吉」「『これだけは許せない』っていうymlだけ作って共有したいです」「プロジェクトや会社によっていろいろ宗教が違うんで大変だけど」

「line lengthのチェックが邪魔で」「自分はline length 200ぐらいあってもいいかな: あんまり長いのは確かに嫌だけど」
「gemのアルファベット順並びチェックされるのも嫌ですよね」「あれは空行入れればブロックが分かれるはず: 空行なしでべた書きすると言われるしそれはわかる」「Rubocopに言われるままの修正だけだと何のアウトプットにもならないのがなー」(以下延々続く)

「JetBrainsのUpsourceみたいな方向でIDEとRubocopが統合されたら幸せになれるかな: ちなみにUpsourceはとっても優秀で、Web画面からinspect definitionとかのJetBrainsのエディタ機能が使えるし、逆にRubyMineとかからレビューコメント付けたりもできる」「へー!」「Upsource、10人まで無料なのか」「GitLabのWeb IDEも似た路線でとてもいいんだけど一番高いエディションが必要」


jetbrains.comより

「お、モーフィアスが」「マトリックス知ってる人がいて何だかほっとしたー」

#yield_selfは思ったよりいいぞ(RubyFlowより)

# 同記事より
# before
url = construct_url
response = Faraday.get(url)
data = JSON.parse(response.body)
id = data.dig('object', 'id') || '<undefined>'
return "server:#{id}"
# or, short yet less readable form:
return "server:" +
  (JSON.parse(Faraday.get(construct_url)).dig('object', 'id') || '<undefined>')

# after:
construct_url
  .yield_self { |url| Faraday.get(url) }
  .yield_self { |response| JSON.parse(response) }
  .dig('object', 'id').yield_self { |id| id || '<undefined>' }
  .yield_self { |id| "server:#{id}" }

# with method()
construct_url
  .yield_self(&Faraday.method(:get))
  .body
  .yield_self(&JSON.method(:parse))
  .dig('object', 'id').yield_self { |id| id || '<undefined>' }
  .yield_self { |id| "server:#{id}" }

「メソッド名はクソだけど」だそうです。

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

Rails小粒記事2本

めちゃ短い記事です。著者はいずれも同じ人です。


つっつきボイス: 「TechRachoの朝記事向けに短い記事も押さえておきたかったので」「(3本目)SELF JOINはSQLやってる人なら普通に使うやつ」

Ruby trunkより

C-APIからの不要なexportをなくしてパフォーマンス向上(反映->close)

Ruby 3でprime_divisionを強化&修正

使うにはrequire 'prime'が必要です。

# 14383より
-1.prime_division
 => [[-1,1]]

0.prime_division
Traceback (most recent call last):
        4: from /home/jzakiya/.rvm/rubies/ruby-2.5.0/bin/irb:11:in `<main>'
        3: from (irb):85
        2: from /home/jzakiya/.rvm/rubies/ruby-2.5.0/lib/ruby/2.5.0/prime.rb:30:in `prime_division'
        1: from /home/jzakiya/.rvm/rubies/ruby-2.5.0/lib/ruby/2.5.0/prime.rb:203:in `prime_division'
ZeroDivisionError (ZeroDivisionError)

つっつきボイス:prime_divisionって素因数分解か」「おーこんなメソッドあるんだ」「ゼロも整数」

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

forが要素をsplatしない

a = [Struct.new(:to_ary).new([1, 2])]
a.each {|i, j| p [i, j]} #=> [1, 2]
for i, j in a; p [i, j]; end #=> [#<struct to_ary=[1, 2]>, nil]


つっつきボイス: 「おー、forで変数が展開されないってことか」「nobuさんが投げたやつですが今のところ動きなさそう」「forだと動きにぶいでしょうね: そもそもRubocopに直されちゃうw」「直されるべき」

Ruby

Java経験者が知っておきたいRubyの特徴(RubyFlowより)

// Java
public static Object create(Class c, String value) throws Exception
{
  Constructor ctor = c.getConstructor( new Class[] { String.class } );
  return ctor.newInstance( new Object[] { "Hello" } );
}

public static void main (String args[]) throws Exception
{
  Greeting g = (Greeting) create(Greeting.class, "Hello");
  g.show();
}
# Ruby
def create(klass, value)
  klass.new(value)
end

g = create(Greeting, "Hello")
g.show

つっつきボイス: 「うん、これはなかなかいい記事」「Java出身のkazzさんがきっと好きだと思って」「ここでいうmessageってメソッド呼び出しのことなんじゃ?」「messageってSmalltalkの用語じゃん!: Javaじゃなかったのかw」「書いた人が結構いい年の予感」

参考: Wikipedia-ja Smalltalk

Ruby 25周年でメッセージ募集


つっつきボイス: 「『私とRubyの初めての出会い』みたいな感じならみんなだいたい書けるんじゃ?」「自分のときは、学部1〜2年の頃使ったCD-ROMライターPCのFedora Linuxのインストールスクリプトか何かがRubyだったなー: たぶんバージョン0.xぐらいの頃」
「そういえば未踏の一番最初がRubyだったんじゃないかな」「そうなんだ!」

Rubyのメモリ使用量を削減する

Aaron Pattersonさんの記事です。


つっつきボイス: 「ちょうど以下のGC改善gemを見つけたんですが、1年前から動きがないのと、最近のRuby JIT周りの動きが早くて時の流れを感じてしまいました」

Ruby 3 JITの最新情報: 現状と今後(翻訳)

Rubyオブジェクトのアロケーションを追ってみた(Ruby Weeklyより)

Rubyのobjspaceライブラリを使っています。

# 同記事より
require 'objspace'

ObjectSpace.trace_object_allocations do
  obj = Object.new

  puts "File: #{ObjectSpace.allocation_sourcefile(obj)}"
  puts "Line: #{ObjectSpace.allocation_sourceline(obj)}"
end

# File: trace.rb
# Line: 4

つっつきボイス: 「こう書くとアロケーションがこう変わるみたいなのがわかりますね: Stringをfreezeするとこうなるとか」「レイヤは違うけど、ちょうど今日社内勉強会でやった「データマッパー」の話にも通じるものがある: lazyに書かないとこうなるよ、みたいな」

RubyRogueポッドキャスト「Rubyデバッガー」


devchat.tv/ruby-roguesより

ゲストのDaniel Azuma氏はGoogleでRubyとElixirのチームリーダーを務めているそうです。

awesome-awesomeness: まとめ情報のまとめ


つっつきボイス: 「まとめのまとめ」「草不可避」「awesomeなんちゃらという名前のまとめ情報って、GitHubで手っ取り早く★集めたい人が作りまくってますね」「とりあえずRubyの項はなかなかよさげでした」

fir: fishシェル風の対話的Ruby REPL


同記事より

SQL

MySQLをダウンタイム最小でPostgreSQLに移行する(Postgres Weeklyより)

⭐PostgreSQLの設定ファイルをGUIで生成するサービス(Postgres Weeklyより)⭐


pgconfigurator.cybertec.atより


つっつきボイス: 「よくあるやつかなと思ったけど、How would you describe your workload?↓があるのがいい: 結局どういうデータアクセスがあるかが重要なんで」


pgconfigurator.cybertec.atより

今週の⭐を進呈いたします。おめでとうございます。

pg_trgm: ワイルドカード検索を高速化する標準ツール(Postgres Weeklyより)

pg_trgm ignores non-word characters (non-alphanumerics) when extracting trigrams from a string. Each word is considered to have two spaces prefixed and one space suffixed when determining the set of trigrams contained in the string. For example, the set of trigrams in the string “cat” is “ c”, “ ca”, “cat”, and “at ”. The set of trigrams in the string “foo|bar” is “ f”, “ fo”, “foo”, “oo ”, “ b”, “ ba”, “bar”, and “ar ”.


つっつきボイス: 「全文検索とかで使うやつですね」「trigram: 三重文字」「PostgreSQLのこういうExtensionとかプラグインってもう無数にありますね: データベースの研究者がオープンソースであるPostgreSQLにたくさん集まって実装と検証に使ったのが大きいんじゃないかな」
VLDBっていう世界最大のデータベースカンファレンスがあるんですが、プロポーザルがすっごく分厚い」「2017年で第43回!」「Very Large!」「最近追えてないけど、当時はXMLデータベースが熱かった」

Herokuが「Postgres PGX」プランをリリース(Postgres Weeklyより)


blog.heroku.comより

JavaScript

ちょっと便利なスニペット

とても短い記事です。

// 同記事より
const originalObject = { a:1, b: 2, c: 3 };
const shallowObjectClone = {...originalObject};

つっつきボイス: 「記事は短いんですが、コメントやツイートで俺も俺もと盛り上がってます」「大喜利化しとるなー」

await (await fetch('https://api.github.com/users/wesbos')).json();

信頼できないJavaScriptをSaaSとして動かすには


つっつきボイス: 「レイヤで仕切ったりDockerでサンドボックス化したり、この通りにすれば大きな被害はないだろうけど、いったいどれだけ信頼されてないんだそのコードw」「書いた人(´・ω・)カワイソス」

Reduxを使っていいときいけないとき


blog.logrocket.comより


つっつきボイス: 「BPS アプリチームもRedux使ってた気がする」

FirebaseとAngularでAuth0認証する方法

Auth0はシングルサインオンのサービスのようです。

CSS/HTML/フロントエンド

平方マイルをみたいにmileの肩に2を付けて表すには


dev.to/ice_lenorより

formatDistanceでやれるそうです。


つっつきボイス: 「一応Unicodeを探してみましたが、平方マイルの文字はないですね」

WebSubがW3C仕様でRecommendationに

WebSub provides a common mechanism for communication between publishers of any kind of Web content and their subscribers, based on HTTP web hooks. Subscription requests are relayed through hubs, which validate and verify the request. Hubs then distribute new and updated content to subscribers when it becomes available. WebSub was previously known as PubSubHubbub.
w3.orgより

前はPubSubHubbubという名前だったんですね。


つっつきボイス: 「早口言葉すぐる」「しかも最後のbubが小文字とか」「インド人の話す英語みたいな」「名前変えてよかったね~」

Chrome Devtoolsで変更をリロード後も維持できる機能が追加


developers.google.comより


つっつきボイス:babaさんが『いたずらに使えそうw』って」「CSSはともかくJSでどうやってんのかな」

CSSのコメントの書き方ベストプラクティス(Frontend Weeklyより)


webdesign.tutsplus.comより


つっつきボイス: 「うん、CSSスタイルガイドとかこういうベストプラクティスがあるのはいい: 良記事」「お、これはBootstrapのファイル↓」


webdesign.tutsplus.comより

「ところで、BootstrapのCSSを最近読む機会があったんだけど、思ったよりずっとシンプルで読みやすいんですよ: もっと死ぬほどでかいかと思ってた」「へー」「しかもブラウザハック的なコードにはちゃんと解説が書いてあるのがエライ」

CrookedStyleSheets: CSSだけでトラッキングするテクニック集

// 同リポジトリより
@supports (-webkit-appearance:none) and (not (-ms-ime-align:auto)){
    #chrome_detect::after {
        content: url("track.php?action=browser_chrome");
    }
}

つっつきボイス: 「Googleに怒られないかなとふと思って」「まあ昔の携帯Webサイトなんか、こうやるしかなかったですからね」「はーん、vender-prefixで切り替えたりとか」「JS禁止の案件なんかで使えるかもしれないけど、まあお遊びというか芸ですね」

その他

Bashシェルスクリプトをデバッグする

# 同記事より
#!/bin/bash
_DEBUG="on"
function DEBUG()
{
 [ "$_DEBUG" == "on" ] &&  $@
}

DEBUG echo 'Reading files'
for i in *
do
  grep 'something' $i > /dev/null
  [ $? -eq 0 ] && echo "Found in $i file"
done
DEBUG set -x
a=2
b=3
c=$(( $a + $b ))
DEBUG set +x
echo "$a + $b = $c"

brook: Goで書かれたマルチプラットフォームのプロキシ

CLI版とGUI版があり、設定がほとんど不要だそうです。

Kubernetesを2500ノードにスケールアップ(WebOps Weeklyより)


blog.openai.comより

minikube: ローカルで動かせるKubernetes(GitHub Trendingより)


kubernetes/minikubeより


つっつきボイス: 「これは前からあるやつ: kubernetesは複数クラスタが前提なんで、これは設定確認用ですね」

村井純先生の講演

2018年2月19日を過ぎると消されるそうですので、それまでにどうぞ。


つっつきボイス: 「休みの日に聞いてたんですがめちゃめちゃ面白かった: いろいろキワドイことやってたんだなーと」「村井先生はネットの先駆者としていろいろやってきた人なので」(以下延々省略)「あと村井先生がとても美声でした」「大学の先生は話すのも仕事のうちなので声大事ですね」

番外

movfuscator: MOV命令だけを吐き出すCコンパイラ(GitHub Trendingより)


xoreaxeaxeax/movfuscatorより


つっつきボイス: 「よーやる」「MOVはCPUにもろ依存するからプラットフォーム限定だろうけど」

この表記知らなかった


つっつきボイス: 「お、KiとかMiとか普通に使いますよ」

手作り暗号ライブラリは…

インフルエンザワクチンの効果が30%しかなくてもワクチンを接種すべき理由

参考: なぜ30%しか効果がなくてもインフルエンザワクチンは打つべきなのか?

壁に隠れている部分を撮影できる次世代カメラ


つっつきボイス: 「昔ブレードランナーで、写真に写っていない物陰にVR的に回り込んで再生するシーンにびっくりしたのを思い出しました↓」「今やスマホのカメラで指紋取れますからね」

参考: 高画質を追求してきたカメラは今後「見えない物を撮る」方向へと進化していく

ドッグイヤーどころじゃなさそう


つっつきボイス: 「今どきのAI/機械学習は質のいいデータセットもないと進めようがないっすね」

はいです


つっつきボイス: 「ズキズキッ」「はいです頑張ります」「やーホントこのとおり: 早く寝れば早く起きられますよ」


今週は以上です。

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

週刊Railsウォッチ(20180119)derailed_benchmarks gem、PostgreSQLをGraphQL API化するPostGraphile、機械学習でモック画像をHTML化ほか

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

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

Rails公式ニュース

Ruby Weekly

Awesome Ruby

Random Ruby

RubyFlow

160928_1638_XvIP4h

Postgres Weekly

postgres_weekly_banner

Frontend Weekly

frontendweekly_banner_captured

Github Trending

160928_1701_Q9dJIU

デザインも頼めるシステム開発会社をお探しなら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探訪シリーズ