ひびのログ

日々ではないけどログを出力していくブログ

Android チュートリアル写経

ふと Android 開発をしたいなーと思ったので、ひとまずチュートリアルをやってみよう! と思い立ってやってみました。

参考

こちらのサイトを参考にいたしました。

employment.en-japan.com

ソースコード

ちょっとずつ参考サイトから変更しています(一部後述)。

画面レイアウト

Android 画面レイアウト

工夫したところ

  • Start ボタンを連続して押したときに、重複してタイマーが作動しないようにした
  • 状態(State)を別クラスに切り分け、Flux らしきものにした
  • if 文を when 式で記述した

わからなかったところ

  • どのファイルを公開してどのファイルを公開してはいけないのか
  • 一般的なディレクトリ構成
  • 一般的な状態管理方法
  • Singleton or object
    • 今回は実装が楽な object で作りました
  • Activity

感想

わからないことは多々あれど、Android 開発の基礎の基礎がわかったのでよかったなと。

最近は ReactNative とか PWA とかあるので、そちらにも突っ込んでいこうかなと思います。

Redux(っぽいもの)を見よう見まねで実装してみた

私は React を使うときに Redux を使っていたのですが、 その内容を深くは理解していませんでした。

最近 React を使っていないのもあり、難しくなさそうだし(特に何があったわけでもないけど)この機会に Redux を作ってみようと思い、見よう見まねで作ってみました。 作ったのは Vanilla JS 用ですけど。

Redux のソースはほぼ見ていませんので、内容は全然違います。 また、React + Redux しか触ったことがありませんので、本家の Vanilla JS + Redux とは違っていると思います。 型チェックとかも何もしていません。

リポジトリはこちらです。

github.com

ソース解説

lib/createStore.js

唯一の Redux 成分。 これがないと始まらない。 combineReducersとかapplyMiddlewareとかそんな高尚なものはありません。

createStoreに作ったReducer配列と初期値を渡してあげることで、Storeが作られます。

src/ActionCreator.js

ただの関数群です。よしなに実装してください。

Store を渡してあげることでdispatchできるようになるので、typeactiondispatchします。 Middleware を使わない Redux と同様に、非同期処理はここでやればいいと思います。

src/Reducers.js

type``action``stateを受け取って処理をする Reducer の配列です。 これも普通の Redux と変わりません。

src/index.js

つなぎこみ部分です。

まずcreateStoreで Store を取得します。

次にstore.connectで、 View の DOM Element と、それに表示する内容を作る関数を記述します。

そしてリスナーの設定をして終わりです。

最後にrenderしてあげれば初期表示されます。 dispatchすると Reducer が適用された後、勝手に表示されます。

実装してみて

そこまで難しいことはしていないんだなーという印象です。 動くまで2時間、今の形になるまで大体5時間くらいでした。 いい勉強になりました。

Slack bot をBotkitで作成してみる!

私は今プライベートでSlackを使っていて、botを育てている最中です。 だんだん機能が充実してきて、なかなか楽しくなってきました。 どのような機能があるのか、今後ご紹介したいと思っています。

今回はbotを動かすところまで解説したいと思います。



環境

OS:CentOS7
Node.js:9.2

Hello World

まずは、botに「hello」とリプライを送ったら「World」と言うようにしましょう。

Slackの設定(事前準備)

Appディレクトリを「Bots」で検索して「設定を追加」! ユーザー名を入力して「追加する」ボタンを押すと設定画面が出てきます。 そこにAPI トークンがあり、それを使用します。 それ以外はよしなに設定しておいてください。

サーバ側の設定

私は勉強用のVPSが遊んでいたので、それを使用しています。 Herokuとかでも運用できるみたいなので、完全無料がいい方はそちらを使用してください。

ちなみに外部からポートを開ける必要などはありません。

サーバにSSHしたら、Slack bot用のディレクトリを作成して、npm init -yを実行します。 いつものやつです。

するといつものようにpackage.jsonとかができるので、以下のようにBotkitをインストールします。

$ npm init -y
$ npm i -S botkit

botのソースは下記のとおりです。

const Botkit = require("botkit");

// bot controller 取得
const controller = Botkit.slackbot({
    debug: false,
});

// botの起動
controller.spawn({ token: slackToken }).startRTM((err, bot, payload) => {
    // エラーが出たら落とす
    if (err) {
        throw new Error(err);
    }
});

// 指定した単語が、指定の方法で投稿された場合に、コールバックを実行する
controller.hears(["hello"], ["direct_mention"], (bot, message) => {
    bot.reply(message, "World");
});

slackTokenには、先程取得したAPI トークンを記述してください。

そしてnodeコマンドで実行すれば、botが起動します。 Slackでbotに「Hello」とリプライを送ると、「World」と返ってきます。 「Hello」がどこかしらに含まれていれば反応があります。

f:id:tee-talog:20171218224454p:plain

(かなり黒いですね……)

もうちょっと賢くさせる

簡単なやつだけじゃなくてもっと難しいこともしたい! というあなたに。

正規表現

反応する単語を正規表現で指定することもできます。 ただし正規表現リテラルではなく、文字列で指定する必要があるようです。

// 最後にYOとついている投稿があったら反応する
controller.hears(["YO$"], ["ambient"], (bot, message) => {
    bot.reply(message, "YOYO!");
});

キャプチャもできます!

