投稿者「sasaki」のアーカイブ

4年目プログラマが参考にしたQiita記事まとめ⑱

概要

特にカテゴリもレベルも偏らずにざっくばらんに、参考になったQiita記事を一言添えて列挙するシリーズ18本目。

今回からタイトルを「4年目」に致しますが、ナンバリングは継続とします。

Qiitaまとめシリーズ

機械学習案件を料理に例えると分かりやすい件

機械学習と料理って同じなのか!?

依然、記事の内容に例えて言うなら、「肉っぽい何かと赤みのある野菜とよくわからない粉とか使って、いい感じのビーフシチュー的な料理を作って」という東郷平八郎でも躊躇うような注文状態に対して肉じゃがを提供できたら大満足ぐらいな状態になった。

と言っても、自分含めてノウハウがまとまってない環境なので誰が悪いというわけでなく、試行錯誤して頑張って、後は煮るなり焼くなりどうにか「料理」と呼べるほぼ物体Xが出来たのでファーストステップとしてはありだと思ったけど。

僕とVimの1年間

一年で成長しすぎじゃないですかね‥‥。もう三年ぐらいvimしか使ってない(xcodeは除く)のに、未だにIDE的な使い方はできてなくてシンプルなvimでチマチマ作業してる。もっと根本的な解決図りたいけど、いざvimをそこまで拡張すると、「vimであり必要
なくね?」となりそう。

デザイナーとアプリエンジニアが仲良く開発できるためのチートシートを作る

記事はネイティブの話だけど、ネイティブに限らず、「開発用語を統一する」というのは大事。理想はちゃんとwikiなりに辞書をまとめて、定義されたワード以外の曖昧な言い回しとかは一切禁止にしたほうが余計な誤解とか招かずに済むはず。あとからプロジェクトに参入した人がログやソースコード追ったりするときも楽になるし。

Laravel初心者から毛を生やす

Laravelに限らずRailsとかでも、フレームワークをちょっとやってそれっぽくアプリケーションを開発できるようになるとそこで満足してしまうことが多い。フレームワークが持ってる機能はそんなちょっとやったぐらいで全て抑えられるものじゃないので、常によりより実装方法をフレームワークが提供していないかを意識して、良いコードを書く習慣を付けたい。

範囲式を使ったフリップフロップ

Rubyのフリップフロップ式の使い方。この記事見るまでRubyでそんなこと出来るの知らなかったが、こんなトリッキーなコードを使うときが来るのだろうか。よほど限定的な状況じゃないと大した可読性も得られずレビュー通らなそう。でもプログラマとしてはここぞという場面で使いたい欲が高まってくる。

学習を加速させるインデックス読書術

読書なんてのは「15分読んで合わなそうなら捨てる」ぐらいの気持ちでガンガン当たったほうが良い。全部読まなきゃならないなんて圧力を自らにかけて視野を狭めるようなことはもうしたくない。

やはりお前らの真偽値メソッド名は間違っている。 〜「Xxx できる?」系メソッドの命名〜

True/Falseを戻すメソッド名の先頭にisを付けたい気持ちはよくわかる。(Rubyだと末尾に’?’を付けられるのでそうはならないが)

英単語のチョイスはどうにかなっても、品詞を使い分けで失敗する問題が現場でもよくある。allow/allows/allowedぐらいの使い分けは社会人としてやってできてほしいけど。

品詞の使い分けで失敗するの何でかって、それっぽい日本語で機械翻訳かけて出たのをそのまま使うケースが自分含め多いからなんだよね。機械翻訳使うなら、日本語側も品詞を意識して、それに応じた翻訳結果が出るかを意識する必要がある。Google翻訳と比べるとcodicはその辺よく出来てると思うけど。

新卒エンジニアのお節介

こういうFRESHな視点を忘れないようにしたい。いや新人でここまで考えられたら最初から戦力になると思うぐらいしっかりしてるけど。

超高速な静的Webページを作ろう!

保守性と機能性を無視した極端な例だけど、阿部寛タイプはこのぐらい突き詰めたほうがいいかも。以下あたりのノウハウは一般的なWebアプリケーションでも活用できそう。

  • CDNで配信する
  • 画像は可能な限りSVCを用いる
  • そもそも画像を減らす、縮める、base64で1ファイルに束ねる
  • 圧縮して配信する

強いエンジニアにHelloWorldさせてみた(縛りあり)

パワフルな力技実装から、トンチがきいた回答、言語仕様を巧みに利用したテクニカルな回答と、色々あって面白い。単純に数値を数値以外で表現できるならASCII使ってどうにでも出来ると思ったけど、色々な回答があるからいくつかチェックしよう。

※ 回答11が何故そうなるのかさっぱりだったので検証してみた。

解答

console.log(((![]+[])[+!![] + +!![]]+([][+!![]]+[])[+!![] + +!![] + +!![] + +!![] + +!![]]+([][+[]]+[])[+!![] + +!![] + +!![] + +!![]]+([][+[]]+[])[+[]]+(![]+[])[+!![] + +!![]]+(![]+[])[+!![] + +!![]]).toUpperCase());
VM1624:1 LIFULL

まず、空配列の否定は文字列になる

![]
false

配列の和は文字列結合になる。これ意外。

[1,2,3] + [4,5,6]
"1,2,34,5,6"

よってこれで文字列のfalseが取れる

![] + []
"false"

空配列を反転してさらに反転すると真偽になる(true)
それを数値に変換すると1。これで数値が取れるようになる

+!![]
1

よってこれで2が取れる

+!![] + +!![]
2

これで”false”の3文字目である”l”を抜き出せる。一気に解答に近づいてきた。

(![]+[])[+!![] + +!![]]
"l"

配列の範囲外を取得するとundefinedが取れる

([][+!![]]+[])
"undefined"

なんと”undefined”には、先程取得した”l”以外のLIFULLを構成するアルファベットを全て含んでる。
なのでこれまで同様の手法で文字を抜いてく

