t__nabe_log

雑多 作業、学習ログ多め。

Google Homeを買った。

ついにGoogle Homeを購入

以前から欲しかったので買ってしまった。 https://i.gyazo.com/5af0321a1d46238da2ed9440de71e04d.jpg

正直舐めてた。Spotifyを気楽に再生・停止、TwitterやSlackに音声で呟き、各種ストリーミングサービスの再生や料理レシピ、買い物リストなどを使っているが本当に生活が楽。気をつかうことが減るのは良いことだ。

参考にしたサイト

Google Home で音楽を聴く - Google Home ヘルプ

  • 音楽を手軽に聴けるようにするのが一番の目的だったのでまずここを読んだ。

Google Homeで好きなポッドキャストをスマートに再生する - Qiita

  • Rebuild fmを聴きたかったので。

10分でSlackからGoogleHomeを喋らせるめちゃ速レシピ - Qiita

  • Slackへの投稿方法。Twitterもこれを参考に作った。

Smart Home - Scrapbox

  • 徐々にスマートホームにしていきたいと思っているので読んでいる。他の人が作ったScrapboxは読むハードルが上がる印象があったが1テーマで絞ると非常に見易い。

今後やりたいこと。

  • 簡易なサーバでNode.jsを動かしてGoogle Homeで遊びたい。
  • スクレイピングしたテキストを読みあげてもらいたい。
  • スマートホーム化
  • Google HomeをきっかけにRasberry pi等にも興味が出てきたので触ってみる。

「プロを目指す人のためのRuby入門」を読み終わった。

f:id:nabeatsu1:20171210192706j:plain 一度読んだから汚く移ってる😥

伊藤淳一さん(@jnchito)の「プロを目指す人のためのRuby入門」を終えることが出来ました。 Rubyを触ったばかりのころからQiitaの記事でお世話になっていたのでこの本が発売されるということを聞いた時からやってみたいと思っていました。

学習時の自分のスキル

メディア事業をやっている企業で管理職をやりながら、3月から基本情報の勉強がてらにCASL2の勉強を始めたのがプログラミングの初めての経験。

その後5月から未経験でプログラマとして転職。業務で学習時間を設けてもらった後にRuby on Railsで小規模な社内システムを開発。その後RailsでWebアプリケーションを制作した後にAPIを作って、iOSからそのAPIを利用するためのアプリをSwiftで2月完成目標に開発中。

「プロを目指す人のためのRuby入門」を始めたきっかけ

  • 最低限のRubyの知識は業務の過程で身に付けたものの、わからないことがあった時はその都度周辺の知識を含めて調査という感じで開発を続けていたので、このあたりで一度Rubyの体系的知識を頭に入れておきたかった。

  • テストコードを今まで書かずにコーディングしていて、そろそろテストコードの書き方を勉強しようと思っていた。

  • Railsアプリケーションの開発をしているのにRubyについて場当たり的な対応で得た知識のままでいるのはどうかと思った。

進め方

  • 1度目ということで記載されているプログラムは全て自分の環境でも書いてみる

読んだだけで使えるようにならないのはプログラミングを始めてから身に沁みているので、必ずこれは行うようにしました。

  • 紹介されていたリンク等を1度は目を通す

これは単純に楽しいからです。以前読んだReal World HTTPの時にもそう感じたので今回も紹介されたリンクは積極的に読んでみることにしました。覚えようとはしていないです。

nabeatsu.hatenablog.com

このようなやり方で進めたので、読み終えるまでに2週間程度かかってしまいました。 もっと気楽に1周した方が良かったのかなぁとちょっと思ったりしました。

使用頻度が少ないと事前に記載されている

個人的にはテスト駆動開発を体験出来るということと並んでありがたいと感じたところです。

一通りの機能が同じペースで紹介されていると、全部を覚えなければいけないような気分になって進めるのが億劫になってしまいます。

ですが、この本では使用頻度が少ない、実際の業務ではこういう風に書くことが多い、などという風に説明されているので、読む時に「この書き方はあまり使われないみたいだから写経して動いて納得出来たら次に進もう。」みたいな感じで進めることが出来ました。

知ってはいるし使い方もなんとなくわかるみたいな分野を体系的に学ぶことが出来る

