随時更新!! Xcode shortcutまとめ

Xcode

--- shortcut
New Project command + shift + n
New Playground option + command + shift + n
Tool Bar command + option + t
Navigation command + 0
Debug Area shift + command + y
Utility Area command + option + 0
Modify Indentation ctrl + i
Grep File command + shift + o
Utility Area の object library の grep command + option + ctrl + 3
Go Back commad + ctrl + ←
Show Standard Editor command + enter
Show Assistant Editor command + option + enter

Simulator

--- shortcut
Toggle Software keyboard command + k

reference from

https://www.amazon.co.jp/dp/4798048704

随時更新!! AWS S3 cli のよく使うコマンドまとめ

s3にあるオブジェクトの総量を見たい時

$ aws s3 ls --summarize --human-readable --recursive s3://<backet name>

---
Total Objects: 21887
   Total Size: 2.7 GiB

s3にディレクトリを同期

$ aws s3 sync <local path> s3://<s3 backet> --exact-timestamps 

reference from

http://www.task-notes.com/entry/20150904/1441335600 https://docs.aws.amazon.com/cli/latest/reference/s3/index.html

随時更新!! やってそうでやってなかったchromeのデバッグ手法

chromeでdebugするときどういう機能を使ってデバックしていますでしょうか?自分は基本、debugger とconsoleくらいしか使っていません。この記事では、目についたやってなかったchromeデバッグ手法を随時追記していきます。

条件的breakpoint

source panel で行番号のところを右クリックすると Add conditional breakpoint というボタンが出てくるので、そのボタンを押すと、表現を記述できる。そうするとその表現がtrueのときにbreakpointが発火される。

https://gyazo.com/6c029f5d444ee9d319caf8b2ea296324

reference from

https://javascript.info/debugging-chrome https://developers.google.com/web/tools/chrome-devtools/

知ってそうで知らなかったJavascript

最近いろいろvueとかreactとか触っているときにそもそも自分はJavascriptがわかっているのかと不安になったので、以下のチュートリアルをやってみた。なんとなくわかるけど、明確に言語化できていなかったところをまとめた。

javascript.info

Strict mode

what is strict mode

長い間Javascriptは、互換性の問題が発生することなしに、発展してきた。新しい機能・仕様が言語に追加されても、古い機能は変わらなかった。このメリットは、既存のコードを壊さないことである。だがデメリットとして、過去のJavascriptの開発者のミスが言語にずっと残ってしまうという問題があった。それを解決するのが、strict mode である。

2009年、ES5がリリースされた。そのとき新しい機能の追加や既存のコードの修正が行われた。それ以前のコードを動かすため、デフォルトだとES5リリース時の殆どの改善はオフになっている。したがって、ES5で改善された仕様を有効化するために、use strictを使う必要がある。

'use strict'
num = 5; // the variable "num" is created if didn't exist
alert(num); // 5

ok

'use strict'
num = 5; // the variable "num" is created if didn't exist
alert(num); // 5

エラーになる。

一言

どうせ今の時代( 2018/04 )ES6で書いてコンパイルするから過去のコードを読むために知っておく必要はあるが、use strictを使うことはないだろうと感じた。どうやら、ES6は最初からstrict modeになっているらしい。

stackoverflow.com

colorOrange or COLOR_ORANGE, 定数の命名におけるcamel caseとsnake caseの違い

snake case

const COLOR_RED = "#F00";
const COLOR_GREEN = "#0F0";
const COLOR_BLUE = "#00F";
const COLOR_ORANGE = "#FF7F00";


let color = COLOR_ORANGE;
alert(color); // #FF7F00

camel case

const pageLoadTime = /* time taken by a webpage to load */;

定数ということは値が決して変わらない(再代入されない)ということだ。だが、ものによっては実行まで値がわからないものがある。 したがって、実行前から値がわかっていて今後その値が変わらないものと、実行時に値が決まり今後その値が変わらないもので、COLOR_ORANGEcolorOrange で記法を分ける。

`` backtickについて

ES6以前は、文字列内で変数展開ができなかったので、以下のように書くことしかできなかった。

let hoge = "hoge"
'foo' + hoge + 'fuga'

だが、ES6になって、以下のように変数展開できるようになった。

`foo${hoge}fuga`

一言