a = (![]+[])[+!![] + +!![]]+([][+!![]]+[])[+!![] + +!![] + +!![] + +!![] + +!![]]+([][+[]]+[])[+!![] + +!![] + +!![] + +!![]]+([][+[]]+[])[+[]]+(![]+[])[+!![] + +!![]]+(![]+[])[+!![] + +!![]]
"lifull"

最後に大文字に変換

a.toUpperCase()
"LIFULL"

ASCIIを使わずとも、false/undefinedから文字列を抜くのが目からウロコ。さらに配列のindexを数値を使わずに得るために空配列を巧みに使ってる所もスゴイ。

「知識ゼロからのビットコイン・仮想通貨入門」レビュー

書籍について

タイトル 知識ゼロからのビットコイン・仮想通貨入門
著者 廣末紀之
発行日 2018/01/10
ページ数 127ページ
価格 1300円
Amazon http://www.amazon.co.jp/dp/4344903293

概要

2017年は仮想通貨元年などと言われていたのに、ブロックチェーン含めその周辺に無関心なまま過ごしてしまい、ITエンジニアとしてこれはアカンと思い、薄くて内容もラフそうな本書籍を購入。

内容の難易度は軽めで、コンピュータに縁がない世代だと難しいが、非エンジニアでもすんなりと全容を把握できる程度。

題の通り、ビットコインをベースとした内容になっているが、基盤技術となるブロックチェーンについてもやや技術的な面も含めて解説されている。ビットコイン以外の仮想通貨(アルトコイン)についても少なからず触れられているので、ビットコイン自体には関心がないという人でも問題ない。

ページ数が少ないこと、大きな図が多いこと、同じ説明を繰り返してること(重要ポイントだから?)から、累計3時間弱で読了。

序章 ビットコイン・仮想通貨 これだけは抑えておきたい7つのポイント

「仮想通貨に言うほど興味ないけど最低限知りたい」みたいな人はここの7ページだけ読んでおけば最低限話題に困らないレベルには慣れる。7つのポイントはざっくり言うと以下の感じ。

  • ビットコインはインターネットで使える仮想通貨のことだよ
  • 国や銀行が関与する円やドル(法定通貨)とは別物だよ
  • ビットコインは非中央集権型(管理者が存在しない)だよ
  • 取引データを承認(マイニング)してビットコインの維持管理に貢献した人には報酬が貰えるよ
  • ブロックチェーンの元となった論文を発表したのはサトシ・ナカモトという謎の人物だよ
  • 日本は世界的に見ても仮想通貨に許容的、積極的なほうだよ

以降の章では、主に上記のポイントについて深掘りしている

PART1 誰がビットコインを作ったの

ブロックチェーン及びビットコインがどのような経緯で生まれたのか、生みの親とされるサトシ・ナカモトとは何者なのか、どうやって維持しているかについての章。

サトシ・ナカモトの正体不明感はロマンを感じる。

PART2 発行の仕組み、安全と信用とは

主にブロックチェーンの技術的な仕組みの章。ITエンジニアにとってはここが一番面白い章で、そうでない人にとっては頭を悩ませるかも。

取引の承認をどうやってるのか、承認の仕組みは安全なのか、脅威は無いのかなど

PART3 どこで補完し、どこで現金と交換する?

実際にビットコインを購入したい人にとっては最も大事な章であり、私のように技術的なほうに関心がある場合はそこまで興味がない章。

口座はどうやって作るのか、どうやって売買するのかなど。

PART4 私達の生活はどう変わる

ビットコイン以外の仮想通貨(アルトコイン)にはどのようなものがあるのか、何故800種もの仮想通貨が生まれるのか、国ごとの仮想通貨に対する扱いはどうなってるのか、日本では法律はどれほど整備されてるのかなど。

このあたりは仮想通貨の浸透と共にどんどん変わっていくものだから、あっという間に情報が古くなると思う。

感想など

  • 当初の目的であった「仮想通貨とブロックチェーンについてザックリ知りたい」をわずか3時間弱、1300円でしっかり満たせたので良い買い物ができたと思う。
  • 一つのテーマを必ず2ページ見開きにおさめて、上半分に図やグラフを、下半分にテキストを配置するスタイルで一貫されてるので非常に読みやすい
    • 故にどこから読んだら良いのか迷ったりもした。私は最初に文章を読んで概要を把握して、それから図に目を通して理解するフローにした。
  • 「ビットコインは非中央集権型である(仲介者が存在しない)」あたりの説明が何度も何度も登場するのが気になった。
    • 頭から順に読まなくても良いようにする配慮?

以下の人には向いてそう

  • 仮想通貨全然知らないけどざっくりと抑えたいITエンジニア
  • 教養として、話題の一環として仮想通貨を知りたい人

以下の人には向いてなさそう

  • 仮想通貨に投機(投資)して設けたい人
  • ブロックチェーンの技術を具体的に知りたい人
    • 一番最初のステップとしてはありかも

MANABIYA day2 参加してきました

概要

2018/03/24 国内最大級のエンジニア向けの技術祭典を謳う、teratail主催のカンファレンス企画、MANABIYAの二日目に終日参加してきました。本記事はその概要や個人的な感想などのレポになります。

MANABIYAとは

公式サイトより転載

“MANABIYA” は、teratailがおくるITエンジニアの問題解決カンファレンスです

ITエンジニア特化型Q&Aフォーラムteratailでは、「質問」と「回答」という形で問題解決をサポートしてきました。次に私達が目指すのは、既存のQ&Aシステムでは解決できない問題に解を見出していくことです。「質問」まではいかないが ”気になっていること”、「回答」を知りたいがなかなか ”知る機会がなかったこと”。そういった ”疑問” を日本中から集め、カンファレンスを通じて解決策を見出し、”知恵” を生み出す。これが、”MANABIYA” を開催する想いです。

日本中の “疑問” をみんなの “知恵” に。

