Tech Racho エンジニアの「?」を「!」に。
  • Ruby / Rails関連

週刊Railsウォッチ(20200218後編)rubyapi.orgで高速検索、RuboCopとJUnitFormatter、AWS Organizationsでの管理ほか

こんにちは、hachi8833です。いつの間にやらGoby言語の★が3,000になりました(ついでにバージョンちょっぴり上がりました)。V言語の作者のmedvednikovさんもを付けてくれていました😂。それだけですはい。

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

Ruby

rubyapi.org: Ruby APIドキュメントを高速検索(Hacklinesより)


rubyapi.orgより


つっつきボイス:「rubyapi.org?」「サイトを開くのが早いかも: いわゆるRubyメソッドとかを検索できるサイトですが、ドキュメントのサンプルコードをブラウザ画面で実行できる↓のが面白いなと思って(ただしExperimental)」「おぉなかなか有能😋」「実行はちょっと重いですがしょうがないかな」「過去バージョンについてもRuby 2.3まで切り替えられるみたいです」


rubyapi.orgより

「やはりというか、ブラウザ画面の実行は最後の行の結果しか出てこない😆」「まあここが違ってればドキュメント更新必要とかわかるでしょうけど☺️」

「前にウォッチにも貼った結城浩さんのツイート↓で『コピペで動くサンプルコードが欲しい』とあったのをちょっと思い出しました」「ああ、それで言うとRubyのHTTP周りのサンプルコードなんかは、使い方知ってる人じゃないとコピペしづらいつくりになってたような覚えがありますね☺️」

「ドキュメントって真面目に書くとどんどん行数増えてしまうんですよね😅」

「UIだけ見ると例のAlgoliaっぽいかなと思いました」

後でWebサイトのリポジトリを見た限りではAlgoliaではなくElasticsearchでやっているようです。

SorbetにFIXMEコメントなどというものはない(Hacklinesより)

Sorbetには、何らかのマジックコメントで特定の行のエラーを無視する方法はない。この点は私の知る他のどの段階的型チェッカー(TypeScript、Flow、Hack、MyPy)とも異なる。
自分がチームに参加した当初はどうかと思ったが、実務に使ってみるとこれが実にうまくいった。
同記事より抜粋・大意


つっつきボイス:「短い記事です」「SorbetにはFIXME的なコメントでアラートを黙らせる方法はないと😆」「使う人を選びそうな予感😆」

Sorbetで型付けされたどんなRubyプログラムも、必ずT.untypedと戦わなければならない。SorbetユーザーひとりひとりがT.untypedのしくみとそのトレードオフを熟知しなければならない。特にT.untypedは感染力が強い。T.untypedな変数がやってきたが最後、その変数へのメソッド呼び出しもことごとく型なしとなるであろう。
同記事より抜粋・大意

secure_headers gemに脆弱性


つっつきボイス:「脆弱性レベル10段階で4.3なので中くらいな感じ」「secure_headersってTwitterがやってるんですね 」「この辺は専門家じゃないと難しいな〜😅」

# #418より
def show
  user_input_domain1 = URI.parse "https://google.com;script-src"
  user_input_domain2 = URI.parse "https://*;.;"
  user_input_domains = [user_input_domain1, user_input_domain2]

  override_content_security_policy_directives(frame_ancestors: whitelisted_domains)
end

# 上で生成される以下のレスポンスヘッダは、ユーザーがframe-ansestorを設定すれば`script-src`を変更できるので、XSSの可能性がある
frame-ancestors: https://google.com;script-src *;

「直接関係ありませんが、今日のWebチームミーティングに出た『メモ化のやりすぎはバグの元』みたいな話を思い出しますね: コードを短く書こうとしすぎてバグとか脆弱性につながったりすることってありそう☺️」

html-template: 昔風のRubyテンプレートエンジン(RubyFlowより)

<!-- 同記事より: test.html.tmpl -->
<html>
<head><title>Test Template</title></head>
<body>
My Home Directory is <TMPL_VAR home>
<p>
My Path is set to <TMPL_VAR path>
</body>
</html>
# 同記事より
require 'html/template'