ハッシュ、シンボル、正規表現、繰り返し処理等、Rubyを使ってコーディングをする上で避けては通れないものです。

業務でRubyを書いているので、最低限使えているつもりでしたが、一通り写経して解説を読み、例題としてプログラムを書いていると今までのコードの反省点がいくつも浮かんできました。

特にたくさんのページが割かれていた配列やクラス等、使用頻度が高いオブジェクトに関する体系的な知識は実際のコーディングにすぐに反映されるのではないかなと思います。

テスト駆動開発を体験出来た。

独特な書き方(DSL)のRSpecではなくMinitestというフレームワークを使ってテストコードを書いてから、実際のコードを書き始めます。

Minitestはテストコードを書いた経験がなかった自分でも簡単に感じ、なおかつテストコードの便利さも実感出来るものでした。

業務やプライベートではRailsで開発をしているのでRailsでModelに書く処理にテストコードを書く時はどのように書くのだろうという疑問は残りましたが、これはいずれ自分で学習することにします。

話は逸れますが伊藤さんはRSpecの本の翻訳もされていたそうなので、自分がSwiftのアプリ開発を終える頃に最近のバージョンに合わせた新版を出してくれないかなあと期待しています。

読み終えた後

一度写経して読んだからといって全てを覚えられるはずがないので、配列を使ったコードを書く時にさっと読み直したりということが既に何度かあります。

一度やっただけあってどのあたりに目的の処理が書いてあるか検討が付くので、Rubyを書く時には机の上に置いたままになりそうです…。

当面はこの本やレファレンスを適宜参照しながら今まで書いてきたコードのリファクタリングをしたり、趣味で開発しているRailsのアプリケーションのコードを書きながらRubyに繰り返し触れることで、学習を進めていこうかなと考えています。

おまけ:発売後すぐに学習を始めて良かったこと

SwiftとそのIDEXcodeのアップデート直後に業務で学習と開発をスタートした時に感じた辛さなのですが、本に書かれているコードがバージョンの違いで動かないということが何度もありました。

書かれている内容自体の理解に努めたいのにそれ以前の所で詰まってしまうのは結構なストレスでした。

これはこの本特有の良いところではありませんが、Rubyで現在業務で使っているバージョンで解説もされているのは非常に助かりました。

オライリーのReal World HTTPという書籍を読み終えた。

現在業務で位置情報を利用したWebベースのアプリケーションを製作しているので今Webの基本的な知識を少しずつ深める良い機会だと考え、「Real HTTP World」を読んでみることにした。

どんな内容か

HTTP周辺の知識、なぜHTTPが現在のような形になっているのかを、歴史的な変遷とその仕様を解説しながら解説していく内容。GoでHTTPのそれぞれの規格のクライアントを実装していく章があるがそこをやらなくても読み進められる。

Scrapboxをつかった読書メモ

今ハマっているScrapboxを使って読書メモを残した。個人的な感想をアイコンを使ったコメント風の記述で、読んでいる最中に前提になる知識が不足していた場合やもっと掘り下げていきたいと思った時のログを残したので後から読み返して楽しい。

scrapbox.io

自分にとってのScrapboxとEvernote、それぞれの長所と短所

サービス開始当初から使ってきたEvernote

evernote.com

日本でローンチした2010年からずっとお世話になったEvernote。学生時代からの勉強や読書の記録。Webクリップ、レシピまで何でも突っこんで毎日利用していた。プログラマになってからは言語やフレームワークといったざっくりとした分類の仕方で参考になったドキュメントをどんどんクリップしていた。他のサービスを使ってみるか検討する時もまずEvernoteとの連携がデフォルトで出来るか、またはカスタマイズすれば出来るかというのが前提条件だった。 けれどプログラマとして働き始めてから毎日の開発、勉強の中でログとしてハマったところ、参考になったサイト、どういうきっかけで解決したか、解決出来ずに聞くしかなかったのはどこがわからなかったからか等をEmacsGoogle Drive上にmdファイルで貯めこんでいきはじめた。そのころからEvernoteをあまり使わなくなった。あまり使わなくなってからEvernote以外の選択肢も考えるようになってドキュメント管理ツールを色々と試した。社内のドキュメント共有管理ツールを探してたのも理由の一つ。