知ってた。

null とundefinedとNaN

null

何もない、空という意味。"nothing", "empty" or "value unknown"

undefined

値が定義されていない。"value is not assigned"

もし変数が宣言されていて、何も値が代入されていなければ、その変数はundefinedになる。

let x;
alert(x); // shows "undefined"

NaN

計算のエラー。

alert( "not a number" / 2 + 5 ); // NaN

typeof

typeof演算子は、引数の型を返す。

typeof null // "object"

nullの型判定でobjectが返るのは、Javascriptの仕様のエラー。

Number(undefined) // NaN
Number(null) // 0
Number(true) // 1
Number(false) // 0
Number("hoge") // NaN
Number("") // 0

false, null, "" の場合のみ0, trueで1, "hoge", undefined だとNaNになる。

Boolean(0) // false
Boolean(null) // false
Boolean(undefined) // false
Boolean(NaN) // false
Boolean("") // false
// any other value becomes true

Booleanだと基本空っぽいもの( 0, "", null, undefined, NaN )は、falseになる。ただ、Boolean("0") とかだと文字列になるからtrueが返る。

null とundefined の、0との比較

nullとundefinedの比較

alert( null == undefined ); // true
alert( null === undefined ); // false

何にも型変換しないので

nullと0との比較

alert( null > 0 );  // (1) false
alert( null == 0 ); // (2) false
alert( null >= 0 ); // (3) true

なぜ(1)(2)がfalseになっているのに、(3)だけtrueになっているのか

理由

== と、>, <, >=, <= は動きが違うから。>, <, >=, <= は、null を数字に変換して0にして比較するけど、== は型変換しないから。

undefined と0の比較

alert( undefined > 0 ); // false (1)
alert( undefined < 0 ); // false (2)
alert( undefined == 0 ); // false (3)

(1)と(2)がfalseなのは、undefinedがNaNに変換されるから。 そして、NaNはすべての比較演算子でfalseを返す。 最後にfalseになっているのは、== でundefinedとイコールになるのはnullだけだから。

文字列と数値の変換

alert( 1 + '2' ); // '12' (string to the right)
alert( '1' + 2 ); // '12' (string to the left)
alert(2 + 2 + '1' ); // "41" and not "221"
alert( 2 - '1' ); // 1
alert( '6' / '2' ); // 3

文字列の足し算をすると片方の値は文字列に変換される。 引き算割り算は数値計算になる。

counter++, と ++counterの違い

  • increment/decrement は、変数にのみ使える。したがって、5++ みたいなのはエラーになる。
let counter = 0;
counter++;
++counter;
alert( counter ); // 2, the lines above did the same
let counter = 0;
alert( ++counter ); // 1

先に1が足される

let counter = 0;
alert( counter++ ); // 0

次のループで1が足される。

演算子の優先順位

developer.mozilla.org

演算子には優先順位があり、それにしたがって演算される。

a = 1 + 2, 3 + 4, 5 + 6 // a = 3, 7, 11
alert(a) // 11

カンマで複数の式を評価できるが、結果として返るのは、最後の値。 カンマは、= より順位が低い。

比較演算子

alert('a' > 'A'); // true
alert( 'Z' > 'A' ); // true
alert( 'Glow' > 'Glee' ); // true
alert( 'Bee' > 'Be' ); // true

大文字のAは小文字のaとはイコールじゃない。aの方が後。理由は小文字は内部のencoding table(Unicode)では、大文字より後にあるから。

alert( '2' > 1 ); // true, string '2' becomes a number 2
alert( '01' == 1 ); // true, string '01' becomes a number 1
alert( true == 1 ); // true
alert( false == 0 ); // true

== と === の違い

let a = 0;
alert( Boolean(a) ); // false

let b = "0";
alert( Boolean(b) ); // true

alert(a == b); // true!

上記2つの比較はtrueになる。なぜなら文字列が0に変換されるから。 ただ下記はfalseになる。

alert(a === b); // false!

== は、型を変換した値同士の比較だけど、=== は、型を変換することなく比較をして真偽値を返す。

alert( 0 == false ); // true
alert( '' == false ); // true
alert( 0 === false ); // false, because the types are different

論理演算子

  • ORは、trueをさがしにいく
