suztomoの日記

2010-12-18

[]Erlangのnode一覧

> nodes().

でつながってるノード一覧が見られる.

あとErlangはクローラとかに使えるらしい.SocketのAbstractionも便利.

[]Erlangでrpc

@kuenishiさんからrpc:callを教えてもらった.

Erlang -- rpc

次のようなファイルを用意して,

-module(rpcserver).
-export([testcall/0]).
testcall() ->
    io:format("remote calling", []),
    okay.

一つのTerminalで実行

~/Documents/.../Erlang/rpc $ erl -sname fuga
Erlang R14A (erts-5.8) [source] [64-bit] [smp:4:4] [rq:4] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.8  (abort with ^G)
(fuga@SuzBookPro)1> c(rpcserver).
{ok,rpcserver}

別のTerminalでrpc:callでNodeを指定してこの関数を実行できる.

(tako@SuzBookPro)2> rpc:call(fuga@SuzBookPro, rpcserver, testcall, []).
remote callingokay

io:formatの出力結果が呼び出し側で表示されるのがミソ?

更にerlangモジュールのmemory関数をrpcしてみるとこんなかんじ

(tako@SuzBookPro)3> rpc:call(fuga@SuzBookPro, erlang, memory, []).    
[{total,9551720},
 {processes,874872},
 {processes_used,868264},
 {system,8676848},
 {atom,619969},
 {atom_used,594139},
 {binary,58744},
 {code,5966812},
 {ets,302640}]

[]ErlangでDistributed Programming

Erlang -- Concurrent Programming

rikitakeさんが以前この認証に関する論文を書いていて,その謝辞に西尾さんたちが載っていたのを覚えている.

registerでatomとprocessをひもづけることができて,更に@Hostnameで遠くにあるプロセスとも通信することができる.

erl -sname <name>

によって起動するErlang shellに名前を与えることができて,この名前によってどのErlang nodeにメッセージを送信するか決められる.

register(pong, spawn(tut17, pong, [])).
...
{pong, Pong_Node} ! {ping, self()}

とすることでどのノード(ここではPong_node, fuga@SuzbookProなどのように記述できる)の中のどのprocess(ここではping)にメッセージを送ることができる.


[]Erlangのパターンマッチと比較

-module(tut6).
-export([list_max/1]).
list_max([Head|Rest]) ->
   list_max(Rest, Head).
list_max([], Res) ->
    Res;
list_max([Head|Rest], Result_so_far) when Head > Result_so_far ->
    list_max(Rest, Head);
list_max([Head|Rest], Result_so_far)  ->
    list_max(Rest, Result_so_far).
4> tut6:list_max([1,3,4,5]).
5
5> tut6:list_max([1,3,"suz",5]).
"suz"
6> tut6:list_max([1,3,"suz",aiueo]).
"suz"
7> "aiue" > aiue.
true
8> "a" > "b".
false
9> "ai" > "b".
false
10> "ai" > b.  
true
  • 1つの関数は複数の数の引数をとれる
  • exportでどの引数の数のやつかを指定できる
  • 比較は異なった型同士でもできる.

[]ErlangをEmacsで書くerlang.elの場所

メモ

  • 検索でerlang.elのページを見つけるErlang -- Erlang mode for Emacs
  • でもどこでダウンロードできるかわからない
  • もしかしてErlangをインストールしたらどこかに入ってる?
  • macportでインストールしたerlangはどこにあるんだる
  • spotlightでerlang.elを探す -> みつかる /opt/local/lib/erlang/lib/tools-2.6.6/emacs/erlang.el

2010-11-02

[]RubyのPath

Macでfirewatirっていうモジュールを使おうとしているんだけれども,RubyのPathってみんな何にしているんだろう.


firewatrをインストール

sudo gem install -V firewatir

でfirewatirをインストールでどこにインストールされたのか探すと