Evernoteの良いところと悪いところ

あくまで個人的な感想。

良いところ

  • とりあえずEvernoteに入れたから大丈夫、という状況を作れる。
  • 手軽にクリップ出来る。
  • サイト元が消えてもクリップしていれば見返せる。下世話な話題やエロいのはよく消えるから大事。神。
  • ざっくりとしたスタック、ノートブックのわけかたでも検索したら引っ掛かる。
  • 画像やPDFの文字も検索出来る。神。自分の書いたメモをスキャンすればあとで検索して見つけられる。神。
  • サードのサービスを使えばmarkdownも対応可能。
  • 情報が豊富。コミュニティも親切で活発

(自分にとって)悪いところ。特にEvernoteを使う必要ないなと感じたこと。

  • 重い。
  • 前職からプログラマに転職してから勉強と仕事で手一杯 + 楽しいので下世話な話題やネットで今日話題の~みたいなのに関心がなくなった。
  • エロはDMMで良くない?ってなった。そうじゃないものに関しては一期一会の精神で。
  • ざっくりとした階層の管理をしているのに面倒臭く感じる。→ 管理しても恩恵が少ないからやる気にならない? or 検索すれば良いから?
  • 「あとで整理する」みたいなフォルダが出来る。結局整理しない。自分の性格を鑑みて当然起こるものと想定しておくべきだった。
  • そもそもクリップしたものを見返さない。プログラミングのことに関しては検索して解決してしまうのでEvernoteの中に入れたな、という考えに至らない。
  • 画像やPDFを入れない。
  • 自分の書いたメモをスキャンしても汚すぎて認識しない。
  • markdownのためにサードのアプリケーションやサービスと本家を使い分けるのしんどい。

悪いところはほぼ自分の性格が原因になっているので、一部を除いてEvernoteに非はない。Evernoteが便利で離れられない人がたくさんいるのも納得。

Scrapboxの良いところと悪いところ

scrapbox.io

開発中のログとかはプライベートのプロジェクトを作って完全に移行済み。その他のドキュメントは少しずつ移行しながら利用中。

良いところ

  • 独自の記法が個人的な用途に関してmarkdownより便利で書きやすく、後から見易い。
  • リンクを作ることでドキュメント同士を関連付けられる。あるテーマについて掘り下げたらそれに関する情報が集まる。
  • リンクによって階層で管理する必要がない。リンクを作るだけで良い。
  • 掘り下げた話題、今学習中の言語についてのドキュメントが繋がって楽しい。
  • 関連付けられたテーマについて調べたことを残すのが楽。後から見返すのも楽なので見返す頻度が上がる。
  • コミュニティが大きくなってきている。親切。
  • これから連携やサードパーティが盛りあがっていくかも。
  • 一部部分のクリップならブックマークレットから可能。

(自分にとって)悪いところ。

  • Webベースのみ。公式のMacアプリやiOSアプリはない。iOSアプリは欲しい。
  • 大きくなってきているが今のところEvernote程ではない。
  • たまに記法間違える。
  • markdownに変換するブックマークレットがあるものの、Scrapboxから変換してきました感MAX。

EvernoteからScrapboxへ移行中

自分の用途が

  • 開発、学習中に残すドキュメント
  • 読書メモ
  • ちょっとしたクリップ ぐらいで充分なことに今さら気付いたので移行後も不満なくScrapboxを利用出来ている。Evernoteから他のサービスに移行しようかなと考えている人はぜひScrapboxを一度使ってみてください。

せっかくプログラマになったので勉強してScrapboxみたいな気に入ったサービスに何かしらの貢献が出来るようになりたいなぁ、とぼやいて終わり。

Swift初学者のSwift学習ログ(書籍:本気ではじめるiPhoneアプリ作り)

形式

基本的に詰まった順に列挙。

xcode最新版(9.0)と参考書で使用されているバージョン(8系)との違い

githubと連携させないので業務では必要ない。 必要なら以下参照 Xcodeの概要: ソースコード管理機能を使う

editorのdocument outlineが見当たらない