alert( true || true );   // true
alert( false || true );  // true
alert( true || false );  // true
alert( false || false ); // false
result = value1 || value2 || value3;

左から実行していき、それぞれの項が、booleanに変換される。もしtrueがあれば、booleanに変換前の値を返す。すべてfalseだったら、最後の項を返す。

let x;

true || (x = 1);

alert(x); // undefined, because (x = 1) not evaluated
let x;

false || (x = 1);

alert(x); // 1
  • ANDは、falseをさがしにいく
alert( true && true );   // true
alert( false && true );  // false
alert( true && false );  // false
alert( false && false ); // false
result = a && b;
result = value1 && value2 && value3;

左から実行していき、それぞれの項が、booleanに変換される。もしfalseがあれば、booleanに変換前の値を返す。すべてtrueだったら、最後の項を返す。

// if the first operand is truthy,
// AND returns the second operand:
alert( 1 && 0 ); // 0
alert( 1 && 5 ); // 5

// if the first operand is falsy,
// AND returns it. The second operand is ignored
alert( null && 5 ); // null
alert( 0 && "no matter what" ); // 0
  • ANDは、ORの前に実行される
alert( 5 || 1 && 0 ); // 5

1 && 0 -> 0を返す。 5 || 0 -> 5を返す。

loop

while for のcounter 変数のスコープ

ループ内がスコープ範囲。

for (let i = 0; i < 3; i++) {
  alert(i); // 0, 1, 2
}
alert(i); // error, no such variable
let i = 0;

for (i = 0; i < 3; i++) { // use an existing variable
  alert(i); // 0, 1, 2
}

alert(i); // 3, visible, because declared outside of the loop

break

最初で条件判定したいときは、while() 最後で条件判定したいときは、do while() 中間で条件判定したいときは、while(true) + break

let sum = 0;

while (true) {

  let value = +prompt("Enter a number", '');

  if (!value) break; // (*)

  sum += value;

}
alert( 'Sum: ' + sum );

continue

for (let i = 0; i < 10; i++) {

  // if true, skip the remaining part of the body
  if (i % 2 == 0) continue;

  alert(i); // 1, then 3, 5, 7, 9
}

Labels for break/continue

深いネストからbreakするのに使える

labelName: for (...) {
  ...
}

for (let i = 0; i < 3; i++) {

  for (let j = 0; j < 3; j++) {

    let input = prompt(`Value at coords (${i},${j})`, '');

    // what if I want to exit from here to Done (below)?

  }
}

alert('Done!');

単なるbreakだと一階層上にbreakするだけで、グローバルにはbreakできない。

outer: for (let i = 0; i < 3; i++) {

  for (let j = 0; j < 3; j++) {

    let input = prompt(`Value at coords (${i},${j})`, '');

    // if an empty string or canceled, then break out of both loops
    if (!input) break outer; // (*)

    // do something with the value...
  }
}
alert('Done!');
  • continueも上記のような使い方が可能。
  • labelはgotoではないので、以下のような使い方はできない。
break label;  // jumps to label? No.

label: for (...)

function

function name(parameters, delimited, by, comma) {
  /* code */
}

関数

  • 関数は関数外の変数にアクセスできる。でも逆は無理。
  • 関数は値を返す。でも値がなかったら、undefined を返す。

default 値の設定

function showMessage(from, text = "no text given") {
  alert( from + ": " + text );
}

showMessage("Ann"); // Ann: no text given

デフォルト値のサポートは古いJavascriptではされていなかったので、以下のようなコードを使って再現していた。

function showMessage(from, text) {
  if (text === undefined) {
    text = 'no text given';
  }

  alert( from + ": " + text );
}
function showMessage(from, text) {
  // if text is falsy then text gets the "default" value
  text = text || 'no text given';
  ...
}

return

function doNothing() {
  return;
}

alert( doNothing() === undefined ); // true

何も返さない return は、return undefined と同じ。( undefinedを返してるのと同じ )

関数定義と関数表現

関数定義

function sayHi() {
  alert( "Hello" );
}

関数表現

let sayHi = function() {
  alert( "Hello" );
};
function sayHi() {
  alert( "Hello" );
}

alert( sayHi ); // shows the function code

上記を実行すると、

function sayHi() {
  alert( "Hello" );
}

が返る。