.(中略)
/Library/Ruby/Gems/1.8/gems/firewatir-1.6.7/VERSION
/Library/Ruby/Gems/1.8/gems/firewatir-1.6.7/firewatir.gemspec
/Library/Ruby/Gems/1.8/gems/firewatir-1.6.7/README.rdoc
Successfully installed firewatir-1.6.7
1 gem installed
Installing ri documentation for firewatir-1.6.7...
rdoc --ri --op /Library/Ruby/Gems/1.8/doc/firewatir-1.6.7/ri --title FireWatir API Reference --accessor def_wrap=R,def_wrap_guard=R,def_creator=R,def_creator_with_default=R --exclude unittests|camel_case.rb|testUnitAddons.rb --main README.rdoc --quiet lib README.rdoc --title firewatir-1.6.7 Documentation
Installing RDoc documentation for firewatir-1.6.7...
rdoc --op /Library/Ruby/Gems/1.8/doc/firewatir-1.6.7/rdoc --title FireWatir API Reference --accessor def_wrap=R,def_wrap_guard=R,def_creator=R,def_creator_with_default=R --exclude unittests|camel_case.rb|testUnitAddons.rb --main README.rdoc --quiet lib README.rdoc --title firewatir-1.6.7 Documentation
suztomo@suzbookpro.lan ~/Documents/asitano/v01/asitano/test
~/Documents/.../asitano/test $ 

というわけで探すと/Library/Ruby/Gems/1.8/gems/firewatir-1.6.7/lib/firewatir.rbというファイルが見つかるので,firewatrをロードできるようにするために /Library/Ruby/Gems/1.8/gems/firewatir-1.6.7/libを環境変数RUBYLIBに含めてみた.動いた.

んだけれども,モジュールをインストールする都度に"そのモジュールのインストールディレクトリ/lib"を環境変数に設定しないといけない...?

2010-06-20

[]Haskell入門

Haskell-modeがこうしろって言うから従っていたらパースエラーではまっていた.

do ...
  if cond
  then do xxx
  else do yyy

do以外のところのifはこの形式で動くのに,doの中だとif, then, elseを並列にしてはいけない?

if cond
then do xxx
else do yyy

Archive Not Found - Takaki’s web

2010-04-26

[]PyPy translation error (libintl.h) in Mac OS X

PyPy is a python implementation using JIT.

404 Not Found

When I tried to "translate" the PyPy,

python translate.py --opt=2 targetpypystandalone.py

I got error that there is no libintl.h.

[platform:ERROR] /var/folders/iP/iPZKdsuIE881ZiEqvpEGd++++TI/-Tmp-/usession-trunk-0/platcheck_26.c:22:21: error: libintl.h: No such file or directory

Solution

According to no title, I downloaded gettext from http://www.gnu.org/software/gettext/, and configure-make-make-install-ed.

Then the tlanslation worked well. It displayed Mandelbrot fractal during the long execution ( about 30 minutes).


PyPy!

It works.

~/Documents/.../translator/goal $ find /usr -name libintl.h 
/usr/local/include/libintl.h
suztomo@yl-dhcp4.is.s.u-tokyo.ac.jp ~/Documents/LanguageStudy/pypy/pypy-trunk/pypy/translator/goal
~/Documents/.../translator/goal $ python translate.py --opt=2 targetpypystandalone.py

.(omit).

suztomo@yl-dhcp4.is.s.u-tokyo.ac.jp ~/Documents/LanguageStudy/pypy/pypy-trunk/pypy/translator/goal
~/Documents/.../translator/goal $ ./pypy-c 
Python 2.5.2 (74054, Apr 26 2010, 05:04:40)
[PyPy 1.2.0] on darwin
Type "help", "copyright", "credits" or "license" for more information.
And now for something completely different: ``with all appropriate
contextualisationing''
>>>> 46 - 2
44
>>>> 

2010-04-01

[]Twitter Streaming API from Processing

I wrote a Processing class (TwitterStreamingTrack.pde), which helps programmers who want to use Twitter Streaming API from Processing.


Sample Program

Through the Twitter Streaming API, this Processing program receives tweets that match "#nowplaying" or "suztomo".

/*
  TwitterStreamingTrackTest.pde
*/
TwitterStreamingTrack tst;

void setup() {
    size(1200, 800);
    PFont f = createFont("FFScala", 100);
    textFont(f);
    /*
      TwitterStreamingTrack(PApplet parent, String keywords,
                            String username, String password);

    */
    tst = new TwitterStreamingTrack(this, "#nowplaying,suztomo",
                                    "account", "password");
    background(0xFF);
}

