週刊Railsウォッチ(20191112後編)invisible gemで可視性を変えずにパッチ当て、スライド:「型なし言語のための型」、自然言語の言語名を推測ほか

こんにちは、hachi8833です。DHHがAppleクレカの件でTVに出てたようです。

  • 各記事冒頭には⚓でパーマリンクを置いてあります: 社内やTwitterでの議論などにどうぞ
  • 「つっつきボイス」はRailsウォッチ公開前ドラフトを(鍋のように)社内有志でつっついたときの会話の再構成です👄
  • 毎月第一木曜日に「公開つっつき会」を開催しています: お気軽にご応募ください

お知らせ: 週刊Railsウォッチ「第16回公開つっつき会」(無料)

第16回目公開つっつき会は、今週11月14日(木)19:30〜にBPS会議スペースにて開催されます。今回は月初ではありませんのでご注意ください。

週刊Railsウォッチの記事にいち早く触れられるチャンス!発言・質問も自由です。引き続き皆さまのお気軽なご参加をお待ちしております🙇。

Ruby

invisible: privateやprotectedを変えずにモンキーパッチ(Ruby Weeklyより)

# 同記事より
module WithFoo
  extend Invisible

  def public_method
    super + ' with foo'
  end

  def protected_method
    super + ' with foo'
  end

  def private_method
    super + ' with foo'
  end
end
class MyClass < Base
  include WithFoo
end

instance = MyClass.new

MyClass.public_method_defined?(:public_method)       #=> true
instance.public_method                               #=> 'public with foo'

MyClass.protected_method_defined?(:protected_method) #=> true
instance.protected_method                            # raises NoMethodError
instance.send(:protected_method)                     #=> 'protected with foo'

MyClass.private_method_defined?(:private_method)     #=> true
instance.private_method                              # raises NoMethodError
instance.send(:private_method)                       #=> 'private with foo'

「RubyのRubyのModule Builderパターン」記事↓のshioyamaさんの作ったgemです。

RubyのModule Builderパターン #1 モジュールはどのように使われてきたか(翻訳)


つっつきボイス:「publicだろうとprotectedだろうとprivateだろうとモンキーパッチを当てたいようです」「ほぇ〜😆」

「そもそもprivateメソッドってパッチ当てられるんでしたっけ?」「たしかできるはず🤔: 普通にクラスをオープンすれば上書きされるはずですし」「README見ると、privateメソッドに普通にパッチを当てるとpublicになっちゃうみたいですね」「あ〜!そうかも!😳: そのとおり、publicメソッドでオーバーライドしたことになります」「そういうことでしたか😅」

後でRuby 2.6.5で試してみたところ、確かにvisibilityなしでパッチを当てるとpublicに変わりますね。Bazでprivateを指定するか、invisible gemをインストールしてBazモジュールでextend Invisibleすると変わらなくなりました。

class Foo
  private
  def foo
    99
  end
end

class Bar < Foo
end

Bar.public_method_defined?(:foo)  #=> false(fooはpublicではない)
Bar.private_method_defined?(:foo) #=> true(fooはprivate)

module Baz
  def foo
    88
  end
end

class Bez < Foo
  include Baz
end

Bez.public_method_defined?(:foo)  #=> true(fooがpublicに変わった)
Bez.private_method_defined?(:foo) #=> false(fooはprivateではなくなった)

「メソッドのvisibilityを変えずにパッチを当てられるgemなんですね😳」「元のincludeするモジュールのvisibilityに合わせてパッチを当てると言ってますね☺️」「しかもsuper使ってても大丈夫となってるし」

「本当ならパッチを当てる側のモジュールにもpublicとかprivateとか書かないといけないんでしょうけど、メソッドがいくつもあってそれぞれvisibilityが違ってたらモジュールにいちいちvisibility書いてられないみたいなことになりそう😇」「invisible gemを入れると元のvisibilityをチェックしてくれてそれを変えないようにパッチを当てられるのか〜」「まあサンプルコードのdef public_methodみたいな名前は個人的にはメタ過ぎてどうかと思いますけど😆」