template = HtmlTemplate.new( filename: 'test.html.tmpl' )

puts template.render( home: ENV['HOME'],
                      path: ENV['PATH'] )

つっつきボイス:「1999年風のテンプレートエンジンって、そこまでしてレトロさを出したいのかと😆」「😆」「<TMPL_VAR home>みたいに書くテンプレート言語って、ないわけじゃないけど割と珍しい気がしますね🤔」

「この記法、大文字じゃないけどXSLTにちょっと似てるかも🤣」「XSLTってありましたね🤣」「ほんのちょっぴり書いた😆」「どうしてもXSLTを書かないといけなくなったときにXSD(XML Schema Definition)勉強しましたけど、二度と書きたくない😆」「😆」「ちなみにXSDはXMLのデータ形式をバリデーションするのに使います: XMLがこれにパスしないとvalidかどうか信じられなくて脳が死にそうになる😆」

<!-- https://www.w3schools.com/xml/xsl_intro.asp より -->
<?xml version="1.0"?>

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
  <html>
  <body>
    <h2>My CD Collection</h2>
    <table border="1">
      <tr bgcolor="#9acd32">
        <th>Title</th>
        <th>Artist</th>
      </tr>
      <xsl:for-each select="catalog/cd">
        <tr>
          <td><xsl:value-of select="title"/></td>
          <td><xsl:value-of select="artist"/></td>
        </tr>
      </xsl:for-each>
    </table>
  </body>
  </html>
</xsl:template>

</xsl:stylesheet>

参考: XSLT: 拡張可能なスタイルシートの言語変換 | MDN
参考: XML Schema Tutorial

「自分としてはなつかしのJSP(JavaServer Pages)にオールドスタイル感じる🤣: 中かっこ{}が出てきたり」「当時はJSPに邪悪さしか感じなかった🤣」「Javaをスクリプト言語っぽく使ってみましたというか😆」

参考: JavaServer Pages - Wikipedia

<!-- http://www.wakhok.ac.jp/~tomoharu/db2003/text/db_c2.html より -->
   <%
     String name = null;
     if (request.getParameter("name") == null) {
   %>
         <p>not found!</p>
   <%
     } else {
         foo.setName(request.getParameter("name"));
     }
   %>

「ついでに以下↓も貼りました」「2020年度のRuby HTTPクライアントの最高峰とは😆」

「自分はやっぱりHTTPClient↓が好きかな〜❤️(ウォッチ20180615)」「この記事にHTTPClientないけど、まあお好きなものをどうぞ☺️」


目次より

  • net/http(Rubyビルトイン)
  • Faraday
  • http.rb
  • rest-client
  • httparty
  • excon
  • Typhoeus
  • Curb
  • 目的に合ったクライアントを使おう

RuboCopとJUnitFormatter


つっつきボイス:「RuboCopにJUnitFormatterというものが入ったらしいんですけど、これ何でしたっけ?」「JUnitは昔からあるJavaのテストスイートですけど、へ〜RuboCopでJUnit使う人がいるとは!」「なぜだろう😆」

参考: JUnit - Wikipedia

JUnitとはJavaで開発されたプログラムにおいてユニットテスト(単体テスト)の自動化を行うためのフレームワークである。
Wikipediaより

# 同PRより
$ rubocop --format junit
<?xml version='1.0'?>
<testsuites>
  <testsuite name='rubocop'>
    <testcase classname='example' name='Style/FrozenStringLiteralComment'>
      <failure type='Style/FrozenStringLiteralComment' message='Style/FrozenStringLiteralComment: Missing frozen string literal comment.'>
        /tmp/src/example.rb:1:1
      </failure>
    </testcase>
    <testcase classname='example' name='Naming/MethodName'>
      <failure type='Naming/MethodName' message='Naming/MethodName: Use snake_case for method names.'>
        /tmp/src/example.rb:1:5
      </failure>
    </testcase>
    <testcase classname='example' name='Lint/DeprecatedClassMethods'>
      <failure type='Lint/DeprecatedClassMethods' message='Lint/DeprecatedClassMethods: `File.exists?` is deprecated in favor of `File.exist?`.'>
        /tmp/src/example.rb:2:8
      </failure>
    </testcase>
  </testsuite>
