FM牛鍵屋本舗

プログラマ(弱)の日々精進系ブログ

メソッド引数ではハッシュのブレースを省略できるよ!!!

Rakeのtask定義で本当に不思議だったこと

パーフェクトRubyの12章にRakeの説明が載っていて、つらつらと学んでいたんですが、ふとひっかかったことが。

task :hoge => :moge

書き方だけ見るとHashだなあ、と思ったんですが、{}がない。これは一体どういうことだろうとirbで以下を打ってみても

irb(main):002:0* my_hash = :hoge => :moge

ファッキンエラー。

SyntaxError: (irb):2: syntax error, unexpected =>, expecting end-of-input
my_hash = :hoge => :moge
                  ^
    from /usr/local/bin/irb:11:in `<main>'

シンボルに=>メソッドが定義されているのだろうかと見てみても、ううんもしやRake独自?とドキュメントを漁ってみてもわからず。

もしやメソッド引数では上記の書き方が出来るのか?と試してみたら

def some_method(something)
  something[:hoge]
end

puts some_method :hoge => :moge # => moge

ビンゴーーーー

改めて本を読み返してみたら、キーワード引数においてブレース省略できるって書いてありました。

言語仕様(メソッド呼び出し)言語仕様(ハッシュ式)にもちゃんと書いてありますね。

メソッドの引数の末尾に要素が1つ以上のハッシュを渡す場合は、{, }を省略することができます。ただし、obj[...] 形式のメソッ ド呼び出しと配列式では、要素全体がハッシュの場合に限り、 {, }を省略することができます。

余計な時間使っちゃった…

Deferred模索中。とりあえずスペルややこしい。

今日試みたjQueryのDeferred

ECMA6からPromiseが言語仕様に含まれているんだっけ…。 最近流行りはObservableなんだっけ…。 そんなことを思いつつ、今日も元気にjQueryでDeferred。いつもスペルを間違える。

普段は

function hoge() {
  var $d = new $.Deferred();
  confirm($d.resolve, $d.reject);
  return $d.promise();
}

function moge() {
  hoge().done(...).fail(...);
}

みたいな書き方をしていたんですが、なんか今ひとつだなーと感じていて…。 今回、サーバ側へ状態の問い合い合わせや確認ダイアログを 数回出し、結果的に登録を行うような仕組みを仕事で実装することになり、 ちょっと違った感じに実装してみました。 正しいのかどうかまったくわかりませんが(OSSのソースでも今度眺めてみよう)。

var SaveAction = function() {
  var self = this;
  var confirmA = function() {
    var $d = new Deferred();
    confirm('保存する?', $d.resolve, $d.reject);
    $d.promise()
      .done(queryA);
  }

  var queryA = function() {
    var $d = new Deferred();
    $.ajax({
      // 中略
    })
    .done(function(result, _) {
      if (result.exists) {
        $d.resolve();
      } else {
        $d.reject();
      }
    })
    .fail(function(e) {
      console.log(e);
      $d.reject();
    });
    $d.promise()
      .done(save)
      .fail(showErrorMsg);
  }

  // 中略

  this.execute = function() {
    confirmA();
  }
}

SaveAction.execute();
// or new SaveAction().execute();

これなら各メソッドは、自分の「次に行うこと」だけを知っていて、 それを責任持って呼び出すだけという構造を作れるので割とわかりやすいかなあと。 また、クラスっぽく仕上げているので、以下のような利点があるのかなと。

  • prototypeも含めて拡張がしやすい
  • function内なので
    • リソースの共有が可能
    • 処理間の論理的なつながりを明示できる
  • 外側からexecute()キックするだけで一連の処理が走る

うーん、どうだろう…

JavaScriptのprototype

ふとjavascriptのこと考えていて、 「prototypeのこと私ちゃんと説明出来ない…」と冷や汗が出たので ちゃんと調べてみる。

ちょっと記事のレベルが低いので後日書き直します…

調べる前の知識(間違っているかもしれない)

  • javascriptの各オブジェクトが参照できるプロパティ
  • 雛形となるオブジェクトからいくつオブジェクトを作ろうとも
    実態は一つ。なのでメモリの節約になる。
  • メソッド呼び出し時に自身->自身のプロトタイプ->親->親のプロトタイプ…と探しに行く

言語仕様

object that provides shared properties for other objects

共有のプロパティを他のオブジェクトに提供するオブジェクト…

言語仕様もちゃんと読まなきゃですが、 一旦他の資料を参考に…。

JavaScript:Good Parts

EffectiveJavaScript

ECMA5まではclassの概念がない そのため、オブジェクト指向の機構として、 他のオブジェクトを雛形(prototype)として 新しいオブジェクトを生成する。 {}Object.prototypeとリンクしている。

prototypeに関するメソッド

  • prototype
    • newによって作成されるオブジェクトのプロトタイプ
  • getPrototypeOf(obj)
    • objのprototypeを取り出すためのメソッド
  • __proto__
    • objのprototypeを取り出すためのメソッド(非標準)

書いてみた

    var MyObject = function() {};
    MyObject.prototype.echo = function() {
      console.log('hello');
    }

    var childObj1 = new MyObject();
    var childObj2 = new MyObject();
    var childObj3 = new MyObject();
    childObj1.echo(); // hello
    childObj2.echo(); // hello
    childObj3.echo(); // hello

    MyObject.prototype.echo = function() {
      console.log('good evening');
    }

    childObj1.echo(); // good evening
    childObj2.echo(); // good evening
    childObj3.echo(); // good evening

    childObj1.say = function() {
      console.log('Apple!!');
    }

    childObj2.cry = function() {
      console.log('tear');
    }

    var Moge = function(){};
    // prototypeに設定
    Moge.prototype = childObj1;
    var moge = new Moge();

    moge.echo(); // good evening
    moge.say(); // Apple!!
    try {
      moge.cry(); // エラーになる
    } catch (e) {
      console.warn(e);
    }

    var Hoge = function(){};
    Hoge.prototype = {
      age : 32
      , type : 'animal'
      , call : function() { console.log('How are you'); }
    }
    var hoge = new Hoge();
    console.log(hoge.age); //32
    console.log(hoge.type); // animal
    hoge.call(); // How are you

Go言語のTLSのHTTP実装:オレオレ証明書をコード中で登録する

Real World HTTPで GO言語でTLSの簡易HTTPサーバ、クライアントを実装しよう、というトピックがありました。

説明の通り、OpenSSLコマンドでルートCA、サーバ、クライアントの鍵と証明書を作りました。(コマンドの意味は理解できておらず…この辺りも学んでおかないと…)

本来、無条件に信頼するルートCAはOSに登録されていたり、ツールや言語によってはn内部に含まれていたりするそうです。今回のオレオレ証明書curlで叩くならコマンドラインで渡すなどの方法もとれるそうですが、、GO言語のデフォルトではOSのを参照してしまうそう。

それも面倒なので、プログラムコード内で登録します。 サーバ認証の場合、検証するのはクライアント側になるので、クライアントコードにルートCA追加処理を記述します。これは上記書籍にサンプルソースがありました。 *tls.ConfigRootCAsを使うそうです。

抜粋ですが。

   cert, err := ioutil.ReadFile("ca.crt")
    if err != nil {
        log.Println(err)
    }
    certPool := x509.NewCertPool()
    certPool.AppendCertsFromPEM(cert)

    tlsConfig := &tls.Config{
        ClientAuth: tls.RequireAndVerifyClientCert,
        MinVersion: tls.VersionTLS12,
        ClientCAs:  certPool,
    }
    tlsConfig.BuildNameToCertificate()

    server := &http.Server{
        TLSConfig: tlsConfig,
        Addr:      ":18443",
    }

じゃあクライアント認証も…ってことで、写経してみましたが動かない。

018/01/27 14:57:59 http: TLS handshake error from [::1]:57397: tls: failed to verify client's certificate: x509: certificate signed by unknown authority

むむ、CAが信頼できない、と。 じゃあどうやるんだろうってことで、crypto/tlsのドキュメントを読んだところ解決。ClientCAsを使用します。

   cert, err := ioutil.ReadFile("ca.crt")
    if err != nil {
        log.Println(err)
    }
    certPool := x509.NewCertPool()
    certPool.AppendCertsFromPEM(cert)

    tlsConfig := &tls.Config{
        ClientAuth: tls.RequireAndVerifyClientCert,
        MinVersion: tls.VersionTLS12,
        ClientCAs:  certPool,
    }
    tlsConfig.BuildNameToCertificate()

    server := &http.Server{
        TLSConfig: tlsConfig,
        Addr:      ":18443",
    }

アロー関数

去年末からずっと渋川よしきさんのRealWorldHTTPという本を読んでるんですが、 なかなか読了できず。。。

FetchAPIのサンプルを拝読していたら、
見慣れぬ構文が…。

// (中略)
.then((response) => {
    return response.json();
})
// (後略)

lamdaっぽい…

ということで、調べてみたら
ECMA6からアロー関数というのが追加されたっぽいですね。
目的は二点。

  • 関数を短く記述
  • thisを束縛しない

ふむ。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title></title>
  <script type="text/javascript">
    function myFunc(sub) {
      console.log(sub('aaaa'));
    }
    myFunc((str) => {return str + 'help';});

    // 別に戻り値を返さなくてもいいし、こういうことも出来る。
    var lamda = (val) => {console.log(val);}
    lamda('take me');

    // JSオブジェクトを返すときは()で囲む。構文の{}と区別つけるためかな
    var obj = () => {return ({hoge : 'moge'});}
    console.log(obj());

    // こうすることで、引数のJSオブジェクトのプロパティにアクセス出来る
    obj = ({hoge}) => {return hoge;}
    console.log(obj({hoge : 'Giant'}));
    
    // thisの束縛について
    // 本来、thisのスコープはレシーバになる。
    // => なんか違った気がする…
    function testThis() {
      console.log('[outer]' + this.name);
      var self = this;
      function inner() {
        console.log('[inner]' + this.name);
        console.log('[inner-self]' + self.name);
      }
      inner();
    }
    testThis.call({name : 'testThis'});

    // アロー関数ではthisは外側のthisになる
    function testThisLamda() {
      console.log('[outer]' + this.name);
      var self = this;
      var inner = () => {
        console.log('[inner]' + this.name);
      }
      inner();
    }
    testThisLamda.call({name : 'testThisLamda'});
  </script>
</head>
<body>
</body>
</html>
aaaahelp
arrow.html:8:7
take me
arrow.html:13:27
Object { hoge: "moge" }
arrow.html:18:5
Giant
arrow.html:22:5
[outer]testThis
arrow.html:27:7
[inner]
arrow.html:30:9
[inner-self]testThis
arrow.html:31:9
[outer]testThisLamda
arrow.html:38:7
[inner]testThisLamda
arrow.html:41:9

synchronizedブロックとwaitに関する仮説

JavaGoldの資格勉強してて、 「なんでsynchronizedブロックでしかwait/notify/notifyAll使えないんだろう?」 と疑問に思ったので考えてみた。

間違ってるとは思うのでツッコミ待ち。

メソッド名から考えてみる

まず、Threadを一時中止するメソッドとして

java.lang.Thread.sleep

がある。 上記のクラス、メソッド名で考えると「Treadが眠る」となる。

一方、

java.lang.Object#wait

こちらは、「オブジェクトが待つ」。 何を待つか。おそらく状態の変化だ。

つまり、いずれも自身へのCPU割当を解除し、他Treadへ移譲するように JVMに指示するメソッドではあるが、 目的語があるかどうか、すなわち他と関連するかどうか、という点で異なっている。

synchronized

synchronizedは「オブジェクトにロックをかける」修飾子。 リソースにロックをかけて処理の原子性とリソースの完全性を担保する。 逆に言うと、synchronizedブロック外は(マルチスレッド環境においては) いつ何時他のThreadの処理が行われても構わない、ということになる。

組み合わせで考えてみる

synchronizedの有無とsleep/waitの組み合わせで考えてみる。

① synchronizedなしのsleep

よくあるパターン(かどうかはわからないが)。 単にちょっと待って他のTreadに何らかの処理をさせる。 他の処理の結果は、原則的に当該処理に影響が出ない。 まあinterrup()とかしたら別だけど…。

② synchronizedなしのwait

※ もちろん実際にはIllegalMonitorStateExceptionが発生する。 他の処理に何かを期待して待つ。 あるとき、自Threadが望んだ状態になる。 しかし、その後の処理を行って居る際に割り込みが発生し、望んだ状態でなくなるかもしれない。 それを防ぐには、synchronizedを使うしかない…。

③ synchronizedありのsleep

対象リソースはロックされているので、それが変更されることはないが 一時的に自身の処理を止めることは出来る。

④ synchronizedありのwait

自身が望む状態を他のTreadに作り出してほしい。 なので、ロック対象のオブジェクトを変更する許可を出す。

こんな感じ?

Facebookが自殺投稿前に検知するAIを初公開

自殺的な投稿に備えて全投稿を走査して、必要ならピンチな本人や友人にメンタルヘルス資材を送ったり、地域の初動対応者に連絡を取ってくれたりして、AIを使うことで人力よりも迅速に助力できるとか。

Facebook rolls out AI to detect suicidal posts before they’re reported


  • for:前置詞難しい。「備えて」か?
  • flag:旗を立てるという意味もあるけど、「合図する」
  • proactive:積極的な
  • artifical:人工の。artifical intelligenceでAI。