elixir, phoenix導入メモ
elixirを試したいので入れた。 大まかな流れは Installation · Phoenix の通り。
ただしMacだとbrewで簡単に入るけど、今後のためにexenv
で入れてみた。
Rubyでいうところのrbenv
。
erlang
brew install erlang
erlangにもerlenv
というのがあるらしいけど、ビルドをしてくれるコマンドがまだないとのことだったので使わなかった。
あとで本格的に使うときに考えよう。
exenv -> elixir
exenv自体はbrewで入れた。
exenv install
をするにはelixir-build
も必要。rbenv
っぽい。
brew install exenv brew install elixir-build # PATHの設定とかまでは自動でやってくれなかった。 echo 'export PATH="$HOME/.exenv/bin:$PATH"' >> ~/.bash_profile echo 'eval "$(exenv init -)"' >> ~/.bash_profile exec $SHELL
elixirを入れる。
# インストールできるバージョンを確認。 exenv install -l # インストール exenv install 1.0.5 # バージョン確認 elixir -v Elixir 1.0.5 mix -v Mix 1.0.5
node, npm
phoenixではアセットのコンパイルにnpm(とbrunch.io)を使うらしいのでnodeも入れておく。 最近v4.0.0が出たらしいのでついでに改めて入れてみる。 phoenixがちゃんと対応しているかは知らず。
nodebrew install v4.0.0 nodebrew alias default v4.0.0 nodebrew use v4.0.0
しかしアセットをnodeで管理するのは時代を感じるし理にかなってる。 Railsも本家でこういう対応してくれないだろうか。。。
phoenix
phoenixのインストールはちょっと見慣れない感じで以下のようにやるらしい。
mix archive.install https://github.com/phoenixframework/phoenix/releases/download/v1.0.2/phoenix_new-1.0.2.ez
mixというのはelixirに付いてくるビルドツールでnpmのようなもの??
Web上のアーカイブ(中身はZIPらしい)を持ってきて$HOME/.mix/archives/
に配置してくれるらしい。
以上で準備できた。簡単。
Hello, Phoenix
とりあえず動作確認まで。
mix phoenix.new hello_phoenix * creating hello_phoenix/config/config.exs * creating hello_phoenix/config/dev.exs * creating hello_phoenix/config/prod.exs * creating hello_phoenix/config/prod.secret.exs * creating hello_phoenix/config/test.exs * creating hello_phoenix/lib/hello_phoenix.ex * creating hello_phoenix/lib/hello_phoenix/endpoint.ex * creating hello_phoenix/test/controllers/page_controller_test.exs * creating hello_phoenix/test/views/error_view_test.exs * creating hello_phoenix/test/views/page_view_test.exs * creating hello_phoenix/test/views/layout_view_test.exs * creating hello_phoenix/test/support/conn_case.ex * creating hello_phoenix/test/support/channel_case.ex * creating hello_phoenix/test/test_helper.exs * creating hello_phoenix/web/channels/user_socket.ex * creating hello_phoenix/web/controllers/page_controller.ex * creating hello_phoenix/web/templates/layout/app.html.eex * creating hello_phoenix/web/templates/page/index.html.eex * creating hello_phoenix/web/views/error_view.ex * creating hello_phoenix/web/views/layout_view.ex * creating hello_phoenix/web/views/page_view.ex * creating hello_phoenix/web/router.ex * creating hello_phoenix/web/web.ex * creating hello_phoenix/mix.exs * creating hello_phoenix/README.md * creating hello_phoenix/lib/hello_phoenix/repo.ex * creating hello_phoenix/test/support/model_case.ex * creating hello_phoenix/priv/repo/seeds.exs * creating hello_phoenix/.gitignore * creating hello_phoenix/brunch-config.js * creating hello_phoenix/package.json * creating hello_phoenix/web/static/css/app.css * creating hello_phoenix/web/static/js/app.js * creating hello_phoenix/web/static/js/socket.js * creating hello_phoenix/web/static/assets/robots.txt * creating hello_phoenix/web/static/assets/images/phoenix.png * creating hello_phoenix/web/static/assets/favicon.ico Fetch and install dependencies? [Yn] * running npm install && node node_modules/brunch/bin/brunch build We are all set! Run your Phoenix application: $ cd hello_phoenix $ mix deps.get $ mix ecto.create $ mix phoenix.server You can also run your app inside IEx (Interactive Elixir) as: $ iex -S mix phoenix.server
途中で「依存関係をインストールする?」と聞かれてyesと答えるとこうなる。
noにしてもプロンプトに表示されるように、あとでnpm install && node node_modules/brunch/bin/brunch build
すれば良いらしい。
で続きもプロンプトに出ているように以下のコマンドを打つ。
mix deps.get Could not find hex, which is needed to build dependency :phoenix Shall I install hex? [Yn] 2015-09-14 23:18:39 URL:https://s3.amazonaws.com/s3.hex.pm/installs/1.0.0/hex.ez [269416/269416] -> "/Users/xxx/.mix/archives/hex.ez" [1] * creating /Users/xxx/.mix/archives/hex.ez Running dependency resolution Dependency resolution completed successfully cowboy: v1.0.3 cowlib: v1.0.1 decimal: v1.1.0 ecto: v1.0.2 fs: v0.9.2 phoenix: v1.0.2 phoenix_ecto: v1.2.0 phoenix_html: v2.2.0 phoenix_live_reload: v1.0.0 plug: v1.0.0 poison: v1.5.0 poolboy: v1.5.1 postgrex: v0.9.1 ranch: v1.1.0 ・・・以下略・・・
出だしにShall I install hex?
と聞かれるのでyesと答える。
hex
とはelixirのパッケージマネージャだそうだ。
あれ?ってことはmix
はmake
てきな位置付けなのかな?
このへんまだよくわからない。
次にmix ecto.create
。
ecto
はRailsでいうActiveRecord的なもの?
mix ecto.create Could not find rebar, which is needed to build dependency :fs I can install a local copy which is just used by mix Shall I install rebar? [Yn] * creating /Users/akiyoshi/.mix/rebar ==> fs (compile) Compiled src/sys/inotifywait.erl Compiled src/sys/fsevents.erl ・・・中略・・・ ** (Mix) The database for HelloPhoenix.Repo couldn't be created, reason given: "psql: FATAL: role \"postgres\" does not exist\n".
大量のファイルが生成されたが最後にエラー。 DBの設定ができてなかったみたい。 postgresユーザーをパスワードpostgresで作成する。
# postgresqlサーバー起動 pg_ctl -l /usr/local/var/postgres/server.log start # postgresユーザー作成 createuser -P -d postgres # 確認 psql -q -c'select * from pg_user' postgres
もういちどmix ecto.create
するとできた。
mix ecto.create The database for HelloPhoenix.Repo has been created.
ようやくサーバー起動
mix phoenix.server [info] Running HelloPhoenix.Endpoint with Cowboy on http://localhost:4000 14 Sep 23:37:53 - info: compiled 5 files into 2 files, copied 3 in 2398ms
http://localhost:4000/ にアクセスすると無事見れた。
参考
公式と以下の記事がとても参考になりました。感謝。
RSpecでデフォルトであるクラスのインスタンスメソッドをスタブにしたい
外部APIとかテスト中は常にスタブにしたいときに、個々のspecで設定するのが面倒だし忘れそうなケース。
こんな :spec/support/xxx_helper.rb
を作っておいて
module XxxHelper # テスト全体で共通の前処理 shared_context 'common_before', common_before: true do before :all do # 全体の前処理(あれば) end before :each do # Userがtweetというメソッドを持っている場合 allow_any_instance_of(User).to receive(:tweet).and_return(true) end end end
以下のように spec/request/xxx_spec.rb
で include_context
するか
require 'rails_helper' describe Xxx do include_context 'common_before' end
もしくは以下のように describe
で宣言的に指定する。
require 'rails_helper' describe Xxx, common_before: true do end
spec/rails_helper.rb
で spec/support
以下を読み込む設定をコメントインするのを忘れずに。
Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }
また個々のspecで expect_any_instance_of
で上書きすればスタブ化したメソッドが呼ばれたか調べたいときも対応できる。
describe 'some_spec' do before :each do expect_any_instance_of(User).to receive(:tweet).and_return(true) end it 'xxxxx' do # xxxxx end end
簡単だけど以上。
MacでJavaがまたわからなくなった
新しいMacBook Pro (2015)を買って便利に使っていたんだけど、やっぱり仕事でまたJava(AndroidStudio)が必要になった。
まだ入れてなかったので今使ってるYosemite10.10.3では何が入ってるんだろうと確認したところ、、、
$ java --version No Java runtime present, requesting install.
とでて下記のようなダイアログが出る。
そうかもはやデフォルトでは入ってないのか、、、
しかしこの java
コマンドは何もの??
これを伝えるためだけに存在するの??
$ which java /usr/bin/java $ ls -l /usr/bin/java lrwxr-xr-x 1 root wheel 74 2 22 18:00 /usr/bin/java -> /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/java
うーん、どうやらMacでのいつもの場所にあってその辺の構成は変わってないみたいだけどよくわからない。
まあとりあえずJava6,7,8が使い分けられる状態にできればいいや。
こちらを参考にさせていただきました。
Mac に brew で Oracle Java のバージョンを指定してインストールする方法 - Qiita
抜粋
- hosts: localhost connection: local gather_facts: no sudo: no vars: homebrew_taps: - homebrew/binary - homebrew/dupes - caskroom/cask - caskroom/versions homebrew_packages: - { name: readline } - { name: openssl } - { name: openssl, state: linked, install_options: force } - { name: python } - { name: ansible } homebrew_cask_packages: - { name: java6 } - { name: java7 } - { name: java } - { name: android-studio }
全体
.bashrcには以下のように書いた。
# Java (未インストールの場合はあるバージョンのが入る) export JAVA_HOME6=$(/usr/libexec/java_home -v 1.6 2>/dev/null) export JAVA_HOME7=$(/usr/libexec/java_home -v 1.7 2>/dev/null) export JAVA_HOME8=$(/usr/libexec/java_home -v 1.8 2>/dev/null) export JAVA_HOME=$JAVA_HOME7 export PATH=$JAVA_HOME/bin:$PATH # Android Studio export STUDIO_JDK=${JAVA_HOME7%/*/*}
Java、せっかく便利(?)なんだからこの辺もうちょい小慣れてほしい。。
Sass/ScssフレームワークBourbon使ってみた
要約
BourbonたちはしっかりHTML/CSS書きたいとき向け。
(CSSの習熟度によって感想変わりそうではある)
きっかけ
以下の記事をみてSass/ScssのフレームワークであるBourbonとその仲間たちを知った。
CSSフレームワークBourbon/Neat/Bitters/Refillsは美しい
CSSフレームワークといえばBootstrap便利でよく使ってるんだけど、記事でも言われているようにクソマークアップ問題は感じている。
そこで代替としてBourbonファミリーはどんなもんか自分でも触ってみた。
色々試した結果
akiyoshi83/ex_bourbon · GitHub
Bourbonとその仲間たちの現時点での認識は以下の様な感じ。
- Bourbon
SCSSのMixin集(like Compass) - Neat
Bourbonを利用したGridフレームワーク - Bitters
Bourbonを利用したコンポーネント集(like Bootstrap?) - Refills
Bourbon, Neatのサンプル、スニペット集
お試しプロジェクト用意
Railsで試してみる。
$ rails new -B -T ex_bourbon $ cd ex_bourbon
Gemfileに追加してインストール。
$ ehoc ‘gem “neat”’ >> Gemfile $ ehoc ‘gem “bitters”’ >> Gemfile $ ehoc ‘gem “refills”’ >> Gemfile $ bin/bundle install —path vendor/bundle
Bourbon自体はNeat, Bitters, Refillsがそれぞれ依存しているので勝手に入ってくる。
$ echo ‘/vendor/bundle’ >> .gitignore $ git init $ git add . $ git ci -m “First commit"
お試し用のページを用意。
$ bin/rails g controller home index $ git add . $ git ci -m "Add home/index and set root path"
Bourbonをセットアップ
とはいっても
app/assets/stylesheets/application.css
を
app/assets/stylesheets/application.scss
にリネームして
既存の内容を全て消してからその中に@importを記述するだけ。
@import ‘bourbon’;
Railsでない場合は以下のコマンドを打つとカレントディレクトリにbourbonディレクトリが出来る。
$ bundle exec bourbon install
※—path
オプションで配置場所を変更できる。
Neatをセットアップ
参考 https://github.com/thoughtbot/neat#requirements
これもBourbonと同じ要領。
ただし@import
はBourbonのよりあとに書く。
Rails以外ではコマンドでセットアップする必要があるのも同じ。
Bittersをセットアップ
参考 https://github.com/thoughtbot/bitters#installation
これはRailsでもコマンドでセットアップが必要。
$ (cd app/assets/stylesheets/; ../../../bin/bundle exec bitters install)
以下のようになる。
$ tree app/assets/stylesheets/ app/assets/stylesheets/ ├── application.css └── base ├── _base.scss ├── _buttons.scss ├── _forms.scss ├── _grid-settings.scss ├── _lists.scss ├── _tables.scss ├── _typography.scss └── _variables.scss
そしてBourbonのあとに@import
する。
Neatも併用する場合はNeatをBittersのあとに@import
する。
@import 'bourbon'; @import 'bitters'; @import 'neat';
それとbase/_base.scss
の@import “grid-settings”;
をコメントインする必要があるらしい。
手元では簡単なグリッドはコメントインしなくても動いたけど必要なのかな?
他にもやりたいことによって@importのパスを変えたり色々変える必要があるらしけどとりあえずこの設定で試す。
あとはこれで普通にHTML書いていくとある程度のスタイルがBittersによってあたっているし(最小限っぽいけど)、グリッドもSCSS側で書けば簡単に実装できる。
またBittersが生成するSCSSは8つあるけどどれも100行未満で簡単に読めてカスタマイズも容易そう、かつSass/Scssビギナーには参考になる気がする。
Refillsをセットアップ
参考 https://github.com/thoughtbot/refills#installation
以下のコマンドで試用できるスニペット一覧が表示される。
$ bin/rails g refills:list Available Refills ================= - accordion-tabs-minimal - accordion-tabs - accordion - animate-info - animate - badges - breadcrumbs - button-group - cards - centered-navigation - comment - device - dropdown - expander - fade-in - flashes - flex-boxes - footer-2 - footer - grid-items-lines - grid-items - hero - hover-tile-animation - icon-bullet-points - image-gradient-dynamic - maps - modal - navigation - pagination - parallax - progress-bar-indication - progress-bar - ribbon - scroll-on-page - search-bar - search-tools - side-image - sliding-menu - stats - switch - tables-minimal - tables - texture-legend - textures - tooltip - type-system-geometric - type-system-rounded - type-system-sans - type-system-serif - type-system-slab - type-system-traditional - vertical-tabs - video
スニペットのインストールは
$ bin/rails generate refills:import SNIPPET
スクリプトをCoffeeScriptで欲しい時は以下。
$ bin/rails generate refills:import SNIPPET --coffee
スニペットは1つずつ指定してインストールするらしい。 単純そうなfooterをインストールしてみる。
$ bin/rails g refills:import footer --coffee
create app/views/refills/_footer.html.erb
create app/assets/stylesheets/refills/_footer.scss
うーん、ほんとサンプルコードが生成されます、ッて感じで、あんまり使い勝手良くないかも。 あくまで参考にする程度か。
感想
Bootstrapみたいにclassを書くだけで劇的にスタイリングが楽になるようなものではない。あくまでスタイルはガシガシ書く必要がある。
ただもちろんブラウザごとの書き方の違いは吸収してくれるし、HTMLに謎のclassが散りばめられることはなくなる。 Bootstrapもちゃんと使うとスタイルの上書きやなんやらで結構ガシガシ書くし、余計なことを気にせずマークアップを正しく書いて見た目はCSSでっていう成功法で実装するには都合が良さそう。
使い捨ての社内ツールやプロトタイプでプログラマが手っ取り早く見た目を整えたいって場合は相変わらずBootstrapは有力な選択肢。
あとCompassもそうだけどBourbonが用意してくれるmixinは結構マニアックなプロパティに関するものもあるので、そもそもCSSにちゃんと詳しくないと使い方が分からないであろうものも結構ある。 そういう場合もBootstrapで充分かも。
BourbonらはあくまでHTML/CSSをちゃんと書きたい人向けのツールだと思った。
とはいえ今後自分が作るツールとかにBourbon使わずBootstrap使うかといえば微妙で、できれば簡単なものでもBourbon使っていきたい。 自分の場合、そもそも簡単なものならBootstrapすら使わず最低限のCSSとJSで済ませてしまうことも多いので。 どうせBootstrap使わないならブラウザ間の違いも吸収してくれるしSCSSもっと使いこなせるようになりたいしBourbon使ったほうが良い気がする。
でどうせならNeatのグリッドシステムあれば便利だしBittersでタイポグラフィとかあたってくれるとまあこれでいいかってなるのでそれも使いそう。 ただテーブルとか変更したいものもあるけどカスタマイズも容易そうなので。Refillsは参考程度かな…
まあ自分の選択のレベルだと好みで良いかなってレベルだけど。 長期的にHTML/CSSをメンテしていく時にはもっと明確にメリットが出るかもしれない。その辺はもっと使い込んでみないとハッキリ言えないけど。
昔入れてたMySQLを入れなおしたメモ
ローカルのMac上にMySQLが欲しくなって入ってたっけな?と調べたときのメモ。
あと最終的にMacPortsで入れてたMySQLをHomebrewで入れなおしたんだけど、なんかMac特有っぽい事があったのでそれも。
調べたら簡単にインストールし直せたんだけど、こういった環境周りで忘れてしまったことの調査って、分からない人には結構時間かかることかもしれないので誰かの参考になれば。
まず過去にインストールしてたらMySQLへの接続コマンドが入ってそうなので打ってみる。
$ mysql
と打ってタブで補完すると以下のように出てきた。
mysql5 mysql_install_db5 mysqladmin5 mysqlhotcopy5 mysql_client_test5 mysql_secure_installation5 mysqlbinlog5 mysqlimport5 mysql_client_test_embedded5 mysql_setpermission5 mysqlbug5 mysqlshow5 mysql_config5 mysql_tzinfo_to_sql5 mysqlcheck5 mysqlslap5 mysql_convert_table_format5 mysql_upgrade5 mysqld_multi5 mysqltest5 mysql_find_rows5 mysql_waitpid5 mysqld_safe5 mysqltest_embedded5 mysql_fix_extensions5 mysql_zap5 mysqldump5 mysql_fix_privilege_tables5 mysqlaccess5 mysqldumpslow5
うーん、一体いつ入れたんだっけ?
昔過ぎて思い出せない。
このまま新しくインストールするのは気持ち悪いので消そう。
Linuxでもそうだけどwhich
コマンドで指定したコマンドのパスを調べられる。
$ which mysql5
/opt/local/bin/mysql5
場所はわかったけど、どうやってインストールしたんだっけ?
パス的に自分でビルドしたものではなさそう(自前ビルドはいつも別の場所でやっているので)なのでパッケージ管理システムっぽい気がする。
このMacではHomebrewとMacPortsで入れたものが微妙に混在している…
Homebrewから調べる
$ brew list | grep mysql
違った…じゃあMacPortsか?
$ port installed | grep mysql mysql5-devel @5.5.2-m2_1 (active)
これだ!
なんでdevelだけインストールしてたんだろう…?
何かが依存してるかもだけど全く覚えてないので、壊れてるの発見したらその時考えよう…
$ port uninstall mysql5-devel
これで綺麗になったので改めてbrewでインストールする。
$ brew update $ brew install mysql ==> Installing mysql dependency: openssl ==> Downloading https://downloads.sf.net/project/machomebrew/Bottles/openssl-1.0.2.yosemite.bottle.tar.gz ######################################################################## 100.0% ==> Pouring openssl-1.0.2.yosemite.bottle.tar.gz ==> Caveats A CA file has been bootstrapped using certificates from the system keychain. To add additional certificates, place .pem files in /usr/local/etc/openssl/certs and run /usr/local/opt/openssl/bin/c_rehash This formula is keg-only, which means it was not symlinked into /usr/local. Mac OS X already provides this software and installing another version in parallel can cause all kinds of trouble. Apple has deprecated use of OpenSSL in favor of its own TLS and crypto libraries Generally there are no consequences of this for you. If you build your own software and it requires this formula, you'll need to add to your build variables: LDFLAGS: -L/usr/local/opt/openssl/lib CPPFLAGS: -I/usr/local/opt/openssl/include ==> Summary 🍺 /usr/local/Cellar/openssl/1.0.2: 459 files, 18M ==> Installing mysql ==> Downloading https://downloads.sf.net/project/machomebrew/Bottles/mysql-5.6.22.yosemite.bottle.tar.gz ######################################################################## 100.0% ==> Pouring mysql-5.6.22.yosemite.bottle.tar.gz ==> Caveats A "/etc/my.cnf" from another install may interfere with a Homebrew-built server starting up correctly. To connect: mysql -uroot To have launchd start mysql at login: ln -sfv /usr/local/opt/mysql/*.plist ~/Library/LaunchAgents Then to load mysql now: launchctl load ~/Library/LaunchAgents/homebrew.mxcl.mysql.plist Or, if you don't want/need launchctl, you can just run: mysql.server start ==> /usr/local/Cellar/mysql/5.6.22/bin/mysql_install_db --verbose --user=akiyoshi --basedir=/usr/local/Cellar/mysql/5.6.22 --dat ==> Summary 🍺 /usr/local/Cellar/mysql/5.6.22: 9666 files, 339M
依存関係でOpenSSLも入った。
今までなかったんだっけ???
またインストールの出力にMac特有っぽいことが書いてあったのでメモ。
- 他でインストールしたmysqlの
/etc/my.conf
があると正常に起動できないかもよ(これはMacだけじゃないか…でも親切ね) - ログイン時に自動起動するには
~/Library/LaunchAgents
に/usr/local/opt/mysql/*.plist
のシンボリックリンクを貼ってよ launchctl load ~/Library/LaunchAgents/homebrew.mxcl.mysql.plist
で今すぐ起動もできるよ(?)mysql.server start
でも可だよ
あとインストールの出力の最後のように書かれている通り勝手に初期設定もしてくれたっぽい。
試しに起動してみる。
$ mysql.server start
Starting MySQL
.. SUCCESS!
psコマンドで確認すると確かにプロセスが起動していた。
接続してみる。
$ mysql -u root Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 2 Server version: 5.6.22 Homebrew Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | test | +--------------------+ 4 rows in set (0.00 sec)
イケた!
どんな初期設定になったかは調べてないけどとりあえずMySQL使えれば良いレベルなので困ったらで良いか。
Promiseのスニペット
JavaScriptのPromiseが便利そうなので使い始めてたのだけど、メソッドチェインしたり入れ子にしていたら混乱してきたのでまとめる。
この数日でよく使った(そして度々間違えた)パターンのメモ。
逐次実行
こんな感じのPromiseオブエジェクトを返す関数があったとする。
function promise1() { console.log('promise1 args', arguments); return new Promise(function(resolve, reject) { setTimeout(function() { // resolveしたものがthenの引数になる resolve('resolve promise1'); }, 500); }); } function promise2() { console.log('promise2 args', arguments); return new Promise(function(resolve, reject) { setTimeout(function() { resolve('resolve promise2'); }, 400); }); } function promise3() { console.log('promise3 args', arguments); return new Promise(function(resolve, reject) { setTimeout(function() { resolve('resolve promise3'); }, 300); }); }
単純にthenで連結すると逐次実行になる。
これは単純。
// それぞれのpromise関数には前の関数でresolveした値が引数にくる promise1() .then(promise2) .then(promise3) .then(function() { // promise3でresolveに与えたものが引数で渡ってくる console.log(arguments); // returnした値を次のthenのコールバックで受け取れる return "returm then callback"; }).then(function() { console.log(arguments); });
出力。
promise1 args [] promise2 args ["resolve promise1"] promise3 args ["resolve promise2"] ["resolve promise3"] ["returm then callback"]
別のパターン。
事前にいくつthenが必要になるか分からないときなどはこういった手間がいるかも。(以下はJavaScript Promiseの本の例そのままです)
// 以下の様なヘルパー関数を使って // Promiseオブジェクトを返す関数の配列を // 逐次処理することもできる function sequenceTasks(tasks) { function recordValue(results, value) { results.push(value); return results; } var pushValue = recordValue.bind(null, []); // reduceの第2引数のpromiseオブジェクトを初期値に折りたたむ return tasks.reduce(function (promise, task) { return promise.then(task).then(pushValue); }, Promise.resolve()); } // 逐次実行 sequenceTasks([promise1, promise2, promise3]);
出力。
promise1 args [undefined] promise2 args ["resolve promise1", "resolve promise2", "resolve promise3"] promise3 args ["resolve promise1", "resolve promise2", "resolve promise3"]
入れ子
API全体をPromise使おうとしていたんだけど、「あれ?この関数でreturnしているpromiseオブジェクトをそのまま返せば良いんだっけ?新しくnewしないといけないんだっけ?」と迷った。
結論をいうとそのまま返して良いし、返す前にthenやcatchで処理を追加してもよい。thenやcatchが返すオブジェクトも新しいpromiseオブジェクトであるため。
thenやcatchは処理を追加していくイメージっぽい。
function promiseInner() { console.log('promiseInner args', arguments); return new Promise(function(resolve, reject) { resolve('promiseInner'); }); } function promiseOuter() { console.log('promiseOuter args', arguments); // promiseのなかでもpromiseが使える // promise関数自体もthenも // 新しいPromiseオブジェクトが返るので // それをそのまま返せばメソッドチェインできる return promiseInner().then(function() { console.log('promiseOuter after4', arguments); return "return promiseInner in promiseOuter"; }); } promiseOuter() .then(function() { console.log('afterInner', arguments); });
出力。
promiseOuter args [] promiseInner args [] promiseOuter after4 ["promiseInner"] afterInner ["return promiseInner in promiseOuter"]
もっと慣れたら便利っぽいので小さいところから使って慣れていこう。
MacでのJDK管理
MacでJavaはLinuxより更にややこしい。
ググったのが通算3回位になったのでそろそろ自分でもメモ。
Linuxでのは昔書いた記事参照。
UbuntuでのJDK管理 - my coredump
MacでのJava事情とかどこにインストールされるのかとかの詳しいことは、 他の方が書いているのでここでは手っ取り早く結論だけ書きます。
OSXでJavaのバージョンを切り替える
(お世話になっております)
結論
ダウンロードするところ
2014.01.10時点
- JDK1.6 (AppleのサポートでJavaで検索)
http://support.apple.com/kb/DL1572 - JDK1.7
http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html - JDK1.8
http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
インストール
普通にdmgを実行する。 インストールする順番とかは気にしないでも大丈夫だった(1.7の後に1.6入れたり)。
バージョン切り替え
.bash_profileとかお好みのドットファイルにに以下を記述。
export JAVA_HOME=$(/usr/libexec/java_home -v 1.6) export PATH=$JAVA_HOME/bin:$PATH
-v 1.6
の部分を切り替えればバージョンが切り替えられる。
変更した後は.bash_profileなどを再読込するかログアウト・ログインする。