void draw() {
    /*
      getNewTweets() returns a new Tweet object (defined below), if exists.
    */
    Tweet t = tst.getNewTweet();
    if (t != null) {
        fill(0x0);
        String msg = t.msg;
        text(msg,250 - int(random(500)), int(random(1000)) - 100);
    }
}

D

In the directory that contains this program (TwitterStreamingTrackTest.pde), are two Processing files (Tweet.pde, TwitterStreamingTrack.pde).

Tweet.pde

/*
  Tweet.pde
*/
public class Tweet{
    public String msg;
    public String scname;
    public String username;
    public String time;

    public Tweet(){
        msg = "";
        scname = "";
        username = "";
        time = "";
    }

    public Tweet(String _msg, String _scname, String _username, String _time) {
        msg = _msg;
        scname = _scname;
        username = _username;
        time = _time;
    }
}

TwitterStreamingTrack.pde

This class requires these two Java libraries (.jar).

/*
  TwitterStreamingTrack.pde
*/
import org.json.*;
import biz.source_code.*;
import processing.net.*;

public class TwitterStreamingTrack {
    private PApplet parent;
    private Client client;
    private int byteBuffersNum = 10;
    private byte[][] byteBuffers = new byte[byteBuffersNum][4096];
    private byte[] currentByteBuffer;
    private int byteBuffersIndex = 0;
    private int byteBuffersStart = 0;
    private int[] byteBuffersSizes = new int[byteBuffersNum];
    private String encoding = "UTF-8";
    private final String twitterStreamingServer="stream.twitter.com";
    private final String twitterStreamingMethod="POST";
    private final int twitterStreamingPort=80;
    private final String twitterStreamingPath="/1/statuses/filter.json";
    private String twitterStreamingAuthUser;
    private String twitterStreamingAuthPass;
    private String authKey;
    private Tweet recentTweet = null;
    private Pattern HTTPResponsePattern = Pattern.compile("(HTTP/1.1 (\\d+).+)");
    private Pattern HTTPBodyPattern1 = Pattern.compile("\r\n\r\n[^{]+\r\n(.*)", Pattern.DOTALL);
    private Pattern HTTPBodyPattern2 = Pattern.compile("[0-9A-Z]\r\n(.*)", Pattern.DOTALL);


    /*
      parent: usually ``this''
      keywords: keyword list, comma separated
    */
    public TwitterStreamingTrack(PApplet parent, String keywords,
                                 String username, String password) {
        twitterStreamingAuthUser = username;
        twitterStreamingAuthPass = password;
        this.parent = parent;
        initClient();
        prepareAuthKey();

        String encoded_keywords = "logcafe";
        try {
            encoded_keywords= java.net.URLEncoder.encode(keywords, encoding);
        } catch (UnsupportedEncodingException e) {
            println(e.toString());
        }
        sendHTTPRequest(encoded_keywords);
        currentByteBuffer = byteBuffers[byteBuffersIndex];
    }

    /*
      This method should be called each frame.
    */
    public Tweet getNewTweet() {
        recentTweet = null;
        checkBytes();
        return recentTweet;
    }

    private void initClient() {
        client = new Client(parent, twitterStreamingServer,
                            twitterStreamingPort);
    }

    private void prepareAuthKey() {
        /*
          http://www.source-code.biz/base64coder/java/
        */
        authKey = Base64Coder.encodeString(twitterStreamingAuthUser + ":" +
                                           twitterStreamingAuthPass);

    }

    private void sendHTTPRequest(String keywords) {
        sendPostRequest("track="+keywords);
    }
    /*
      requestBody is assumed to be already url-encoded (?).
    */
    private void sendPostRequest(String requestBody) {
        String requestLine = twitterStreamingMethod + " "
            + twitterStreamingPath + " HTTP/1.1";
        String hostParam = "Host: " + twitterStreamingServer + ":" +
            twitterStreamingPort;
        String userAgentParam = "User-Agent: curl/7.19.4 (universal-apple-darwin10.0) libcurl/7.19.4 OpenSSL/0.9.8l zlib/1.2.3";
        String authParam = "Authorization: Basic " + authKey;
        String acceptParam = "Accept: " + "*"+ "/"+"*";
        String contentLengthParam = "Content-Length: " + requestBody.length();
        String contentTypeParam = "Content-Type: application/x-www-form-urlencoded";
        sendln(requestLine);
        sendln(authParam);
        sendln(userAgentParam);
        sendln(hostParam);
        sendln(acceptParam);
        sendln(contentLengthParam);
        sendln(contentTypeParam);
        sendln("");// empty line before request body
        sendln(requestBody);
        sendln("");
        sendln(""); // end of request, that is two new line
    }