ざっくりとどんな企画が列挙すると

  • 著名なエンジニアなどの方々による講演、ディスカッション
  • 講演者に1:1で直接相談などができるコーナー
  • ハンズオン形式の各種技術体験
  • LT大会
  • XR(AR,VR,MRなど)の体験コーナーや、IoTの展示コーナー
  • 各種スポンサー企業による出展
  • 学校給食風の飲食店

などがありました。仕事の都合で二日間に渡るイベントの中で二日目のみの参加になりましたが、どのコーナーもなかなかに楽しむことができました。

雰囲気はInstagramを見ると伝わるかもしれません。

ちなみに受付を済ませると、イベント限定のトートバックと缶バッチ3個が貰えました。缶バッチはプログラミング言語やOSなどの技術ワードが書かれたものが多数が用意されており、3個まで自由に選んで貰えました。私は最近はもっぱらRailsとVuejsを書いてるので、Ruby/JavaScript/Node.jsを選びましたが、JSとNodeじゃちょっと被ってますね。

以降では、拝聴した講演の内容や感想などをまとめていますが、メモを取りきれなかった部分、記憶が怪しい部分が少なからずあります。明らかな誤りがあった場合はお手数ですがご報告頂けると幸いです。

プログラミング言語界隈で出てきがちなキーワード50連発

Rust.jp主催、清水智公様の講演です。Rustはこの後に少し触ってみたんですが、コンパイルの制約が厳しくて、コンパイルを通すまでが大変、でも通ってしまえばバグが生まれにくいといった印象でした。

50連発の50にはあんまり意味がなく、とにかく時間の許す限り話をしようという意味だそうです。講演中に登場した主なワードは以下の通り。

  • プログラミング言語
  • チューリング完全
  • インタプリタ
  • コンパイラ
  • JIT
  • AOT
  • プログラミングパラダイム
  • 手続き型
  • オブジェクト指向
  • 関数型
  • 論理型
  • 並列性、並行性
  • 手続き的、宣言的
  • 帰納法、演繹的
  • 型、型推論
  • ジェネリクス、総称型
  • アクセス権
  • エコシステム、再利用

多くはよく知るワードでしたが、それが何故必要になるのか、他のワードとどう関わってくるのかが図付きで関連付けられていて、楽しく拝聴することができました。

個人的には以下のお話が興味深かったです。(文面は要約です)

  • プログラミング言語の必須要素は「変数」「演算」「条件分岐」「繰り返し」で、FizzBuzzはそれら全てを抑えている。新しいプログラミング言語を学ぶ時は、その言語で最も自然にFizzBuzzを書いた時にどうなるかを見てみると良い。

  • 新しい言語を学ぶなら、「この言語を作った人は何を理想に、どうしたくて作ったのか」を意識しよう

エンジニアのための自分経営戦略

コーディングを支える技術の著者としても有名な西尾泰和様の講演です。

ちなみに本ブログでも、コーディングを支える技術のレビューを掲載しています。(レビューと言うほどでもない読書メモですが)

「コーディングを支える技術」レビュー | qs Developers

本講演のスライドはWebで公開されています。こちらに目を通すだけでも概ね講演の内容は把握できるのでおすすめです。

MANABIYA_エンジニアのための自分経営戦略.pdf

講演内容については上記スライドの通りなので、拝聴して特に良かったこと、感じたことを列挙します。

  • 「『この本を全部読んで理解しよう』はダメ。『まずは15分読んでみよう、それでダメなら辞めよう』にする。そうすれば失敗したときの損失を最大15分に抑えることができる。」 この言葉は僕にとっての学ぶことのハードルを下げる特効薬になりました。あまり深く考えずに少しだけやってみて、そこでイケそうなら突き進む、ダメそうなら打ち切って切り替えていく。足踏みしない学習プロセスを得ることができました。

  • 「お金は使うと無くなり、使わないとなくならない。知識は真逆で、使わないとなくなるが使えば使うほどなくならない」 これは目から鱗な本当に上手い言い回しだと思いました。確かにその通りで、苦労して得た知識も使わなければどんどん減っていくけど、使い続ければ一生使える。肝に銘じます。

  • 「技術進歩による知識の海面上昇は早い。ググってすぐに辿り着ける情報は知識交換では役に立たない。海面の上の情報を学ぶことが専門性を高めるということで、ググって手に入らない情報を自分で動かして知ることが大事」 今まで頑張って学んだこと、出来るようになったことが、技術の進歩によって誰にでも手が届くものになる。この業界はずっとその繰り返しだと思うので、その中で常に「誰にもは出来ない事」を出来る人になる事を意識しないといけないと思いました。

プログラミング CrossSession

MANABIYAにおけるCrossSessionは、その分野の著名な方々が、そのテーマに関する質問などを元にディスカッションするというセッションです。

プログラミング CrossSessionでは、前項の「プログラミング言語界隈で出てきがちなキーワード50連発」の講演も行った、清水 智公様をセッションオーナーに、光成 滋生様、keen様、沼野 剛志様がスピーカーとなる講演でした。