let sayHi = function() {
  alert( "Hello" );
};

alert( sayHi ); // shows the function code

上記を実行すると

function () {
  alert( "Hello" );
}

が返る。

sayHi というのは、() がついてないので、関数を実行したわけではない。多くのプログラミング言語では関数名で実行されるが、Javascriptはそうではない。

Javascriptでは、関数も値なので、値として対処しなければならない。

上記の例が示しているのは、sayHi という変数に、文字列でソースコードが代入されているということである。

sayHi() という風にすればコードを実行できる。ただそれでも値なので、以下のようなことが出来る。

function sayHi() {   // (1) create
  alert( "Hello" );
}

let func = sayHi;    // (2) copy

func(); // Hello     // (3) run the copy (it works)!
sayHi(); // Hello    //     this still works too (why wouldn't it)

上記で起こっていることとしては、まず関数が作られ、sayHiという変数に代入される。(2)で、sayHiという変数の中身(ソースコード)がfuncという変数にコピーされる。もし、func = sayHi() だったら sayHi() の実行結果が funcに代入される。sayHiのソースコードではなく。

また、これは以下のように書いても同様の動きをする。

let sayHi = function() { ... };
let func = sayHi;

;を関数定義につけなくていいのはなぜか?

function sayHi() {
  // ...
}

let sayHi = function() {
  // ...
};

if {}, for {}, と同様に、code blockとして、function sayHi() {} をあつかっているから。

関数表現の方は、コードブロックではなく、値を変数に入れている文なので ; が必要。

コールバック

値として関数が、使われる例。

function ask(question, yes, no) {
  if (confirm(question)) yes()
  else no();
}

function showOk() {
  alert( "You agreed." );
}

function showCancel() {
  alert( "You canceled the execution." );
}

// usage: functions showOk, showCancel are passed as arguments to ask
ask("Do you agree?", showOk, showCancel);

この例でいうところの ask がコールバック関数・コールバックと呼ばれるものである。

function ask(question, yes, no) {
  if (confirm(question)) yes()
  else no();
}

- function showOk() {
-   alert( "You agreed." );
- }

- function showCancel() {
-   alert( "You canceled the execution." );
- }

- // usage: functions showOk, showCancel are passed as arguments to ask
- ask("Do you agree?", showOk, showCancel);

+ ask(
+   "Do you agree?",
+   function() { alert("You agreed."); },
+   function() { alert("You canceled the execution."); }
+ );

上記のように短く書くこともできる。 ask(...) の中で呼ばれている関数は名前が無い、無名である。 これらの関数は ask(...) の外からはアクセスできない。なぜなら変数に代入されているわけではないから。

関数表現と関数宣言の違い

関数表現は、その関数が実行されて使用可能になるときに作られる。 それに対して関数宣言はすべてのscript/code blockから使用可能である。Javascriptはscriptを実行する前に関数宣言を探しに行き関数を作り、それからscriptを実行する。

sayHi("John"); // Hello, John

function sayHi(name) {
  alert( `Hello, ${name}` );
}
sayHi("John"); // error!

let sayHi = function(name) {  // (*) no magic any more
  alert( `Hello, ${name}` );
};

逆に言えば関数宣言は、そのblock内からじゃないと使用できない。

let age = 16; // take 16 as an example

if (age < 18) {
  welcome();               // \   (runs)
                           //  |
  function welcome() {     //  |
    alert("Hello!");       //  |  Function Declaration is available
  }                        //  |  everywhere in the block where it's declared
                           //  |
  welcome();               // /   (runs)

} else {

  function welcome() {     //  for age = 16, this "welcome" is never created
    alert("Greetings!");
  }
}

// Here we're out of curly braces,
// so we can not see Function Declarations made inside of them.

welcome(); // Error: welcome is not defined

それに対して関数表現だと、

let age = prompt("What is your age?", 18);

let welcome;

if (age < 18) {

  welcome = function() {
    alert("Hello!");
  };

} else {

  welcome = function() {
    alert("Greetings!");
  };

}

welcome(); // ok now

上記のように、変数に代入されているので、block外からも使用できる。

結局どっちを利用したらいいのか。

上記に合わせてケースバイケース

Arrow関数

  • (...args) => expression は、評価して結果を返す。
  • (...args) => {expression} は、bracketのおかげで複数の文を関数内に書くことができる。ただなんらか値を返す必要がある。