</testsuites>

JUnit Style Formatter
Machine-parsable
junitスタイルフォーマッタはJUnitフォーマットでの出力を提供する。
このフォーマッタはrubocop-junit-formatter gemを元にしている。
同PRより

「あ、HTMLとかJSONを出すようにJUnit形式でも出力したいってことか!😳: この記事↓でやっているように、JenkinsみたいなCIにはJUnit形式でも渡せるので、CIにJUnit形式のXMLで渡すといい感じに整形してくれたりするんでしょうね☺️」

参考: rubocop-junit_formatterを導入した | r7kamura on Patreon

「そんな機能があるんですか?」「ありますあります、XML系だとJUnitがこの手の形式の先駆けだったので」「Javaの話ではなかった😆」「記事ではCircle CIでもJUnit形式がサポートされてるってありますね」「JUnit、Javaのアサーション系のテストでは普通に使ってた☺️」

「ところでrubocop-junit_formatterとrubocop-junit-formatter、名前のアンスコとハイフンが1箇所違うだけ😆」「つらい名前😆」「メンテされてるのは前者、と」

Noah Gibbsさん退職エントリと書籍


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

つっつきボイス:「RubyKaigiやTechRachoの翻訳記事↑などでおなじみのNoah GibbsさんがAppFolioを退社してスコットランドに移住するという退職記事を読んでたら、『Rebuilding Rails』という本を出してたことを知りました😳」「お、自分でRailsを組み立てて学ぼう的な本ですね😋」

ご注意: 後でサンプルをよく見てみると、『Rebuilding Rails』は使われているRubyが2.0と相当古かった...😅。ご購入の前にご確認を。


『Rebuilding Rails』サンプルPDFより

なお同書のサンプルアプリは以下に公開されています。

書籍『Mastering Software Technique』

Noah Gibbsさんの新しい本(執筆中)は、以下の『Mastering Software Technique』です。フォームで申し込むとサンプルPDFをダウンロードできます。


software-technique.comより

以下は昨年RubyKaigiでのNoah Gibbsさんです。同書はこのスピーチの内容の延長線にあるようです。

その他Ruby


つっつきボイス:「数学範囲広すぎと思ったら、数式のパーサーでした☺️」「構文解析怖くない😆」「まあ実際そのとおりで、言語の動きがわからなくなったらAST(抽象構文木)を見るのが一番確実ですし☺️」

参考: 抽象構文木 - Wikipedia

DB

PostgreSQLのwork_mem設定のコツ(Postgres Weeklyより)


つっつきボイス:「PostgreSQLのwork_mem設定で単位を指定しないとキロバイト単位になるそうです」「割とよくあるヤツ: ddコマンドとかも単位を付けないとえらく小さい単位になりますし🤣」「スワップ領域が超可愛らしいサイズに🐥」

参考: dd (UNIX) - Wikipedia

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

マルチアカウントのAWS Organizationsでユーザーとロールを管理する


つっつきボイス:「マルチアカウントのユーザーをどう管理するか問題、SSOもその手段のひとつ、と」「この記事だとSAMLの方がいい感じにできそうな気もするけど🤔」

参考: Security Assertion Markup Language - Wikipedia


同記事より

「記事の人はSSO(シングルサインオン)で管理するより上みたいにやるのが好みだそうです」「Assume RoleでOrganizationsを管理するヤツですね」「Assume Role?」「特定のユーザーに一時的にポリシーを付与するようなことができます」「おぉ」

参考: Assume Roleの用途・メリット - Carpe Diem

「AWS Organizationsの管理は、何がベストかが場合によって違ってくるので結構悩ましいんですよね😅」「うーむ」「やりたいことが案件ごとに非常に多岐に渡っていていろいろ難しいですし」

