読者です 読者をやめる 読者になる 読者になる

ushumpei’s blog

生活で気になったことを随時調べて書いていきます。

¥eあるいはedit

 mysqlの対話環境でちょっと長い処理を実行したくなった時のメモです。

 mysqlコマンドを実行すると対話環境が起動します。ただ改行を含んだクエリを書こうとすると、どこか間違えた時に書き直すのが非常に面倒です。

 そういった時は¥eまたはeditコマンドを使うと便利です。コマンドを実行するとエディタが起動し直近に実行したクエリが表示されます。編集を行い保存して閉じるとコマンドを抜けて対話環境に戻ります。あとは;を入力してエンターキーを押せば内容が実行されます。毎回エンターキーを押すのも面倒な場合は、¥e;で実行します、この場合はエディタを閉じたら即時実行されます。

 開くエディタは選べるようです。私の環境ではデフォルトはviでした。これは環境変数EDITORで設定できます。(export EDITOR=vimとか設定しときました)

 調べたいクエリがあった時に、

  1. mysql> ¥e;実行
  2. vimが開くので挿入コマンド:a!でコピーしてきたクエリをペーストする
  3. 適宜修正して:wqvimを終了する
  4. 結果を確認し、必要なら1に戻る

 という感じで使っていました。

 ちなみに¥eを実行した時に編集しているファイルは/tmp以下に作成されていることが確認できました、しかしこれはエディタを閉じると削除されるようです。ちゃんと取っておきたいなら保存した方がいいと思います。(viなら:w ~/hogehogeなど)

感想

 rails consoleでもeditコマンドが使えるみたいですirbはダメか、コマンドが違うようです?)。他の対話環境ではどうなんでしょうか?

追記: 2017/01/13 - 今手元にあるrails 5で試してみると、editコマンドは使えないみたいです。動作が確認できていた環境はすでに手を離れてしまったので再確認できません。。。何かわかり次第追記します。

git logの折り返し

 gitのlogdiff表示時の、文字列の折り返しの切り替え方をメモします。

 自分の環境(mac 10.12terminalgit version 2.8.4 (Apple Git-73))ではデフォルトで折り返しがされていたのですが、以下の指定で折り返しが無効になりました。

折り返し無効

$ git config --global core.pager "less -S"

折り返し有効

$ git config --global core.pager "less -r"

 (デフォルトで有効だったので、折り返し有効のコマンドは未確認です。。。)

 git log --graph --decorateなどでログを見たい場合は、折り返さない方が見やすい気がします。

 ちなみにcore.pagergit loggit diffで表示するときの出力コマンドを指定しているそうで、lessSオプションをつけて折り返しの制御が行われているようです。catとかも指定できるようです。moreは私の環境では文字化けしました。

アロー関数(Arrow function)の書き方色々

 アロー関数は引数や戻り値の種類によって色々な書き方ができます。分割代入を使うことで柔軟な関数をシンプルに宣言できてとても気持ちいです。

 基本的な書き方から、やや直感的ではない書き方まで、メモしていこうと思います。

ざっくり

 アロー関数の記述方法は、引数に関しては、引数なし、引数1、引数N、引数オブジェクトリテラルによる分割代入、の4種類があります。関数の処理部分に関しては波括弧、括弧なし、丸括弧の3種類があります。

  • 引数1、括弧なし
  • 引数N、丸括弧
  • 引数オブジェクトリテラルによる分割代入、丸括弧
  • 引数なし、波括弧

 を並べてみます。

引数1、括弧なし

 引数が1のときは、引数の括弧は省略できて、右側が評価され戻り値が返ります。Promiseのcatchとかすっきりします。

const factorial = n => (n > 0) ? n * factorial(n-1) : 1;

引数N、丸括弧

 引数N個は単純にfunctionのときと同じように並べるだけです。戻り値にオブジェクトリテラルを返したいときに丸括弧を使うとすっきりです。

let projection = (a, b) => ({ 
  x: (2 * a) / (1 + a * a + b * b),
  y: (2 * b) / (1 + a * a + b * b),
  z: (-1 + a * a + b * b) / (1 + a * a + b * b),
});

引数オブジェクトリテラルによる分割代入、丸括弧

 上の例と近いです。ただ引数個数が頻繁に変わる可能性がある場合この記法がいいようです。ですが、個人的に好きなので何でもかんでもこれで書きたいです。Reactの純粋な関数スタイルのコンポーネントを書いたりするとき便利です。