項目によってあったりなかったりするだけだった。 ただ、メニューバーにあったshow document outlineは項目が消えていた。

実機接続のテストでiPhoneの設定からプロファイルとデバイス管理がない

プロファイルのみになっている。

xcodeで実機の利用ができない(0xE80000E2) - Qiita

Xcode9で実機でのアプリが実行できないとき

を参考に解決。

Optional型の変数を定義した後にアンラップ処理後の変数を利用しない場合の表現がある理由。

厳格なSwiftに対して返り値がなくても問題ないということを宣言するため。

どこよりも分かりやすいSwiftの"?"と"!" - Qiita

enum型が初見でしっくりこなかった

列挙型

// enumの定義
enum Fluit {
  case Apple
  case Orange
}

// Switch文の値にenum値を指定するとenumの値がすべて網羅されているかチェックが入る。処理の記述漏れ対策に良い。
let value = Fluit.Orange
switch value {
case .Apple:
    print("Appleです")
case .Orange:
    print("Orangeです")
}

Clusure、無名関数について

意味のわからないかたまりに見えた。

{(引数:引数の型) -> (戻り値の型) in
    // 処理
    return 戻り値
}

こんなの。Rubyでの記法のProcやラムダと比較しながら理解した。

Swift さくっと確認したい基礎文法 [クロージャ(closure)] - Qiita

特徴と考え方を理解

エラーが起きた箇所を表示させたい

エラーの画面が意味不明。 thread logのみが表示され見辛い。

何かしらの設定を弄ってしまった可能性あり

// Xcodeの設定(カラースキームとかプロジェクトとか)がリセットされるので注意。 defaults delete com.apple.dt.Xcode.LSSharedFileList defaults delete com.apple.dt.Xcode

をターミナルで実行して解決

同じ症状の人 xcode - Thread 1: Stopped at breakpoint 1 - Stack Overflow

Xcodeでコード補完が効かなくなった時に… - Qiita

Auto LayoutのUpdateFramesがadd New Constratintsにない

同じ所にボタンとしてupdateframesがある。 ただクリックできない items of new constraintsを設定出来ないがそれは大丈夫なのか

Type 'ViewController' does not conform to protocol 'UITableViewDataSource'が解決出来ない。

// テーブルの行数を返却する
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            // Todoの配列の長さを返却する
            return todoList.count
        }
        
        // テーブルの行ごとのセルを返却する
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            // Storyboardで指定したtodoCell識別子を利用して再利用可能なセルを取得する
            let cell = tableView.dequeueReusableCell(withIdentifier: "todoCell", for: indexPath)
            // 行番号に会ったToDoのタイトルを取得
            let todoTitle = todoList[indexPath.row]
            // セルのラベルにToDoのタイトルをセット
            cell.textLabel?.text = todoTitle
            return cell
        }

2つのメソッドがボタン押した時のメソッドに入っていたのが問題だった。

Storyboardの制約を使いこなせない

Scrapboxに書いた。 scrapbox.io

参考 StoryboardのAutolayoutの基本 iOSのAuto Layout - Qiita

Rails Carrierwaveでサムネイルのサイズをモデルごとに変更する

RailsでCarrierwaveで画像のアップロード画面を作っていた。当初は1つのモデルでのみ画像をアップロードしたかったのだが、ユーザーのプロフィール作成画面でも画像アップロード機能を実装したくなった。

そこで思い受かんだ解決方法は4つ。

  1. 別のアップローダをgenerateしてそれぞれ別のアップローダをマウントする
  2. 複数のモデルに対応出来るように複数のサイズを作成する
  3. Carrierwaveのresizeをif式で分岐させて処理を分ける
  4. 各モデルに任意のサムネイルサイズの定数を定義。Carrierwaveのアップロードのプロセス中にクラス名と定数を参照させて動的にリサイズする大きさを変更する

このうち1と2はきつい。前者は重複したコードが出来ることになるし後者は無駄な画像が毎回作られることになる。 3か4で迷った。ここは趣味もあると思うけどif式を多用するのに抵抗がある。そこで今回は4を採用してアップローダのコードを変更していった。

モデル

# Userモデル
class User
    THUMBNAIL_SIZE = [100, 100]
    mount_uploader :image, ImageUploader