本セッションは、セッションオーナーの清水様がスピーカー3名に質問をし、それぞれが回答するという流れでした。概ねメモは取ったのですが、どの発言をどなたがしたのかを抑えきれていなかったので、回答を列挙するという形で掲載させていただきます。(順もバラバラ)

  • Q 新しいプログラミング言語をどうやって勉強する?
    • とりあえず公式ドキュメント読んで、公式のチュートリアルやる。その後は大きめのプログラムを書いてみる。わかんなくなったら問題点をブログに書く。そのあと解決できたらブログを更新する
    • 本を読む。特にターゲットを明確に絞ったもの
    • 数学の問題(競技プログラミング?)を解く。他の言語では解けて、アルゴリズムは理解してる問題を新しい言語でもやってみる
  • Q 公式ドキュメントって膨大な情報があるけどどうやって見る?
    • ドキュメントは隅々までガッツリ読む。初めてその言語でコードを書く時はもう文法とか全て理解してるぐらいに。
    • スマホのホーム画面に閲覧用のアプリを置いて、コンビニの待ち時間とか些細な時間にも触れる習慣をつける
    • チュートリアルを読む
  • Q HaskellやRust、C++で全然パラダイムが違うけど、それぞれ学ぶとプログラミングスタイルが変わったり足を引っ張ったりはあるか?
    • 引っ張られることは多い。当たり前にできると思ったことが出来ないとか。
  • Q プログラミングのパラダイムが変わると設計が変わると思うけど、設計どうしてる?データから考えるか手順から考えるかとか
    • 暗号系のことをやってるので、早さが重要視される。そのためデータが先で、効率よくアクセスできるデータ構造を先行して考える
    • 言語による。静的型付け言語なら型を先に決める。そのデータから何ができるか考える。動的型付け言語ならREPLで関数をどんどん書いてみて、それを組み合わせるとか
    • アプリケーションを作る観点なら、APIみたいな外の機能から作る
  • Q 綺麗なコード(メンテナンスコストが低い)とパフォーマンスの高いコードどちらを優先する?
    • そこまでパフォーマンスが重要視されないコードであれば保守性の観点から綺麗に書くことを優先する
    • 将来的にCPUがさらに高速化するので、綺麗なコードを書いておけばいずれパフォーマンスはあがる
  • Q 綺麗なコードとパフォーマンスの速いコード、どちらを優先するかの境界線をどう捉えている?
    • パフォーマンスが微妙な場合、ベンチマークを取って、一定の数値以下なら保守性を犠牲にして高速化したりする
    • パフォーマンスについてはコンパイラに頑張ってほしい。綺麗なコードを書いても、コンパイラがそれを最適化してパフォーマンスをあげるような。
    • 仕事でやる分には綺麗優先。趣味だと高速化が目的になるのでパフォーマンスを最優先にする
  • Q バグが出にくいコードを書くコツは?
    • 確実に動く小さな部品を組み合わせること。ライブラリとか安定して動く、他の人が作ったものを利用すること。
    • Rustなどのように、型の制約をキツくすれば、コンパイルさえ通ればバグの少ないプログラムが出来上がる
  • Q プログラミングをこれからも続けたい?
    • 続けたい。趣味でやる分には、作りたいけど作れてないものがまだまだある。それが終わるまでは続ける。仕事は、コレ以外に向いてるものがないので仕方なくやる。
    • 続けたい。自分が作りたいものを自由に作れるから。
    • 続けたい。でもこれから機械学習がさらに成長して、コードの生成が自動的にできるようになってくると人間不要になっていくのかも。

IoT CrossSession

続けて今度はIoTをテーマにしたCrossSession。

正直な事を言いますと、この時間はWeb系の講演を拝聴するつもりだったのですが、そちらが超満員だったので、同行した友人が拝聴していたこのセッションに向かいました。そのため、他のセッションと比べるとメモが全然取れなかったので、記憶を頼りに少しだけ内容を整理しています。

IoT CrossSessionでは、菅原 のびすけ様がセッションオーナーとなり、馬橋 雄祐様、部谷 修平様、新里 祐教様、菊地 仁様とディスカッションを行う形式でした。

セッションオーナーののびすけ様は、私の大学の先輩にあたり、在学中からITベンチャー企業の役員を務めるほどのスゴイ方で、一方的に知っていました。(主にQiitaで) そのアクティブ過ぎる活動、心から尊敬しております。

ちなみにディスカッションとは言いましたが、始まってすぐにお酒で乾杯が始まり、ゆる〜い雰囲気でまさにフリートークといった空気が印象的でした。セッションでは事前に集められた質問及びTwitter上の書き込みを見ながら、スピーカーの方々に話題を振るという流れでした。

ちなみにセッション中に、以下の私のツイートも拾って話題の一つにして頂けました。私含むWebエンジニアが会場の多くを占めていたようで、やはり気になる話題だったようです。(改めて見ると日本語が怪しいツイートだ)

上記質問の回答を要約すると、「適した言語は色々あるけど、最初は自分の好きな言語でやると良いよ」とのことでした。ありがとうございました。

他、記憶頼りですがセッション中の気になったお話は以下の通りです。

  • 国内で66歳のベテラン猟師のおじいさんが、IchigoJamで初めてプログラミング及びIoTを学んで、猟師にIoTを取り入れた事例がある。ある分野のプロフェッショナルとITを組み合わせる可能性が無限にある
  • やりたいことがあってIoTに手を付けるのが正しい。漠然と「IoTやりたい」という考え程度なら無理してやる必要はない
  • この先、ITのようにIoTも一般化する。その時ほぼ全てのIT企業はIoT企業のようになり、当たり前のようにIoTを扱う日が来る。なので今はWeb系のエンジニアたちも、このままプログラマを続けるのであれば高確率でIoTに携わることになる

オブジェクト指向言語と関数型言語

本日最も高い刺激を受けたセッションでした。資料は公開されているし、内容も資料のままなので、内容については割愛します。
オブジェクト指向言語と関数型言語 | κeenのHappy Hacκing Blog

40分という限られた時間の中で、このスライドの量をしっかりと解説するテンポの良い発表も印象に残りました。何よりこの辺の技術の話が本当に好きなんだと言う気持ちが伝染し、意欲を引き上げられたのが一番の成果だったりもします。

特にWebエンジニアは、実務じゃオブジェクト指向な言語しか使う機会が殆どありません。そんな人でも関数型のような他のプログラミングパラダイムを学ぶ必要はあるのか、学べばどんな利点があるのか、早口ながらスッと頭に入って引き込まれる発表でした。

会場は席があっという間に埋まって立ち見になりましたが、それでも足が疲れるとか感じることもなく、あっという間の40分でした。

LT大会(プログラミング/IoT)

最後のセッションは有志によるLT大会でした。ただ、募集人数に対して有志が思ったように集まらなかったのか、プログラミングテーマとIoTテーマで計12人募集していたはずが、3人だけで終わってしまうという残念な結果でした。