controller.hears(["ドーモ。(.*)です"], ["direct_mention", "direct_message"], (bot, message) => {
    bot.reply(message, `ドーモ。${message.match[1]}=サン。botです。`);
});

定時処理

Botkitだけではできないため、cronパッケージを使用します。

$ npm i -S cron

そして、bot.replyは使用できないため、bot.sayを使用します。 botを起動した際にcronへ登録します。

// botの起動
controller.spawn({ token: slackToken }).startRTM((err, bot, payload) => {
    // エラーが出たら落とす
    if (err) {
        throw new Error(err);
    }
    
    // cronに登録
    new CronJob({
        cronTime: "0 12 * * *",
        onTick: () => bot.say({
            text: "お昼休みは ウキウキ watching",
            channel: "general",
        }),
        start: true,
        timeZone: "Asia/Tokyo",
    });
});

ファイルアップロード時の処理

controller.hearsは、特定の単語のみに反応しますが、もっと広範囲に反応するcontroller.onを使用します。

// ファイルアップロードイベントにリスナ登録する
controller.on(["file_share"], (bot, message) => {
    bot.reply(message, "ファイルがアップロードされました。”);
});

ちなみに

controller.hearscontroller.onの特化したもの、
bot.replybot.sayの特化したものと捉えています。


その他詳しくは、Botkitの公式ドキュメントを参照してください。

github.com

messageオブジェクトをのぞいてみると面白いと思います。

「コメント」と「コメントアウト」と「コメント化」の違い

プログラミングをしているときにわからないことがありググったときに、 「コメント」を使用すべき箇所で「コメントアウト」という単語が使用されていることがままあります。

プログラミングにおいて、「コメント」と「コメントアウト」、そして「コメント化」はそれぞれ違う意味を持ちます。

「コメント」とは

「コメント」とは、 「ソースコード中にメモなどを記述するために、特別な構文等を使用して記述した、 プログラムとして解釈されない文字列、またその内容」 です。

英語の「comment」の「注釈・解説」という意味そのままです。

コメントを記述するための「コメント構文」を使用して書かれている文字列全般を指します。

コメント構文には、

  • C/C++やJava等では「//」や「/* ~ */」など
  • RubyやPython等では「#」など

が用いられます。
こちらは、言語によって定められています。

ここで言いたいことは、「コメント」は単なる「文字列」ということです。

「コメントアウト」とは

こちらは、 「コメント構文を使用して、ソースコードをコメントに変え、 一時的にプログラムを無効化すること」 を言います。

ソースコードをコメントにするとプログラムとして解釈されないため、 ソースコードを削除したように動かすことができます。

デバッグを行うときによく利用されています。

「この行を削除したらどうなるんだろう? でも削除してしまうと戻せなくなってしまう……」
そんなあなたにコメントアウト!
簡単に削除した動きが実現できます!

英語の「out」がくっついたことにより、「コメントによって取り除く」といった意味になります (プログラムの動きの外に出すイメージです)。

言いたいことは、「コメントアウト」は「自分が行う動作」です。

「コメント化」とは

「コメント化」と言うこともあります。 これは、「文字列がコメントになる」という意味です。

よく「コメント化する」というように使われます。

これは「状態の変化」です。

まとめ

  • 「コメント」は「文字列」
  • 「コメントアウト」は「自分が行う動作」
  • 「コメント化」は「状態の変化」

ですので、これらはすべて違うものです。

間違えないように注意しましょう!

例文

  • コメントにはプログラムの意図を書きましょう。
  • ここがコメントになっていないのでエラーが発生している。
  • コメントアウトしてデバッグしてみよう。
  • コメントアウトしているところを元に戻そう。
  • この行はコメント化してください。

EditorConfigをVimに導入したら結構便利だった

便利だったので布教してみます。

導入のきっかけ

Vue.jsを勉強してみようと思って、vue-cliでプロジェクトを作ってみたところ、2スペースインデントに苦しめられたので。

.vimrcいじるほどではないなーと感じたんですが、作ったプロジェクトの中に.editorconfigがあるのを発見して、「ならば導入してみよう」となりました。

EditorConfigってそもそも何?

エディタの設定をいじることなく、独自の設定ファイルを記述することで、プロジェクトごとのフォーマットの設定ができるという画期的な仕様。

大抵はエディタに内蔵されていたり、プラグインとして提供されていたりする。

詳しくは公式へGo!

editorconfig.org

Vimへの導入方法

dein.vimを使っています。

call dein#add('editorconfig/editorconfig-vim')

以上です! 簡単!

その他のエディタ

内蔵されていたりプラグインがあったりします。詳しくは公式へ。 手書きのロゴがとってもかわいい!

…………Eclipse? 知らんな。

使い方

.editorconfigファイルがあれば、勝手に読み込まれてその設定が使用されます。

自分で定義しておくことも可能です。というかしたほうがいいです。

使ってみた感想

タイトルにもあるけど、結構便利。

vue-cliなど、テンプレートをダウンロードしてきてそのまま使うならほぼ必須だと思います。 自分はタブインデント派なので、大抵のJSプロジェクトで設定が必須です。

マイ.editorconfig

これをホームディレクトリに配置しています。 上のディレクトリを見に行かないため、root = trueを設定したファイルを置いています。

大抵の.editorconfigには設定してあるとは思いますけどね。

github.com

懸念事項

深いディレクトリでVimを起動すると、親のディレクトリに.editorconfigを探しに行くので、Vimの起動が遅くなる?(未検証)