「もしかしてキワモノかと思ったら結構いいgem!?」「まあキワモノかも😆」「でもこれは面白い!👍」「用途としては、パッチでvisibilityをいちいち書きたくないのでおサボりしたいとか、visibilityが異なるメソッドにまとめてパッチを当てたいときとかですかね〜☺️」

「このgemはどういう仕組みでやってるんだろう?🤔」「Module#includedあたりで頑張ってるのかな?😆」「ソース↓見ると意外に短いですね😳」「たぶんいったんpublicになったメソッドをまたprivateやprotectedに引き戻してるんじゃないかな〜と予想(ソース読んでないけど😆)」「何となく禁断の地に手を入れてるような気が😅」「わかる😆」「むしろRubyの言語仕様上できるのがビックリ」「Rubyの仕様深い😅」

# https://github.com/shioyama/invisible/blob/master/lib/invisible.rbより
module Invisible
  def append_features(base)
    private_methods, protected_methods = methods_to_hide(base)

    super

    base.send(:private, *private_methods)
    base.send(:protected, *protected_methods)
  end

  def prepend_features(base)
    private_methods, protected_methods = methods_to_hide(base)
    return super if private_methods.empty? && protected_methods.empty?

    mod = dup

    if name
      return if base.const_defined?(mod_name = ['Invisible', *name.split('::')].join('__'))
      base.const_set(mod_name, mod)
    end

    mod.send(:private, *private_methods)
    mod.send(:protected, *protected_methods)
    base.prepend mod
  end

  private

  def methods_to_hide(mod)
    [(instance_methods - private_instance_methods)   & mod.private_instance_methods,
     (instance_methods - protected_instance_methods) & mod.protected_instance_methods]
  end
end

append_featuresprepend_featuresにパッチを当ててるんですね😳。

参考: instance method Module#append_features (Ruby 2.6.0)
参考: instance method Module#prepend_features (Ruby 2.6.0)

スライド: 型なし言語のための型

社内Slackで教えてもらいました🙇。


つっつきボイス:「富山Ruby会議でsoutaroさんが発表したスライドです」


toyamarb.github.ioより

富山はブリしゃぶが最高だそうです🐟。

「これまでも情報は出てましたが、以下の相関図↓がまとまっててうれしいです😂: Level 1型チェッカーが必須で、Level 2型チェッカーは好みで選んでいいという位置づけ」「はぁ〜なるほど!」「RubyKaigiでもSorbetとかいろいろ出てきてよ〜わからんかったけど😆こうやって整理されるとありがたい🙏」「選べるのがいい👍」

「Rubyの型チェックはまだまだ難しい点があるようです」「Rubyはいろいろ自由ですし😆」「Array#mapはML型推論が効かないのか😳」

「TypeScriptはうまくやってるな〜コイツめっ😆」

「『型を書きたくない人はTS使わないから観測できない』、まさしく〜😆」「後でじっくり読み返そう😋」

HTTPX: Ruby HTTPライブラリのニューフェース(Ruby Weeklyより)

主な機能:

  • HTTP/2とHTTP/1.xをサポート
  • デフォルトでコンカレントリクエストやれる
  • シンプルかつチェイン可能なAPI
  • プロキシ(HTTP(S)、Socks4/4a/5)
  • シンプルなタイムアウト
  • 軽量(機能を明示的に読み込む)
  • 圧縮(gzip、deflate、brotil)
  • 認証(BASIC、Digest)
  • Cookie
  • HTTP/2 サーバープッシュ
  • H2Cアップグレード
  • リダイレクト

参考: HTTP/2? h2? h2c? って何? - 隙あらば寝る

# 同リポジトリより
response = HTTPX.get("https://nghttp2.org")
puts response.status #=> 200
body = response.body
puts body #=> #<HTTPX::Response .

RubyをRubyで書きたい