3名のLTはそれぞれ内容もスタイルも違っていて面白かったのですが、その人数が非常に物足りなかったです。もう少し早く知っていれば、vimとか勉強方法とかのテーマで私も応募していたので、次回があればアンテナ張っておこうと思います。

MANABIYA総評

最後に、講演内容とは関係なくMANABIYAのイベント全体についての感想をまとめます。

良い点

  • トートバッグと缶バッチ、水が受付時に貰えるのは本当に嬉しかった。特に缶バッチはどこに付けようかと今も迷ってます
  • 各講演のテーマがしっかり決まっているので、自分の興味にあわせて選べるのが良かったです。
  • 各講演とも40分(一部例外あり)という丁度よい、中だるみのない長さが自分的に合っていました。
  • 誰でもその場で”疑問”を書き込み、誰でも回答できる、「壁にテラテイル」は面白い試みでした。
  • 全体的に学校風に仕立てた雰囲気が良かった。学校給食風飲食店にて、揚げパンとタピオカミルクティーのセットが200円で買えるという学食もびっくり価格が良かったです。(夕方の割引時でしたが)

悪かった点

  • 機材トラブルが多く感じました。プロジェクタは本番に限って映らないものという法則もありますが、復旧までが長かったりして残念でした。
  • 屋上テントは席によってはスライドがまったく見えませんでした。上記機材トラブルも相まって、せっかくの講演なのに歯がゆい時間が多かったです。
  • 全体的に会場のキャパオーバーが目立ちました。講演のクオリティーから考えると、参加費を徴収したり、整理券を配布しても良かったかもしれません。

[Rubocop] 特定のルールを特定のファイル(ディレクトリ)でのみ無効にする

概要

Rubocopにて、このファイル(ディレクトリ)ではあのルールは無効にしたいなと思って試してみたら普通に出来たので備忘録を残す。

そもそもRubocopってなんなのさという方は以下を参考に。
[Ruby] RuboCopをインストールしてvimで実用化するまで | qs Developers

前提

  • ruby 2.4.1
  • rubocop 0.52.1

方法

file_a.rb

class Hoge

end

file_b.rb

class Fuga

end

の2つのRubyスクリプトを用意する。両クラスとも、クラスの先頭に空行がある(というか空行しか無い)ので、そのままRubocopを実行すると両ファイルに対してLayout/EmptyLinesAroundClassBodyの警告が出る。

$ rubocop
Inspecting 2 files
CC

Offenses:

file_b.rb:2:1: C: Layout/EmptyLinesAroundClassBody: Extra empty line detected at class body beginning.
file_a.rb:2:1: C: Layout/EmptyLinesAroundClassBody: Extra empty line detected at class body beginning.

2 files inspected, 2 offenses detected

その際、例えばfile_a.rbは警告出していいけどfile_bでは出したくないという場合は、.rubocop.ymlに以下の記述を追加する。

Layout/EmptyLinesAroundClassBody:
  Exclude:
    - 'file_b.rb'

これでfile_a.rbにのみLayout/EmptyLinesAroundClassBodyが適用されるようになる。

$ rubocop
Inspecting 2 files
.C

Offenses:

file_a.rb:2:1: C: Layout/EmptyLinesAroundClassBody: Extra empty line detected at class body beginning.

2 files inspected, 1 offense detected

個別に実行しても同様。

$ rubocop file_a.rb
Inspecting 1 file
C

Offenses:

file_a.rb:2:1: C: Layout/EmptyLinesAroundClassBody: Extra empty line detected at class body beginning.

1 file inspected, 1 offense detected
$ rubocop file_b.rb
Inspecting 1 file
.

1 file inspected, no offenses detected

3年目プログラマが参考にしたQiita記事まとめ⑰

概要

特にカテゴリもレベルも偏らずにざっくばらんに、参考になったQiita記事を一言添えて列挙するシリーズ17本目

Qiitaまとめシリーズ

エンジニアリング・マネージャの技術との関わりかた、あるいは折り合いのつけかた

エンジニアリングマネージャって存在を初めて知った。もしかすると自分が目指す先の一つかも知れない。確かにエンジニア視点でマネジメントされるなら、豊富な技術経験がある人のほうが安心できる。プログラマリーダとも違う、エンジニアをマネジメントする立場はあってほしいね。

Rubyでif文やwhile文とか言っている入門は非推奨

ちょっと言い過ぎかなと思った‥‥。入門者から見たら文って言ったほうがわかりやすいし、正確な説明を必要としないレベルのサイトもあると思うし。それを言ったら#includeはおまじないって言ってるサイトはどうなのさ。ただ入門の次のステップとして、Rubyに限らず文と式の違いはしっかり理解できるようになってたほうが良いと思う。

Macに別れを告げて、クラウド中心の開発生活を始めるまで

徹底しててスゴイ。ストレージとかのクラウド化はもう自然の一部になってきてるけど、開発環境のクラウド化はどうしても抵抗ある。「インターネット繋がってないと使えない」って理由ではない。カフェでMac開いても、Wifi拾えなきゃまず開発しないし。(ググれないと何も出来ないゆとりなので)
何となく、ほんとに何となく開発環境はローカルに起きたいって気持ちが強い。そもそも記事通りにAWS導入したらお金もかかっちゃうしね。

Haskellを勉強して感動したこと・難しいと思ってること

来年こそはHaskellで物作りしよう。毎年言ってるなコレ。なんとなく、プログラマ人生に大きく影響を与える言語だと思ってる。Haskellがというより純粋関数型言語が。初めて出会ってからもう4年も経つのに何も出来てない。何で何回挑戦しても詰むんだろ。

食べられないほうのカリー化入門

カリー化の概念はよくわかったけど、それでも自分が実用的に活用できる場面がイマイチ想像できないな。そして部分適用とカリー化の違いもよくわからない。このへんも関数型言語に慣れてこないと解らない感覚なのかな。で、読み終わってから、記事の各見出しが美味しんぼだということに気づいた。