let func = (arg1, arg2, ...argN) => expression

は、以下と一緒

let func = function(arg1, arg2, ...argN) {
  return expression;
}

Reference from

https://javascript.info https://developer.mozilla.org/ja/docs/Web/JavaScript/Strict_mode

Automated testing with mocha / mocha 触ってみた

install

Install with npm globally:

$ npm install --global mocha
npm install --save-dev mocha

mocha とは

Mocha is a feature-rich JavaScript test framework

テスト全体を取りまとめて管理したり、画面に表示したりするためのもの

chaiとの違い

chaiとは

Chai is a BDD / TDD assertion library for node and the browser that can be delightfully paired with any javascript testing framework.

テスティングフレームワークと合わせて使うアサーションライブラリ。アサーションは、個々のテストの判定を行いその結果を返すための機能。

chaiとmochaの違いは、chaiアサーションのためのライブラリだけど、mochaはテスティングフレームワーク

development example

累乗(jsでいう**)の関数を開発する。

1, テストととして仕様を書く

describe("pow", function() {

  it("raises to n-th power", function() {
    assert.equal(pow(2, 3), 8);
  });

});
  • describe("title", function() { ... })

    • 仕様としての関数を書く
  • it("title", function() { ... })

  • assert.equal(value1, value2)

    • その実装が期待通り動いているか確認する

→ 落ちる

2, 実装を書く

function pow() {
  return 8; // :) we cheat!
}

→ 成功

3, usecaseを追加する

describe("pow", function() {

  it("raises to n-th power", function() {
    assert.equal(pow(2, 3), 8);
  });

+  it("3 raised to power 3 is 27", function() {
+    assert.equal(pow(3, 3), 27);
+  });

});

4, 2に戻る

function pow() {
-   return 8; // :) we cheat! 
+  let result = 1;
+
+  for (let i = 0; i < n; i++) {
+    result *= x;
+  }
+
+  return result;
}

5, 1→4を繰り返す。

Goal

<!DOCTYPE html>
<html>
<head>
  <!-- add mocha css, to show results -->
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/mocha/3.2.0/mocha.css">
  <!-- add mocha framework code -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/mocha/3.2.0/mocha.js"></script>
  <script>
    mocha.setup('bdd'); // minimal setup
  </script>
  <!-- add chai -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/chai/3.5.0/chai.js"></script>
  <script>
    // chai has a lot of stuff, let's make assert global
    let assert = chai.assert;
  </script>
</head>

<body>

  <script>
    function pow(x, n) {
      if (n < 0) return NaN;
      if (Math.round(n) != n) return NaN;

      let result = 1;

      for (let i=0; i < n; i++) {
        result *= x;
      }
      return result;
    }
  </script>

  <!-- the script with tests (describe, it...) -->
  <script src="test.js"></script>

  <!-- the element with id="mocha" will contain test results -->
  <div id="mocha"></div>

  <!-- run tests! -->
  <script>
    mocha.run();
  </script>
</body>

</html>
describe("pow", function() {
  it ("for nagative in the result is NaN", function() {
    assert.isNaN(pow(2, -1));
  });

  it ("for no-integer n the result is NaN", function() {
    assert.isNaN(pow(2, 1.5));
  });

  describe("raises x to power n", function(){
    function makeTest(x) {
      let expected = x * x * x;
      it (`${x} in the power 3 is expected`, function(){
        assert.equal(pow(x, 3), expected)
      });
    }

    for (let x = 1; x <= 5; x++) {
      makeTest(x);
    }
  });
});

まとめ

  • Behavior Driven Development (BDD) では、実装 (implementation) の前に仕様 (specification) が来る。そして最後に仕様とコードが揃う。

    • 仕様(テスト)を書く→落ちる→その落ちた仕様の実装 というのをやっていく。
  • よくテストされたコードは、良い設計につながる

    • 何をやっているかわかりやすい、入力と出力が明確

感想

  • mocha & chai は、js 版rspecみたいな感じかな。
  • test(仕様)→実装 という開発手法は始めてだったので新鮮だった。ただちょっと開発が遅くなりそうだと思った。
  • もとが英語記事なので、日本語の語の定義が難しかった。

reference from