「Organizationsは、Organizationsアカウントを分けておけば請求額を明示的に分けられるのは利点ですね😋」「請求を後から分けるのは難しいんでしょうか?」「構造上アカウントが分かれてないと分離は無理😇」

「AWS Organizationsはmasterとその下の2階層でやっている分には比較的わかりやすいので自分は割と好きですね🥰」「あとAWS Organizationsだと子アカウントを作るときに認証を要求されないのがかなり便利😋: 普通のAWSアカウントを新しく作ろうとするとクレカ登録とか電話認証とかホントめんどくさい」「なるほど」

「Organizationsだと、後でサービスを子アカウントごとmasterから切り離して譲渡できるのもありがたい😂(認証は必要ですが)」「おぉ?」「AWSで最も面倒な作業のひとつは"AWSアカウントの移行"なんですよ: 動いているEC2インスタンスを全部AMI化してAMI共有したりとかS3バケットもコピーしたりとかマジ地獄☠️」「むむむ」「なのでこうやって後で切り離せるようにしておくのは、特にBPSのような受託開発では重要ですね☺️」

「とにかくAWSのアカウント管理は何がベストプラクティスかは一概に言えなくて、案件に応じて考えるしかないんですけど、ひとつ重要なのは変に統合しないことでしょうね🧐: 統合されたものを後から切り離すのはとても大変なので、切り離す可能性のあるところで分けておくのは必須に近い」「なるほど!」

その他インフラ

うれしくて貼っちゃいました😂。

JavaScript

知らない間に強くなってたJSを急いでキャッチアップした


つっつきボイス:「JSをずっと触ってなかった人が久しぶりにやってみてわかったことをメモした感じの記事です」「さすがにprototype.js触ってる人はほとんどいないでしょうけど、jQueryは今でも触ってる人いますし☺️」「letで驚いている😆」「コメントにも『「ES5の機能で感激するとはどんだけ長い間JS触ってなかったのか』という書き込みがありました😆」「まあオライリーのゾウさんJS本にもこの辺のことあんまり書いてませんし☺️」「他のコメント欄も『オレもこれ知らなかった』みたいな声が続々寄せられてました」「JSをセカンダリ言語でやってる人たちにしてみれば知らない機能ありますよね☺️」


はみだし:「記事の末尾にきゃわいいイーブイの絵🐰」「ヤバい、ポケモンわからない😅」「自分も世代ズレてます😅」「自分は初代から😋」

参考: イーブイ|ポケモン図鑑ソードシールド|ポケモン徹底攻略

CSS/HTML/フロントエンド/テスト

忙しい人のためのdraw.io


つっつきボイス:「BPS社内Slackで評判の記事でしたね」「これ割と有用😋」「draw.ioでプレースホルダ使えるのも知らなかった」「PlantUML↓使えるのも初めて知った」

参考: PlantUML: シンプルなテキストファイルで UML が書ける、オープンソースのツール

「む、見た感じdraw.ioのPlantUMLで書いた結果はひとつのオブジェクトになるっぽい?」「バラせないのかな...」「PlantUMLの図を出力してさらに細かくいじれたらいいんだけど、惜しいな〜😢」

言語・ツール

PEG: あいまいさのない分析的形式文法


つっつきボイス:「最近ちょっとPEG(Parsing Expression Grammar)という形式で言語を記述してパーサーを生成して遊んでるんですけど、昔ながらのyacc/lexやEBNFよりイケてるようです」「人間が読むかコンピュータに読ませるかで変わってきますね☺️」「PEGはEBNFや正規表現より厳密に書けるらしくて、自然言語の記述には固すぎて向いてない代わりにパーサーを記述するのに向いてるみたいでした😋」

// mna/pigeonより: PEGのGo方言
{
package main

func toIfaceSlice(v interface{}) []interface{} {
    if v == nil {
        return nil
    }
    return v.([]interface{})
}

}

Input       ← #{ c.state["Indentation"] = 0; return nil } s:Statements  r:ReturnOp EOF 
                                            { return newProgramNode(s.(StatementsNode),r.(ReturnNode)) }