end

# Photoモデル
class Photo
    THUMBNAIL_SIZE = [700, 700]
    mount_uploader :iamge, ImageUploader
end

アップローダ

マウントするモデルが1つの場合は以下のようにしていた。

# app/uploader/image_uploader.rb
class ImageUploader < CarrierWave::Uploader::Base
    version :thumb do
      process resize_to_fit: [700, 700]
  end
end

複数モデルでthumbのサイズを動的に変更するために以下のように変更

# app/uploader/image_uploader.rb
class ImageUploader < CarrierWave::Uploader::Base

    def dynamic_resize_fit
        size = model.class::THUMBNAIL_SIZE
        resize_to_fit size[0], size[1]
    end

    version :thumb do
      process dynamic_resize_fit
  end
end

これでモデルごとにサムネイルのサイズを変更出来る。 モデルごとにバージョンを用意してサイズやリサイズのメソッド(resize_to_fitやresize_to_limit)を変更したい時はscaleメソッドを変更する等して対応するらしいが今回はその必要がなかったのでここまで。

Rails5 MySQL(innoDB)でutfmb4を使う

"Index column size too large. The maximum column size is 767 bytes"とエラー

入社2ヵ月の新米エンジニアです。ログとして残す。もっと良い解決の仕方があれば教えて欲しいというのも理由の一つ。 Railsのdb:migrate途中でエラー。 エラー内容は以下。

Mysql2::Error: Index column size too large. The maximum column size is 767 bytes.: CREATE UNIQUE INDEX

とか

Specified key was too long; max key length is 767 bytes

原因

直接の原因はdatabase.ymlのencodingをutf8からutf8mb4に変更したこと。 絵文字への対応が変更の目的。

ActiveRecordのString型カラムはvarchar(255)定義され、デフォルトだと最大で767byteまでしか使えない。utf8は1~3byteで1~4byteになるutf8mb4だと767byteをオーバーしてしまいエラーになる。

環境

  • AWSのEC2サーバーの/var/www以下にRails 5.1.2
  • anyanvで管理しているrbenvでruby2.4.1をglobal *devise用のモデルのdb:migrate中に今回のエラーが起きた

解決まで

最大767byteまでしか使えないならその制限を広げてしまえば解決出来るはず。MySQLにはinnodb_large_prefixというオプションが追加されているらしいのでこれをONにしたい。ONにしたら3072byteまで広げることが出来る。それをするためにinnodb_file_formatをAntelopeからBarracudaにしないといけない。

MySQL 5.7.7以降はデフォルトでBarracudainnodb_large_prefixもデフォルトでON。

自分の環境の設定が知りたい時はMySQLにログインして

show global variables like 'innodb%';

上のコマンドを叩くとinnodb云々の設定が確認出来る。

MySQLの設定を変更してdb:migrate

# /etc/my.cnf
innodb_file_format=Barracuda
innodb_file_format_max=Barracuda
innodb_file_per_table=1
innodb_large_prefix=1

1はON。 設定を変更後

$ sudo service mysqld restart

してindexの所でエラーになったためテーブルが作成されている。drop tableしてdb:migrate。 ネットの情報見たらmy.cnfの書き方は様々だがここまででエラー解決してる人が多い。書き間違いがないか確認したりmysqlのエラーログを見たりするも解決できず。

databaseを削除して作成し直してからdb:migrate

drop database hoges;
create database hoges; 

してdb:migrateしたらマイグレーションに成功。

innodb_file_per_tableが原因だった。デフォルトでは1つのテーブルスペースファイルに全てのDBテーブルのデータが格納されるため、データ量が肥大化したらこのファイルも巨大化する。このオプションをオンにするとテーブル単位でスペースファイルが作成される。テーブル単位で別ディスクへの移動やバックアップ、リストアが出来て管理がしやすくなるらしい。ただオンとオフがあるってことは良し悪しがあるってことで、テーブル毎にバイナリファイルを作ってくれるためディスクI/Oが減るメリットの変わりにテーブルがあまりに多いとクラッシュした時にリカバリに時間がかかったりする。

参考になったサイト qiita.com

blog.kamipo.net

blog.kamipo.net

qiita.com