gitで重いリポジトリをcloneするとき
git clone http://example.com/fuga.git remote: Counting objects: 3203, done. remote: warning: suboptimal pack - out of memory remote: fatal: Out of memory, malloc failed error: git upload-pack: git-pack-objects died with error. fatal: git upload-pack: aborting due to possible repository corruption on the remote side. remote: aborting due to possible repository corruption on the remote side. fatal: protocol error: bad pack header
エラーになるので少しずつ落とす
git clone --depth 1 http://example.com/fuga.git git fetch --depth 10 git fetch --depth 100 # 値は調整しつつ git fetch --unshallow # 最後に全部落とす このオプションは最新のgitでないとない
Ajaxでクロスドメイン通信
Ajaxでクロスドメイン通信について調べたのでまとめ。
シンプルな例
client
var xhr = new XMLHttpRequest(); var url = 'http://example.com/xhr-response.php'; xhr.open('GET', url, true); xhr.send();
server
<?php header('Access-Control-Allow-Origin: *'); echo "ok";
Access-Control-Allow-Origin: *
を付けてレスポンスすると、エラーにならず結果を受け取れる。
クッキー付きの送信
client
var xhr = new XMLHttpRequest(); var url = 'http://example.com/xhr-response.php'; xhr.withCredentials = true; xhr.open('GET', url, true); xhr.send();
xhr.withCredentials = true;
をつけることで、クッキー付きで送信される。
sever
<?php header('Access-Control-Allow-Origin: ' . getenv('HTTP_ORIGIN')); header('Access-Control-Allow-Credentials: true'); echo "ok";
Access-Control-Allow-Credentials: true
をつけ、
かつAccess-Control-Allow-Origin
にはHTTPヘッダーのOriginをつける。
このOriginは、クロスドメインの通信の場合自動的に付与されて送られてくる。
対応ブラウザ
IE以外はok。
IE8,9はXMLHttpRequestではなく、XDomainRequest を使うことで対応可能。
IE6,7はいつも通り動きません。
GET以外
POSTリクエストやPUTリクエストなどは、あらかじめOPTIONSリクエストで許可をもらわないといけない。
client
OPTIONS Origin: http://example.com Access-Control-Request-Method: POST Access-Control-Request-Headers: X-PINGOTHER
server
Access-Control-Allow-Origin: http://example.com Access-Control-Allow-Methods: POST, GET, OPTIONS Access-Control-Allow-Headers: X-PINGOTHER Access-Control-Max-Age: 3600
再度、あらためてPOSTを送る。
参考
Part2 : ErlangVMで動くRuby風の関数型言語Elixir(エリクサー) : 基礎編
Part1はこちら
インターフェース
defprotocolでinterfaceのようなものが定義できる
defprotocol Checker do def ok?(data) end
defimplでinterfaceの実装を定義できる
defimpl Checker, for: List do def ok?([]), do: "ng" def ok?([h | _]) when h == 1, do: "ok" def ok?([2 | _]), do: "ok2" end defimpl Checker, for: Number do def ok?(1), do: "ok" def ok?(_), do: "ng" end Checker.ok?([1,2,3]) # ok Checker.ok?([2,3,4]) # ok2 Checker.ok?([3,4,5]) # ng Checker.ok?(1) # ok Checker.ok?(2) # ng
関数をキャプチャ
定義済みの関数を、別の関数に渡したいとき等に。
f = &Integer.odd?/1 Enum.map([1,2,3,4,5], f) # [true, false, true, false, true]
Erlangの関数をコール
:(コロン)をつけるとErlangのモジュールが呼べる。
:timer.sleep 1000 # 1秒sleep
プロセス生成
spawnで生成。receiveで外から値を受け取れる。
defmodule Process do def from do receive do i -> IO.inspect i * i after 100 -> IO.inspect "timeout.." end end end p = spawn Process, :from, [] p <- 2 # プロセスに値を送るとreceiveで受け取れる。
Stream
scalaにもある無限のリストを作るコレクション
IO.inspect Stream.map(1..1000000000, &(&1 * &1)) |> Enum.take(5) # [1, 4, 9, 16, 25]
File
ファイルをread。
case File.read("/etc/hosts") do { :ok, body } -> IO.inspect body { :error, reason } -> IO.inspect reason end
!を付けると例外を飛ばすようになる。rubyっぽい...
body = File.read!("/etc/hosts") IO.inspect body
例外をcatchしてみる
try do File.read! "/etc/hogeeeee" rescue File.Error -> IO.inspect "catche!" end
様々なファイル操作の関数がある
File.rm_rf! "/tmp/fuga" File.mkdir! "/tmp/fuga" File.write! "/tmp/fuga/elixir.txt", "elixir!" IO.puts File.read! "/tmp/fuga/elixir.txt" IO.inspect File.ls! "/tmp/fuga" File.rm! "/tmp/fuga/elixir.txt"
pmap
Elixir関係ないけど、便利なErlangの関数だったので。
1ループを1プロセスで実行するmap。ものすごい並列感...
defmodule Par do def exec(i) do :timer.sleep 1000 i * i end end :rpc.pmap {Par, :exec}, [], [1,2,3,4,5,6,7,8,9] # 1sかかる Enum.map [1,2,3,4,5,6,7,8,9], &Par.exec/1 # 9sかかる
公式サイトを翻訳したほうが早いんじゃないかと思えてきた...
ErlangVMで動くRuby風の関数型言語Elixir(エリクサー) : 基礎編
Erlangの奇妙な文法を覚えることなく、Erlangの機能が使えるエリクサー。
Ruby風の文法なのでRubyistには馴染みの関数などが使えるが、以下のことを頭にいれておくべし。
楽天Technologyカンファレンスでセッションがあったり、Erlangを簡単に書ける言語としてこれから普及していくのではないでしょうか!
インストール
brew install elixir
iex
iex
irbのようにiexで、試し書きが簡単にできます。(iexはerlのラッパー)
基本文法
四則演算
1 + 1 # 2 1 - 1 # 0 1 * 1 # 1 1 / 1 # 1.0 div 1, 1 # 1 rem 2, 4 # 2 # 2 % 4 not work
型
"a" # string 1 # integer 1.2 # float :id # atom [1,2,3] # list {1,2,3} # tuple [a: "a", b: 2] # keyword
文字列
s = "str" "[" <> s <> "]" # [str] "[#{s}]" # [str] String.reverse "str" # rts String.slice "str", 1, 2 # tr String.first "str" # f String.last "str" # r String.at "str", 1 # t String.graphemes("str") # ["s", "t", "r"]
変数
v = "v" # v = "vv" 不変なので代入不可
デバッグ
IO.inspect [1,2,3] IO.puts "foo" # 文字列のみ(改行コード付き) IO.write "foo" # 文字列のみ(改行コードなし)
コレクション
[head | tail] = [1,2,3] head # 1 tail # [2,3 Enum.map [1,2,3], fn(i) -> i * i end # [1,4,9] Enum.map [1,2,3], &(&1 * &1) # [1,4,9] Enum.filter [1,2,3], &(Integer.odd?(&1)) # [1,3] Enum.find [1,2,3], &(&1 == 1) # 1 Enum.all? [1,3], &(Integer.odd?(&1)) # true [scala = forall] Enum.any? [1,3], &(Integer.odd?(&1)) # true [scala = exists] Enum.at [1,2,3], 1 # 2 Enum.max [1,2,3] # 3 Enum.join [1,2,3], "-" # 1-2-3 f = fn i when rem(i, 2) == 0 -> [i] _ -> [] end Enum.flat_map(1..10, f) # [2, 4, 6, 8, 10] Enum.map(1..10, f) |> List.flatten # [2, 4, 6, 8, 10]
パイプ
[1,2,3,4,5] |> Enum.filter(&(rem(&1,2) != 0)) |> Enum.map(&(&1 * &1)) # [1,9,25] "str" |> String.graphemes |> Enum.map(&("-#{&1}-")) |> Enum.join # "-s--t--r-"
気軽に繋げて書くことができる。
条件
if
if true do "ok" # ok else "ng" end # 簡易版 if true, do: "ok", else: "ng" # ok if true, do: 1 # 1 if false, do: 1, else: 2 # 2
unless
unless false, do: "unless"
case
case 1 do 1 -> p "ok" # ok _ -> p "ng" end case [1,2,3] do [1 | _] -> p "ok" # ok _ -> p "ng" end case {1,2,3} do {1,2,3} -> p "ok" # ok _ -> p "ng" end case [1,2,3] do [_ | [2,3]] -> p "ok" _ -> p "ng" end case [1] do [h | []] -> p h # 1 _ -> p "ng" end a = 1 case true do ^a -> p "not match" _ -> p "match" end
関数
基本
defmodule Math do def sum(a, b) do a + b end end Math.sum(1,2) # 3 defmoduleの中でないとdefは定義できない Math.sum 1,2 # rubyのように()省略可 # ネスト defmodule Math do defmodule Foo do def sum(a, b) do a + b end end end Math.Foo.sum 1,2 # 3 # 短く defmodule Math do def sum(a, b), do: a + b end Math.sum 1, 2 # 3
匿名関数
f = fn(x, y) -> x + y end f.(1,2) # 3 # 短く f = &(&1 + &2) f.(1,2) # 3
高階関数
ff = fn(f) -> f.(2,3) + f.(4,5) end ff.(f) # 14
ガード
f2 = fn x when x < 1 -> "ng" _ -> "ok" end f2.(1) # ok
サンプル
# フィボナッチ defmodule Fib do def f(l), do: f(l,1,1) def f(l, a, b) do if l > b, do: [b] ++ f(l, b, a + b), else: [] end end Fib.f(30) # [1, 2, 3, 5, 8, 13, 21]
# リバース defmodule Reverse do def r([head | tail]), do: r(tail) ++ [head] def r([]), do: [] end Reverse.r [1,2,3] # [3,2,1] Enum.reverse [1,2,3] # [3,2,1]
クラスのようなもの
defrecord Person, name: "", age: 0 do def say(mine) do "I am " <> mine.name <> "." end end tanaka = Person.new(name: "tanaka", age: 20) tanaka.say # I am tanaka.
AS3で動画を扱ったり、JSと連携したり
ActionScript3で動画に関するメモ
動画再生
動画を再生するには以下のいずれか。
- FLVPlaybackを使う。
- flexのspark.components.VideoPlayerを使う。
- Videoクラスなどを使い自前で作る。
1がスタンダード。
FLVPlayback
使い方
ウインドウ -> コンポーネント -> Videoを開く -> FLVPlaybackをステージに。
import fl.video.FLVPlayback; var player = new FLVPlayback(); addChild(player); player.source = "hoge.mp4"; player.autoPlay = true;
対応してる種類
デフォルトで用意されてるコンポーネント。flvと名前が付いてるが、mp4など色々いける。
Flash Player 9 Update 3 では、業界標準の H.264 エンコーディングを利用する高解像度の MPEG-4 ビデオ形式がサポートされ、FLVPlayback コンポーネントの機能が向上しています。サポートされる形式は、MP4、M4A、MOV、MP4V、3GP および 3G2 です。
スキン
Macだと以下にスキンがある。同じ位置にflaもあるので自由にカスタマイズできる。
"/Applications/Adobe Flash CC/Adobe Flash CC.app/Contents/Common/Configuration/FLVPlayback Skins/MinimaSilverPlayBackSeekCounterVolMute.swf"
動画に字幕を付ける
字幕を付けるにはFLVPlaybackCaptioningが使える。
var captions = new FLVPlaybackCaptioning(); captions.autoLayout = false; captions.flvPlayback = player_mc.player; captions.source = "sample.xml";
残念なことxmlファイルを読み込んでしか使えない...。
xmlオブジェクトを読めるようにしてくれれば...。
JSとFlashの連携
連携に必要な設定
1. allowScriptAccessをalwaysに設定する必要がある
<object ... > <param name="allowScriptAccess" value="always"> </object>
2. file://だとダメ
http://localhost/ とかでないと、動きません。
3. flashとjsが別ドメインの場合
flash.system.Security.allowDomain('example.com')
js -> flash
html
<object id="hoge" ...>
js
var swf = document.hoge || window.hoge; swf.to_flash();
flash
if (ExternalInterface.available) { ExternalInterface.addCallback('to_flash', function() { test.text = 'receive it!'; }); }