つっつきボイス:「Ruby言語をRubyで書こうみたいな動きを最近ちらほら見かけるので」「Cで書かれたものを減らしてRubyで書く、わかる〜😋」「Cを滅ぼしたい気持ちも😆」「Rubyで書き直すのはわかるんですけど、パフォーマンス的にどうなんでしょう?」「それが場合によってはRubyで書いた方がCより速いケースもあるらしいと何かで見かけました😳」

どこで見たのかなと思ったらQuoraでした↓。

「Cで書かれたRubyのコアはできたから今後はRubyでRubyを記述しよう、みたいな感じにはなかなかならないんじゃないかなと思ってた😆」「自分は逆に、言語ができたらその言語で記述し直して置き換えるのって言語づくりで割と早い段階でやる印象ありますけどね」「そうなの?😳言語作ったことないからわからないけど😆」「むしろRubyはまだCで書かれてる部分多いのかって思いましたし☺️」「そういえばGo言語のコンパイラも最初Cで書かれていたのが、ある時期からへその緒が切れてGo自身でコンパイラが書かれるようになりましたね(セルフホスティング)」

「ツイートの続き↑を見ると、今は一部でCのコードをRubyで生成してるんですね」「それはOKなのか😆」「人間様はC書かなくてよろしい😆」


つっつきの後で、RubyでCを書く機能がひっそり入ってらしいことを知りました。

その他Ruby


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

「Kubernetes Patterns」が無料で読める


つっつきボイス:「登録すれば無料で読めると😆」「今手が回らないので後でダウンロードしてみます」「どんなパターンがあるのかだけでもさらっと見れたらいいですね😋」「図があったらうれしい」「パターン本ってクラス図を見るだけでだいたいわかるものとそうでもないものとありますけど、だいたいクラス図でわかりますよね☺️」

ダウンロードしました😋。


同PDFより

スライド: AWSのセキュリティ対策全部盛り


つっつきボイス:「ブクマ1000超えてました」「全部盛りなだけあって内容を追うのは時間かかりそう」「セキュリティの解説は本気でやると全部盛りになるのは仕方なさそうですね: 用途ごとにどこを押さえるかをひととおり網羅しないといけませんし☺️」「用途を絞り込めないあたりはフレームワークの解説にも通じるものがあるかも🤔」

「スライドでもお馴染み徳丸本が紹介されてますね↓」「新しい版はmorimorihogeさんいわく『9mm弾ぐらいなら止められそう』なぐらいの分厚さ😆」「物理で防御😆」「やっぱり分厚くなる😆」

「セキュリティはコストとのバランスも重要って昔教わりました」「鍵閉め忘れみたいな大ポカは論外だとしてもまあそうなりますよね☺️」「何を守るかと、セキュリティにいくら投資するかで変わってきますし💰」「上を見たらきりがない」「どんなにセキュリティを高めても米軍に襲いかかられたらアウトでしょうし😇」「セキュリティの後出しジャンケンよくありますし😆『ほれ見たことか』『言わんこっちゃない』とか」「😆」

「ソーシャルエンジニアリングとかショルダーハッキングみたいな『まさかそんな手が?!』みたいな手法もあることを知っておくのは大事ですね〜☺️」「ですね〜」

参考: ソーシャル・エンジニアリング - Wikipedia
参考: ショルダーハックとは - @IT

「某同人誌で読んだんですが、セキュリティ調査のためにハニーポットを仕掛けたところ、さっそく侵入者がやってきてしめしめ釣れたと思ったら、調査場所のWiFiアクセスポイントから位置情報を抜かれそうになって『やばいっ!』て慌ててケーブル引っこ抜いたという話があったそうです💀」「こえぇ😱」「シビレる😇」

参考: ハニーポット - Wikipedia

その他インフラ


nic.ad.jpより


つっつきボイス:「名前はそっけない感じですが、さすがJPNICで『最新データセンターネットワーク・プロトコル動向』とか『サイバーセキュリティ新常識2020』のようなエッジなトピックが盛りだくさんのようです」「『Wi-Fi 今昔物語』😆」「『超高速超低遅延ネットワーク最新動向』強そう💪」「さすがに参加費はお安くなかった💰」「学割なら90%オフだそうです🎓」