    private void sendln(String line) {
        client.write(line + "\r\n");
    }

    private void clearByteBuffer(byte[] buf) {
        for (int i = 0; i<buf.length; ++i) {
            buf[i] = 0;
        }
    }


    private void checkBytes() {
        if (client.available() > 0) {
            int byteCount = client.readBytes(currentByteBuffer);
            if (byteCount > 0 ) {
                String response;
                byteBuffersSizes[byteBuffersIndex] = byteCount;
                //                println("received: " + byteCount + " to buffer#" + byteBuffersIndex);

                int r =  processByteBuffers();
                if (r == 0) {
                    byteBuffersStart = (byteBuffersIndex+1)%byteBuffersNum;
                }
                byteBuffersIndex = (byteBuffersIndex+1)%byteBuffersNum;
                currentByteBuffer = byteBuffers[byteBuffersIndex];
                clearByteBuffer(currentByteBuffer);
            }
        }
    }

    private int processByteBuffers() {
        int ssize = 1<<13;
        byte[] s = new byte[ssize];
        int i;
        int k = byteBuffersStart;
        String response;
        /*
          append butters to the first.
          buteBuffersStart = 7, byteBuffersIndex = 0.
          - byteBuffers[7] = {a, b, c}  (s)
          - byteBuffers[8] = {k, l}
          - byteBuffers[9] = {j}
          - byteBuffers[0] = {r, t, i}
          - byteBuffers[1] = {a, o}

          => s = {a, b, c, k, l, j, r, t, i, a, o}

        */
        for (i=0; i<ssize; ++i) {
            s[i] = 0;
        }
        for (i=0; i<byteBuffersSizes[byteBuffersStart]; ++i) {
            s[i] = byteBuffers[k][i];
        }
        k = (k+1) % byteBuffersNum;
        i = byteBuffersSizes[byteBuffersStart];
        //        println("startBuffer's size: " + i);
        if (byteBuffersIndex != byteBuffersStart) {
            while(true){
                byte[] b = byteBuffers[k];
                int bs = byteBuffersSizes[k];
                for (int j=0; j<bs; ++j) {
                    s[i] = b[j];
                    ++i;
                    if (i>=ssize) {
                        // reset the buffer, but doesn't update recentTweet
                        return 0;
                    }
                }
                //                println("appended size:" + bs);
                if (k == byteBuffersIndex) break;
                k = (k+1)%byteBuffersNum;
            }
        }
        try {
            response = new String(s, encoding);
        } catch (UnsupportedEncodingException e) {
            response = "encoding error";
        }
        return processHTTPResponse(response);
    }

    private int processHTTPResponse(String response) {
        Boolean ret;
        String responseBody;
        String statusLine, statusCode;
        Matcher matcher;
        matcher = HTTPResponsePattern.matcher(response);
        // matches the first occurance.
        if (matcher.find()) {
            statusLine = matcher.group(1);
            statusCode = matcher.group(2);
            if (!statusCode.equals("200")) {
                println("Error: status line is " + statusLine);
                return -1;
            }
        }
        matcher = HTTPBodyPattern1.matcher(response);
        if (!matcher.find()) {
            matcher = HTTPBodyPattern2.matcher(response);
            if (!matcher.find()) {
                return -1;
            }
        }
        responseBody = matcher.group(1);
        return processHTTPResponseBody(responseBody);
    }

    private int processHTTPResponseBody(String responseBody) {
        String twitScreenName, twitRealName;
        JSONObject j, user;
        String twitPostedTime;
        String twitText;

        try {
            //            println(responseBody);
            j = new JSONObject(responseBody);
            // if an exception occurs, go to checkBytes.

            twitText = j.getString("text");
            user = j.getJSONObject("user");
            twitScreenName = user.getString("screen_name");
            twitRealName = user.getString("name");
            twitPostedTime = j.getString("created_at");
            recentTweet = new Tweet(twitText, twitScreenName,
                                    twitRealName, twitPostedTime);
        } catch(JSONException e) {
            return -2;
        }
        return 0;
    }
}


References