個人プロダクト開発で、困った時にどうするか

夫婦でプロダクト開発ってなかなかに、いや相当レアケースだと思うけど、それを覗いても将来的に参考になりそうな情報が豊富。まずは動くモノを作るとこからだけど、上手いこと広げていってコレを参考にできるようにする。

デザイナーがSQLを書けるようになったら、デザインフローが早くなった話

デザイナとSQL、どう関わってくるんだろうと思ったけどそういうことか。でもGoogleアナリティクス入れてる環境なら、GUIで自在に集計できるからわざわざSQLを学習させるメリットが内容にも感じるけどどうなんだろ。

vimrcの育て方

もっとvim力向上させたい。今年はかなりレベルアップした気がするけど、まだ使い方を工夫できるようになっただけで、設定のコツや、vimscriptの応用的な使い方には全然手が出てない。今後も継続的にvim力向上に励もう。

サル以下の存在がまとめた「Git用語」図解

わかる。ブランチの説明が実際と異なってる入門サイトが多い気がする。いや感覚的にそのほうがわかりやすいからだろうけど、 ブランチは線とか面でなく点。もっと言えばC言語のポインタ的なもの。 コミットがブランチに所属するんでなく、ブランチが特定のコミットを指してるだけ。この辺が分かるとブランチの考え方がすんなり来ると思う。

「JSX キモい」に反論してみる

Reactやりはじめ僕 「JSXキモい!」
React慣れてきた僕 「JSXキモくない!」
Vueにハマった僕 「やっぱJSXキモいわ」

記事が言わんとしてることはよくわかる(JSXはテンプレートでなくJSの糖衣構文であること)けど、その上でもやっぱりJSXは気持ち悪くてVueテンプレートのほうが遥かに良い。

記事後半からはJSXやReactだけでなく、Vueでも言えるコンポーネント指向の話だけどこれがまたわかりやすい。長らく続いたサーバサイドのMVCによるロジックとビューの分離がコンポーネント指向では根本から覆されてる。ロジックとビューは密なものであり、もはやCSSはデザイナが書くものではないっていう考えには賛同できる。デザイナさんはデザインに全力を尽くすだけで良くて、中途半端にCSSに手を出されると保守的でないスタイリングになって大変。コンポーネント指向はこれも大きく改善できてる。

[Ruby] privateとprotectedの違いとか調べた

概要

Rubyのprivateメソッドやprotectedメソッドの挙動が、なんかJavaやC#でよく見るオブジェクト指向な挙動と違うので、動かしながら調べてみた。

前提

ruby 2.2.2

privateメソッド

レシーバ付きで呼び出せなくなる

class Hoge
  def initialize
    say_hello
  end

  private
    def say_hello
      p 'Hello!'
    end
end

hoge = Hoge.new # Hello!
hoge.say_hello  # エラー

rubyでは、private以下のメソッドは全てprivateになり、クラス内から呼び出すことができてもレシーバ付きで呼び出すことができなくなる

まぁ呼ぼうと思えば呼べる

class Hoge
  def initialize
    say_hello
  end

  private
    def say_hello
      p 'Hello!'
    end
end

hoge = Hoge.new # Hello!
hoge.send(:say_hello) #Hello!

sendメソッドを使うと、クラスの内側からメソッドを呼び出すのと同じように実行できるので、privateメソッドも呼べてしまう。Rubyのアクセス制御は性善説

privateメソッドの有無の確認

class Hoge
  def initialize
    say_hello
  end

  private
    def say_hello
      p 'Hello!'
    end
end

p Hoge.private_instance_methods.count # 73
p Hoge.private_method_defined? :say_hello # true

クラスメソッド、private_instance_methodsは、クラスに定義されているプライベートメソッドの一覧を、メソッド名(シンボル)の配列で取得できる。これは親クラスのも含んで、Hogeクラスには73のプライベートメソッドがあることがわかる。

また、private_method_defined?メソッドを使えば、指定したプライベートメソッドが存在するか確認できる。

protectedメソッドも基本は同じ

class Hoge
  def initialize
    say_hello
  end

  protected
    def say_hello
      p 'Hello!'
    end
end

p Hoge.protected_instance_methods # [:say_hello]
p Hoge.protected_method_defined? :say_hello # true

hoge = Hoge.new # Hello!
hoge.say_hello # エラー

クラス内からは呼べるけど、レシーバ付きでクラスの外からは呼べない。protected_instance_methodsメソッドでprotectedメソッド一覧を取得して、protected_method_defined?メソッドで有無を検証。このへんもほぼ同じ。

privateとprotectedの違い

class Hoge

  def func
    private_say_hello   # OK
    protected_say_hello # OK
  end

  private
    def private_say_hello
      p 'private Hello!'
    end

  protected
    def protected_say_hello
      p 'protected Hello!'
    end
end

Hoge.new.func

まずはprivateメソッドとprotectedメソッド両方定義したクラスで、クラス内から両方を呼び出してみる。もちろんどちらも呼び出し成功。

class Hoge

  def func
    self.protected_say_hello # OK
    self.private_say_hello   # NG
  end

  private
    def private_say_hello
      p 'private Hello!'
    end

  protected
    def protected_say_hello
      p 'protected Hello!'
    end
end

Hoge.new.func

今度はself付きで呼んでみると、初めて違いが出た。protectedなメソッドは呼び出せたのに、privateなメソッドは呼び出せない。

class Hoge

  def func
    other_hoge = Hoge.new
    other_hoge.protected_say_hello # OK
    other_hoge.private_say_hello   # NG
  end

  private
    def private_say_hello
      p 'private Hello!'
    end

  protected
    def protected_say_hello
      p 'protected Hello!'
    end
end

Hoge.new.func

さらに形を変えて、Hogeクラス内で新しくHogeオブジェクトを作成、同様にメソッドを呼び出した場合も結果は同じく、protectedメソッドだけ呼び出せるようになる。

まとめ