const Deco = ({ deco, children }) => (
  <div>
    {deco + children + deco}
  </div>
);

 呼び出すときは引数で代入しているプロパティをもったオブジェクトを渡せば大丈夫です。引数いっぱいなのは嫌だけど、オブジェクトまるまる渡したら何されるかわからない、といった不安を綺麗に取り去ってくれます。

引数なし、波括弧

 グローバルなオブジェクトに対して何かしたいときに使う、気がします。波括弧なので複数行書くことができます。

const values = () => {
  const inputs = [...document.querySelectorAll('input')];
  const values = inputs.map(input => input.value)
  return values;
};

感想

 戻り値に関して補足です。1行で済む場合は括弧なしか丸括弧、複数行必要なときは波括弧でいいと思います。

 引数オブジェクトリテラルによる分割代入は、修正による影響を少なくできるし、オプションのようなものを渡すことが簡単にできるのでかなり好きです。

 説明の中で複数行とか言っていますが、宣言とか式とか、ちゃんとした言葉をいい加減覚えなければいけないなと思います。

Reactコンポーネントを純粋な関数で書こう

 Reactコンポーネントの書き方は色々あり、es6を使う場合の選択肢は以下の2つがあると思います;

  • クラス
  • 純粋な関数

クラス

 classの構文を使う場合、React.Componentクラスを継承してコンポーネントを定義します。

class App extends React.Component {
  render() {
    return (
      <div className="app-component">
        {this.props.hello}
      </div>
    );
  }
}

純粋な関数

純粋な関数としてコンポーネントを定義する場合、JSX記法で書いたDOMを返すような関数を記述します。なかなか直感的に書くことができます、親コンポーネントから渡されるpropsも引数として宣言します。

const App = ({ text }) => (
  <div className="app-component">
    {text}
  </div>
);

違いは?

 ざっくり言うと状態(state)を持つか持たないかのようです。クラス構文であればstateを持ったコンポーネントを作ることができますが、純粋な関数のコンポーネントではできません。純粋な関数のコンポーネントは引数(props)のみ使用し、実際それはコード上で関数の引数として表現されます。(2つの例でのtextの扱いの違いのような感じです)

 また純粋な関数のコンポーネントではrefが使えないそうです。その理由は説明によるとbacking instanceを持っていないから、だそうです。 静的コンポーネント、というイメージでしょうか。申し訳ないですが詳しくはこちらを参照くださいStateless functions

例:コンストラクタ内でstateを定義する。

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      ...
    };
  }
  ...
  render() {
    ...
  }
}

感想

 reduxチュートリアルで初めてStateless functionで書かれたReactコンポーネントを見ましたが、状態管理をreduxに任せる立場からするとそれは当然なんだろうな、と今になって思いました。

 ReactのStatelessなコンポーネントを作ることは、新しいhtmlのタグを定義することに近い気がしました。

オブジェクトリテラル内でのスプレッド演算子

 こんにちは。

 スプレッド演算子(spread operator)がオブジェクトリテラル内で使えませんでした。babel-preset-es2015入れとけばなんとかなるだろうと思っていたのですが、babel-preset-stage-2が必要みたいです。ECMAScriptの仕様策定方法を知らないのでstage-2の意味はわからないですが、なんかよさそうなものがあったので読もうと思います。

 ざっくりとした設定方法をメモしておきます。

インストール

npm install --save-dev babel-core babel-loader babel-preset-es2015 babel-preset-stage-2 webpack

webpack.config.jsはこんな感じになりました。

module.exports = {
  entry: './index.js',
  output: {
    path: __dirname,
    filename: 'bundle.js',
  },
  module: {
    loaders: [
      {
        test: /\.js[x]?$/,
        exclude: /node_modules/,
        loader:  'babel',
        query: {
          presets: [
            'es2015',
            'stage-2',
          ],
        },
      },
    ],
  },
}

以下動くかどうか確認のためindex.jsindex.htmlを用意。

index.js

let obj1 = { 'before': '...oh' };
alert(JSON.stringify(obj1,null,2));
let obj2 = { ...obj1 , 'after': 'oh!' };
alert(JSON.stringify(obj2,null,2));
// ひどいサンプル

index.html

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8" />
  <title>Spread</title>
</head>
<body>
  <div id="root"></div>
  <script type="text/javascript" src="./bundle.js"></script>
</body>
</html>

webpackでビルド実行

./node_modules/.bin/webpack --colors --progress

 index.htmlをブラウザで開くとアラートが2回表示されます。オブジェクトリテラルが再代入なしで更新されているのが、なんとなくわかるかと思います。もっとプロパティが多いと、魅力が伝わる気がします。

感想

 ちゃんとした例を書かないとダメですね。あとECMAScriptに関しても知っておきたいです。