JavaScript

IntelliCodeがさらに(Publickeyより)


つっつきボイス:「オンライン機能はあってもおかしくない感じですけど、前にも扱った(ウォッチ20180511)IntelliCodeのAIレビューがますますアグレッシブにやってるっぽいですね」「行単位でサジェスチョン😳」「ちょっと試してみたい気が😋」「私もSublimeからVSCodeに移行を企んでます😆」「Matzもこういうのが欲しいって言ってましたね」「元データは結局GitHubのトップ3000リポジトリのソースのようです」「ということはプログラミングに不慣れな人にはあんまり効果ないかも?😆」

「あと20年もしたらコードレビューが今より楽になったりするでしょうか?🤔」「たぶんならない😆」「設計やネーミングまでは手が回らなさそう😆」「やっぱりネーミングが一番難しいですよ😭」「よく名前で内部の振る舞いを表すなとか言われますけど、いい名前だったら内部の振る舞い使ったって構わないわけですし😤」

その他JS

// 同記事より
import React from 'react'
import ReactDOM from 'react-dom'
import App from './app'
const rootEl = document.getElementById('root')
// ReactDOM.render(<App />, rootEl)
const root = ReactDOM.createRoot(rootEl)
root.render(<App />)

つっつきボイス:「Reactが数年をかけてexperimentalでコンカレントモードが入ったそうです」「またエグいものが😆」「コンカレントやりたいんだろうなきっと🤔」「非同期やれるならコンカレントもやりたいとか😆」「非同期でいい思い出ないし😭」「非同期をちゃんと設計するには違う脳が必要🧠」「ぼくたちは手続き脳から脱却できないのかも😅」「自分もやってませんけど、たぶん理論をがっつり勉強しないとだめなんですよきっと😅」「オブジェクト脳とも違うんですよね?」「まったく別😤」「別」

コンカレントモードのissueも賑わってますね。

言語・ツール

Git 2.23に新コマンド


つっつきボイス:「社内Slackで話題になってたヤツで、ちょっとだけタイプ量減りそう」「gitはGUIでやってますが😆」「結局従来の使い方になりそうな予感😅」

# 同記事より
git checkout -b hogehoge # 従来
git switch -c hogehoge   # 2.23から

git checkout .          # 従来
git restore .           # 2.23から

「CentOSとかだとサービスの管理にsystemctlを使いますけど、私は未だにそれをガン無視してserviceコマンド使ってますし😆」「自分なんか/etc/init.dあたりのスクリプトを叩いたりしますし🤣」「macOSはまたコマンド違いますし」

参考: serviceコマンドとsystemctlコマンドを調べてみた – koyama’s blog
参考: コマンド/launchctl - MacWiki

Linuxのサービス起動周りとDockerとの関連を理解する#1(社内勉強会)

guesslanguage: 自然言語が何語かを推測

Go言語でやってますが、元はPythonだそうです。

// 同リポジトリより models/ro.go
package models