クラス内レシーバ無し クラス内レシーバあり クラス外
private OK NG NG
protected OK OK NG

protectedに使いみちある?

そうそう無いと思う。

公式ドキュメントの例だと以下の例があげられてる。

class Foo
  def _val
    'val'
  end
  protected :_val

  def op(other)

    # other も Foo のインスタンスを想定
    # _val が private だと関数形式でしか呼べないため
    # このように利用できない

    self._val + other._val
  end
end

上記みたいにクラス内で自身と他のインスタンス両方で呼び出したいメソッドがあるような場合には使えるっぽい。

参考

[ruby] 配列内の要素に重複がないか検証するメソッドを実装(Array#uniq?)

概要

Rubyにて、配列の要素が重複しているかどうかを検証したい。例えば[1,2,3]ならtrueを、[1,2,3,2]ならfalseを戻すように。

Arrayの標準メソッドにそれらしいものがあると思っていたが、どうやら内容なので自前で作ることに。

前提

ruby2.2.2で動作確認

普通にメソッドを実装する

def uniq?(array)
  uniq_check = {}
  array.each do |v|
    return false if uniq_check.key? v
    uniq_check[v] = true
  end
  return true
end

array.uniq.size == array.size とかでも良かったけど、パフォーマンス的にこっちのほうが良さげ?

配列を引数にして利用する。

[2] pry(main)> uniq?([1,2,3])
=> true
[3] pry(main)> uniq?([1,2,3,2])
=> false

Arrayクラスにメソッドを追加する

前項の普通にメソッドを実装するのも良いけど、使い方がRubyっぽくないので、Arrayクラスにメソッドを追加する形で再実装する。

class Array
  ##
  # 要素が全てユニークであるかを評価
  # [1,2,3].uniq?   - true
  # [1,2,3,2].uniq? - false
  def uniq?
    uniq_check = {}
    each do |v|
      return false if uniq_check.key? v
      uniq_check[v] = true
    end
    return true
  end
end

Arrayのメソッドとしてuniq?を呼べるようになる

[2] pry(main)> [1,2,3].uniq?
=> true
[3] pry(main)> [1,2,3,2].uniq?
=> false

オマケ 重複してる要素を取得する

あわせて、[1,2,3,2,3]なら[2,3]を、[1,1,1,1]なら[1]を取得するようなメソッドも欲しかったのでまとめて実装した。

class Array
  def duplicates
    uniq_check = {}
    dups = {}
    each do |v|
      dups[v] = true if uniq_check.key? v
      uniq_check[v] = true
    end
    dups.keys
  end
end

良い感じに抜き出せた

[2] pry(main)> [1,2,3,2,3].duplicates
=> [2, 3]
[3] pry(main)> [1,1,1,1,1].duplicates
=> [1]

オマケ rspecによる単体テスト

Array#uniq?とArray#duplicatesのrspecによる単体テストも書いた。

describe Array do
  describe 'uniq?' do
    subject { array.uniq? }

    context '[1, 2, 3]' do
      let(:array) { [1, 2, 3] }
      it { is_expected.to be true }
    end
    context '[1, 2, 3, 2]' do
      let(:array) { [1, 2, 3, 2] }
      it { is_expected.to be false }
    end
    context '[]' do
      let(:array) { [] }
      it { is_expected.to be true }
    end
  end

  describe 'duplicates' do
    subject { array.duplicates }

    context '[1, 2, 3]' do
      let(:array) { [1, 2, 3] }
      it { is_expected.to eq [] }
    end
    context '[1, 2, 3, 2, 3]' do
      let(:array) { [1, 2, 3, 2, 3] }
      it { is_expected.to eq [2, 3] }
    end
    context '[1,2,1]' do
      let(:array) { [1, 2, 1] }
      it { is_expected.to eq [1] }
    end
    context '[1, 1, 1, 1, 1]' do
      let(:array) { [1, 1, 1, 1, 1] }
      it { is_expected.to eq [1] }
    end
  end
end

テスト結果

Array
  uniq?
    [1, 2, 3]
      should equal true
    [1, 2, 3, 2]
      should equal false
    []
      should equal true

  duplicates
    [1, 2, 3]
      should eq []
    [1, 2, 3, 2, 3]
      should eq [2, 3]
    [1,2,1]
      should eq [1]
    [1, 1, 1, 1, 1]
      should eq [1]

Finished in 0.01665 seconds (files took 4.48 seconds to load)
7 examples, 0 failures

API Blueprint + aglio でAPIドキュメントサーバを構築する

概要

WebAPIの仕様を記述するための言語であるAPI Blueprintと、API Blueprintで記述されたAPPI仕様からドキュメントとなるHTMLを生成したり、Webサーバとして動作することでドキュメントサーバを構築できるaglioを用いて、Debian上にAPIドキュメントサーバを構築してみたのでその備忘録。

API Blueprint + aglio で作成できるAPIドキュメントのサンプルはこちら

前提

node/npmが使えて、Webブラウザが使える環境からアクセスできるDebianがあること

debian 9.3
node 9.8.0
npm 5.6.0
aglio 2.3.0

API Blueprint/aglioについて

API Blueprintは、WebAPIの仕様を記述するための言語。

例えば以下は、API BlueprintのHello World!

# GET /message
+ Response 200 (text/plain)

        Hello World!

上記コードは、「/messagに対してGETリクエストを送信すると、ステータスコードが200で、text/plain形式の”Hello World!”が返却される」というAPIの仕様を表現している。

上記のHello,Worldだけだとイマイチしっくり来ないが、API Blueprintには様々な構文が用意されている。
その辺りはドキュメントが豊富なので、Exampleに目を通してみるとイメージが付くかもしれない。API Blueprintを使用することで、表現力豊かなAPI仕様を書くことができ、素早い設計やプロトタイプの構築を行えるようになる。

また、関連ツールを用いることで、ドキュメントサーバを構築したり(本記事)、APIの自動テストを生成したり、APIのモックを用意できたり、はては実コードの生成まで行うことができる。

aglioはそんな関連ツールの一種で、API Blueprintで書かれた仕様を元にHTMLを生成したりWebサーバを立ち上げることで、APIドキュメントサーバを構築することができる。以降では、aglioのインストールから、API Blueprintによる仕様からのドキュメント生成、ドキュメントサーバの起動までを行う。

aglioのインストール

npmでaglioをインストール。aglioコマンドを使えるようにしたいので、gオプションでグローバルインストール

$ npm install -g aglio

以下のようなエラーが出る場合

{ Error: Could not get CSS: Error writing cached CSS to file: ENOENT: no such file or directory, open '/usr/local/lib/node_modules/aglio/node_modules/aglio-theme-olio/cache/bb851236ef33e467631256487d5bbe519de24415.css'
    at Object.fs.openSync (fs.js:667:18)
    at Object.fs.writeFileSync (fs.js:1326:33)
    at /usr/local/lib/node_modules/aglio/node_modules/aglio-theme-olio/lib/main.js:222:14
    at /usr/local/lib/node_modules/aglio/node_modules/less/lib/less/render.js:35:17
    at /usr/local/lib/node_modules/aglio/node_modules/less/lib/less/parse.js:63:17
    at ImportVisitor.finish [as _finish] (/usr/local/lib/node_modules/aglio/node_modules/less/lib/less/parser/parser.js:183:28)
    at ImportVisitor._onSequencerEmpty (/usr/local/lib/node_modules/aglio/node_modules/less/lib/less/visitors/import-visitor.js:35:14)
    at ImportSequencer.tryRun (/usr/local/lib/node_modules/aglio/node_modules/less/lib/less/visitors/import-sequencer.js:50:14)
    at /usr/local/lib/node_modules/aglio/node_modules/less/lib/less/visitors/import-sequencer.js:19:25
    at fileParsedFunc (/usr/local/lib/node_modules/aglio/node_modules/less/lib/less/import-manager.js:50:17)
  errno: -2,
  code: 'ENOENT',
  syscall: 'open',
  path: '/usr/local/lib/node_modules/aglio/node_modules/aglio-theme-olio/cache/bb851236ef33e467631256487d5bbe519de24415.css' }

存在しないらしいディレクトリを作ってあげる(パスは環境によって異なるのでエラーメッセージなどで確認する)

$ cd /usr/local/lib/node_modules/aglio/node_modules/aglio-theme-olio
$ mkdir cache

その後再度インストールで解決。

aglioコマンドが使えるようになっていればOK

$ aglio -v
aglio 2.3.0
olio 1.6.3

ドキュメントの作成

適当なディレクトリで、input.mdを作成する。内容は最初に掲示したHello,Worldと同様

# GET /message
+ Response 200 (text/plain)

        Hello World!

aglioコマンドで、API Blueprintで記述したMarkdownファイルからHTMLファイルを生成する。oオプションで出力を指定できるので、output.htmlにしておく。

$ aglio -i input.md -o output.html

出力されたoutput.htmlをブラウザで開くと、以下のようにドキュメントが生成されていることがわかる。

さらに、以下のようなやや複雑なAPI Blueprintコードでinput.mdを上書きして、再度aglioコマンドでoutput.htmlを出力すると

FORMAT: 1A

# Requests API
Following the [Responses](05.%20Responses.md) example, this API will show you
how to define multiple requests and what data these requests can bear. Let's
demonstrate multiple requests on a trivial example of content negotiation.


# Group Messages
Group of all messages-related resources.

## My Message [/message]

### Retrieve a Message [GET]
In API Blueprint, _requests_ can hold exactly the same kind of information and
can be described using exactly the same structure as _responses_, only with
different signature – using the `Request` keyword. The string that follows
after the `Request` keyword is a request identifier. Again, using explanatory
and simple naming is the best way to go.

+ Request Plain Text Message
    + Headers
            Accept: text/plain

+ Response 200 (text/plain)
    + Headers
            X-My-Message-Header: 42
    + Body
            Hello World!

+ Request JSON Message
    + Headers
            Accept: application/json

+ Response 200 (application/json)
    + Headers
            X-My-Message-Header: 42
    + Body
            { "message": "Hello World!" }

### Update a Message [PUT]

+ Request Update Plain Text Message (text/plain)
        All your base are belong to us.

+ Request Update JSON Message (application/json)
        { "message": "All your base are belong to us." }

+ Response 204

以下のように柔軟にAPIの仕様を記述、ドキュメントの構築を行うことができる。

ドキュメントサーバの起動

前述の方法だと、作成中は毎回コマンドを叩いてHTMLを生成して、ブラウザを再読込してとひと手間かかるし、ドキュメントを公開するのも面倒だ。

そこで、aglioのWebサーバ機能を用いて、ドキュメントサーバを立ち上げる。aglioでWebサーバを立ち上げることで、以下の恩恵を受けられる

  • aglioが動いているホスト/ポートに対してHTTPでリクエストすることで、HTML化されたドキュメントを取得することができる
  • Webサーバが立ち上がっている状態で、API Blueprintのコードを編集すると、即座に再ビルドがかかり常に最新の状態になる
  • 再ビルドがかかった際にブラウザでドキュメントを表示していると、ブラウザも自動で再読込がかかる

以下のコマンドでローカルホストの80番ポートにWebサーバを立ち上げることができる

$ aglio -i input.md -s -p 80 -h '0.0.0.0'
Server started on http://0.0.0.0:80/
Rendering input.md
Socket connected

Webサーバが立ち上がり、ブラウザでアクセスしている状態で、エディタでコードを変更すると、以下のようにリアルタイムに再ビルド、ブラウザ更新が行われる。

興味が湧いた人へ

本記事では、API Blueprintとaglioでこんなことが出来るよと触り程度紹介したので、実際に使って見るには情報が不足している。
興味が湧いた人は以下のリンクからさらに調べてみると、より丁寧に書かれているので、さらに理解が深まるはず。