Statements  ← s:Line+                       { return newStatementsNode(s)}
Line        ← INDENTATION s:Statement       { return s,nil }
ReturnOp    ← "return" _ arg:Identifier EOL { return newReturnNode(arg.(IdentifierNode))}

Statement   ← s:Assignment EOL              { return s.(AssignmentNode),nil }
    / "if" _ arg:LogicalExpression _? ":" EOL INDENT s:Statements DEDENT 
                                            { return newIfNode(arg.(LogicalExpressionNode),s.(StatementsNode)) }


Assignment ← lvalue:Identifier _? "=" _? rvalue:AdditiveExpression
                                            { return newAssignmentNode(lvalue.(IdentifierNode),rvalue.(AdditiveExpressionNode)) }

LogicalExpression   ← arg:PrimaryExpression { return newLogicalExpressionNode(arg.(PrimaryExpressionNode)) }
AdditiveExpression  ← arg:PrimaryExpression rest:( _ AddOp _ PrimaryExpression )* 
                                            { return newAdditiveExpressionNode(arg.(PrimaryExpressionNode),rest)}
PrimaryExpression   ← arg:(Integer / Identifier) 
                                            { return newPrimaryExpressionNode(arg) }

Integer ← [0-9]+                            { return newIntegerNode(string(c.text)) }
Identifier ← [a-zA-Z] [a-zA-Z0-9]*          { return newIdentifierNode(string(c.text)) }

AddOp ← ( '+' / '-' )                       { return string(c.text),nil }

_ ← [ \t]+

EOL ← _? Comment? ("\r\n" / "\n\r" / "\r" / "\n" / EOF)

Comment ← "//" [^\r\n]*

EOF ← !.

INDENTATION ← spaces:" "* &{ return len(toIfaceSlice(spaces)) == c.state["Indentation"].(int), nil }

INDENT ← #{ c.state["Indentation"] = c.state["Indentation"].(int) + 4; return nil }

DEDENT ← #{ c.state["Indentation"] = c.state["Indentation"].(int) - 4; return nil }

参考: プログラミング言語を作る/yaccとlex

「Pythonから引退したGuido van Rossumさんも最近PEGで遊んでるようです」「後はこういうのをどこで使う機会があるかかな😆」

その他言語


つっつきボイス:「このブログを久しぶりに見かけたんですけど、今回はSSHキー生成の中身をyoshiさんの乱数記事↓的に追いかけていました」「ちょうど最近これに近いことやったな〜: OpenSSLコマンドで作られたX.509証明書の署名がちゃんとしてるかどうかを目で見て追いかけるという作業😆」「ひぇ〜😅」(以下マルチドメイン証明書などについて延々)

乱数について本気出して考えてみる

その他

お世話になりたい


つっつきボイス:「次と合わせて医療ネタが連続しちゃいましたが😅、タイに根管治療を専門にする歯科医がいるって初めて知りました」「私これ読んでタイに行こうかと真剣に考えました😆」「入れ歯製作なんかは未だに高度な職人芸が必要らしくて、3Dプリンタではまだうまくやれないらしいですね☺️、その他のところでは機材がどれだけ最新かで決まる部分も大きいみたいですけど」

番外

思い出すのはブラックジャック10巻


つっつきボイス:「歯科のドリルとか、それこそブレのないロボットが向いてそう🤔」「日本だと免許とか資格とかクリアしないといけないものがいっぱいありますし😆」

参考: "手術お助けロボット"による超マイクロ手術が初めての臨床実験に成功 | ナゾロジー


後編は以上です。

バックナンバー(2020年度第1四半期)

週刊Railsウォッチ(20200217前編)Railsのオプション引数退治、HSTSのデフォルトmax-ageが1年から2年に変更、semantic_logger gemほか

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

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

Awesome Ruby

RubyFlow

160928_1638_XvIP4h

Hacklines

Hacklines

Postgres Weekly

postgres_weekly_banner


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。