func init() {
    models["ro"] = map[string]int{
        " de": 0,
        " în": 1,
        "de ": 2,
        " a ": 3,
        "ul ": 4,
        " co": 5,
        "în ": 6,
        "re ": 7,
        "e d": 8,
// 略

つっつきボイス:「個人的な興味なんですが、自然言語を対象に何語の文章かを推測するツールです」「リポジトリは5年前の😆」「日本語はない?」「ないか〜」「ひらがなを検出したら100%日本語だから要らないのかも😆」「東京特許許可局みたいに漢字だけだったら中国語と区別するのは難しいかな?😆」「こういうツールを欲しい人は確実にいるんですけど少なくて😢」

「これは基本的にアルファベット語の言語判定用?」「だと思います: キリル文字というだけだとロシア語なのかウクライナ語なのかブルガリア語なのかまではわからないので、その言語に多い文字列を検出してポイントを積んでいく感じで」「へぇ〜」「昔の職場でこれと似たようなツールをperlでこっそり作ったことあったんですけど、そのときにフランス語とルーマニア語がとてもよく似ていて判別が難しいとか、アラビア語とペルシャ語を判定するとかいろいろやってました😆」「😆」「そのときに、アラビア語とペルシャ語の外見的な違いは冠詞のアル(ال)が多めなのがアラビア語で少ないのがペルシャ語だと教わりました」「知らんわ😆」

参考: キリル文字 - Wikipedia
参考: アラビア文字 - Wikipedia

「こういう研究してた人が身近にいましたけど、ポイントを積んで『xx語である確率何%』みたいに判定するのは言語解析で割と一般的なようですね☺️」「やはりそうでしたか😳」「名前は忘れましたけど手法があって、昔世界中の言語の文字列をかき集めて集計するお手伝いしてました」「そんな楽しいことやってたんですね😋」「そのときもいろいろあってですねゴニョゴニョ(略)」

数式表現がISO規格になってた


Wikipediaより


つっつきボイス:「Kindle無料本のアマゾンレビューを読んでたら数式表現のISO規格があることをたまたま知りました」「キリ番ゲットで縁起がいい😆」「『記号 ÷ は使うべきではない』とは😆」「なぜか数理論理学の記号が最初😆」「三角関数やら写像やらベクトルやらオイラー定数やらあれもこれも😋(以下延々)」

その他

classitisとdivitis


つっつきボイス:「先週のウォッチを制作中にclassitisとdivitisという見慣れないWeb関連用語を見かけたんですが、-tisは肝炎(hepatitis)とか膵臓炎(pancreatitis)みたいな『〜炎』を表す接尾語らしくて、それに引っ掛けた新しい造語のようです」「病名というか医学用語☺️」

「意味は基本的にネガティブで、classitisはCSSで無駄なクラスをいっぱい作ること」「無駄なクラスなんかYAGNIにしかなりませんし😆」「divitsはHTMLの意味のあるタグじゃなくて何でも<div>タグでやってしまうことだそうです」「どっちも悪い意味だった😆」

来年2/29と3/1


techbookfest.orgより


つっつきボイス:「今度こそ技術書典行きたいです😭」「今度は何買おうかな😋」

番外

ガラスに刻む


つっつきボイス:「煮ても焼いても喪失しないといっても金槌で叩いたら割れるのでは🔨」「せっかくなのでこのぐらいタフなガラス↓に封入したらいいかなと思って😆」

「ガラス破れたら中の札束持ち帰り放題🤣」「誰も成功しなかったみたいです😊」「飛び蹴りは効かないと😆」「ドリルとかポンチで一点突破する方が見込みあるかも🗼」「そこに液体窒素をかけるとか」「銃は社会的にダメか😆」


後編は以上です。公開つっつき会でお会いしましょう!

おたより発掘

バックナンバー(2019年度第4四半期)

週刊Railsウォッチ(20191111前編)Active Recordモデルをprivateで封じ込める、心折れないRailsスキーマ管理、Railsセッションをクロスドメイン共有ほか

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

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

Ruby Weekly

Publickey

publickey_banner_captured

React Status

react_status_banner

デザインも頼めるシステム開発会社をお探しならBPS株式会社までどうぞ 開発エンジニア積極採用中です! Ruby on Rails の開発なら実績豊富なBPS

この記事の著者

hachi8833

Twitter: @hachi8833、GitHub: @hachi8833 コボラー、ITコンサル、ローカライズ業界、Rails開発を経てTechRachoの編集・記事作成を担当。 これまでにRuby on Rails チュートリアル第2版の監修および半分程度を翻訳、Railsガイドの初期翻訳ではほぼすべてを翻訳。その後も折に触れて更新翻訳中。 かと思うと、正規表現の粋を尽くした日本語エラーチェックサービス enno.jpを運営。 実は最近Go言語が好きで、Goで書かれたRubyライクなGoby言語のメンテナーでもある。 仕事に関係ないすっとこブログ「あけてくれ」は2000年頃から多少の中断をはさんで継続、現在はnote.muに移転。

hachi8833の書いた記事

BPSアドベントカレンダー

週刊Railsウォッチ