JavaScript this

<script>
 var Member = function(firstName, lastName){
//thisはコンストラクタによって生成されるインスタンスを表す。
     this.firstName = firstName;
     this.lastName = lastName;
     this.getName = function(){
         return this.lastName + ' ' + this.firstName;
     }
 };

 var mem = new Member(' Jhon', 'Paul');
 document.writeln(mem.getName());
</script>

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

オブジェクト指向 JavaScript1

<script>
 //JavaScriptのオブジェクト指向はプロトタイプベースのオブジェクト指向であり
 //クラスベースのオブジェクト指向ではない

 // 「クラス」を定義
 var Member = function(){};

 //インスタンス化
 var mem = new Member();//JavaScriptでは関数にクラスとしての役割を与えている
 //new演算子によってオブジェクトを制し得することを想定した関数オブジェクトのことを
 //コンストラクタと言っている。
 //Member関数がコンストラクタにあたる。
</script>

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

JavaScript 高階関数

<script>
 //高階関数arrayWalkを定義
 //引数に与えられた配列dataの内容を、指定されたユーザ定義関数fの規則に従って順番に処理するための高階関数
 function arrayWalk(data, f){
     for (var key in data){
         f(key, data[key]);
     }
 }

 //配列を処理するためのユーザ定義関数
 function showElement(key, value){
     document.writeln(key + ':' + value);
 }

 var ary = [1, 2, 4, 8, 16];
 arrayWalk(ary, showElement);
</script>

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

JavaScript arguments

<script>
 function printf(format){
     //引数の2番め以降を順番に処理
     for (var i = 1; i < arguments.length; i++){
         var pattern = new RegExp('\\{' + (i - 1) + '\\}', 'g');
         format = format.replace(pattern,arguments[i]);
     }
     document.writeln(format);
 }
 printf('こんにちは、{0}さん。私は{1}です。', 'tanaka', 'yamada');
</script>
 
<script>
 //printf()は第一引数で指定された書式文字列に含まれるプレイスホルダ(パラメータの置き場所:{1},{2},...)を第二引数以降の値で置き換えたものを出力する関数
 printf('hello,{0} Im{1}','Jhon', 'Mary');
</script>

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

JavaScript 型

<script>
 var num = 1;
 document.writeln(typeof num);
 var str = 'こんにちは';
 document.writeln(typeof str);
 var flag = true;
 document.writeln(typeof flag);
 var ary = ['JavaScript', 'Ajax', 'ASP.NET'];
 document.writeln(typeof ary);
 var obj = {x:1, y:2};
 document.writeln(typeof obj);
</script>

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

JavaScriptでのHelloWorld

<html>
    <head>
        <meta http-equiv="Content-Type" content=""text/html; charset="UTF-8"/>
        <title>Hello,World!</title>
    </head>
    <body>
        <pre>
            <script type="text/javascript">
                <!--
                     //document.writelnは、指定された文字列を表示するための命令
                     document.writeln('Hello,World!');
                   //-->
            </script>
            <noscript>JavaScriptが利用できません。</noscript>
        </pre>
    </body>
</html>

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで

Lisp覚書

関数

Lispで関数を呼び出すには関数名をカッコで囲む。関数にパラメータを渡したければそれも一緒にカッコに入れる。

(defun function_name (arguments)
 ...)

まず関数の名前と引数を記し、その後ろに関数を実装するコードを書いていく。

トップレベル定義

Lispではグローバルに定義される変数をトップレベル定義と呼ぶ。新しいトップレベル定義はdefparameter 関数で作ることができる。

(defparameter *small* 1)

アスタリスクはearmuffsと呼ばれる習慣。ローカル変数と区別するのに便利。

REPL(read-eval-printループ)の機能

式をタイプするとLispはそれを直ちに評価して結果を返す。CLISPを終了するときは(quit)とタイプする。
Lispでプログラムを書いているときには、わざわざスクリーンに値を表示させるような関数を書くことは少ない。関数内で表示せずとも返した値は自動的にREPLの機能によって表示される。
他の言語でreturnと書くようなところをLispでは関数の最後の式が自動的に返されるのでその必要がない。

数当てゲーム(バイナリサーチ)

(defparameter *big* 100)
(defparameter *small* 1)

(defparameter *big* 100)
(defparameter *small* 1)

(defun guess-my-number()
  (ash (+ *small* *big*) -1));;(+ *small* *big*)は2つの変数の値を足すコード。加算結果はash関数に渡される。ashは渡された数値を2進数で考え、ビットをシフトする。第二引数に1を渡すと左シフト、-1を渡すと右シフトする。

;;関数の呼び出し
(guess-my-number);;50

(defun smaller()
  (setf *big* (1- (guess-my-number)));;setfでグローバル変数*big*の値を変える。guess-mynumberを呼び*small*と*big*を足して右シフトした値を得て、それを引数として1を引いた関数1-(1-は関数名で、「1を引け」と動詞のように読むと良い)を呼び出す。
  (guess-my-number));;smaller関数によって新しい推測値を表示させるために再びguess-my-numberを呼ぶ。

(defun bigger()
  (setf *small* (1+ (guess-my-number)))
  (guess-my-number))


;;実行
(bigger)
;;75
(smaller)
;;62
(smaller)
;;56

;;グローバル変数をリセットするstart-over
(defun start-over()
  (defparameter *small* 1)
  (defparameter *big* 100)
  (guess-my-number))

(start-over);;50

ローカル変数の定義

ローカル変数の定義にはletコマンドを使う。

(let (変数定義)
     ...本体...)

ローカル関数の定義

ローカル関数の定義にはfletコマンドを使う。最初の2行で関数を宣言する。この関数はfletの本体の中で使える。

(flet ((関数名 (引数)
      ...関数本体...))
  ...本体...
  ||<)

一つの引数nを取るローカル変数fを定義し、本体の中で5を引数として関数fを呼び出す。
>|lisp|
(flet ((f (n)
      (+ n 10)))
     (f 5));;15

コードモードとデータモード

Lispではデフォルトではコードモードになっている。
コードモードにいるとき、その入力はフォームの構造に沿っていなければならない。
フォームとは最初の要素が特別のコマンドになっているようなリストのこと。
フォームを読む際に、リストの残りの要素はすべて引数として関数に渡される。

データモードで書かれてものはすべてデータとして扱われる。
データは「実行」されない。
データモードで固定した情報をデータとしてコード中に埋め込んでおくことができる。
Lispにデータモードであることを教えるにはシングルクオートをリストの手前につける。
これを「クオートする」という。
クオートによって「次に来るのはコマンドじゃないよ、プログラムで使うデータの塊だよ」とLispに教える。

コンスセル

Lispのリストはコンスセルでつなぎ合わされている。
コンスセルはリンクリストである。

cons関数

2つのデータをLispプログラムの中で結び付けたいときに使う。
cons(constructの略)を呼ぶとLispコンパイラはそれぞれのオブジェクトへの参照を入れておく、コンスセルのための小さなメモリをアロケートする。
例えばシンボルchickenをシンボルcatとくっつけると、consはひとつのコンスセルを返す。

(cons 'chicken 'cat);;(CHICKEN . CAT)

コンスセルの表現は繋げられた要素の間にドットをおいて全体をカッコで囲んだもの、リストとは異なる。
Lispではコンスセルの連なりとリストは全く同じもの。

(cons 'pork (cons 'beef (cons 'chicken())));;(PORK BEEF CHICKEN)

空のリスト()はCommon Lispではシンボルnilと同じもので、リストの終端は空のリストである。
3つの要素をコンスすれば、3つの要素を持つリストになる。

car

関数car(Contents of the Address part of the Register)はセルの最初のスロットにあるデータを取り出すのに使う。

(car '(pork beef chicken));;PORK

関数cdr(Contents of the Decrement part of the Register)は2番めのスロットの値を取り出すのに使う。リストの場合はリストの残りの部分を返す(リストの最初の要素を取り除く)。

(cdr '(pork beef chicken));;(BEEF CHICKEN)

list

list関数は長いリストを一気に作ることができる。

(list 'pork 'beef 'chicken);;(PORK BEEF CHICKEN)

空と偽

条件式の評価において空のリストは偽として扱う。

progn

prognコマンドを使って一つの式の中に余分なコマンドを押し込むことができる。最後の式の評価値をフォーム全体の値として返す。progn 特別式は、任意の数の引数を受け付け、先頭の引数から順に全ての式を評価する。

(defvar *number-was-odd* nil)
(if(oddp 5)
         (progn (setf *number-was-odd* t)
                'odd-number)
         'even-number);;==>ODD-NUMBER
*number-was-odd*
==>T

whenとunless

ifの中でひとつ以上の処理を書きたいときにprognを使わなくても、whienやunlessを使えば条件が真の時に囲まれた式をすべて実行する。

(defvar *number-is-odd* nil)
(when (oddp 5)
      (setf *number-is-odd* t)
      'odd-number)
==>ODD-NUMBER

*number-is-odd*
==>T

(unless (oddp 4)
        (setf *number-is-odd* nil)
        'even-number)
==>EVEN-NUMBER

*number-is-odd*
NIL

cond

condは複数の節を引数として受け取る。各節の先頭に条件をチェックする述語があり条件が成立した場合残りの式を評価する。条件が不成立であれば、次の節に移る。条件は常に上から順に検査され、最初に条件を満たしたものがcondの返り値になる。

(defvar *arch-enemy* nil)
(defun pudding-eater (person)
  (cond ((eq person 'henry) (setf *arch-enemy* 'stupid-lisp-alien)
         '(curse you lisp alien - you ate my pudding))
        ((eq person 'johnny)(setf *arc-enemy* 'useless-old-johnny)
         '(i hope you choked on my pudding johnny))
        (t '(why you eat my pudding stranger ?))))
(pudding-eater 'johnny)
==>(I HOPE YOU CHOKED ON MY PUDDING JOHNNY)

*arc-enemy*
==>USELESS-OLD-JOHNNY

(pudding-eater 'george-clooney)
==>(WHY YOU EAT MY PUDDING STRANGER ?)

case

caseでは比較対象になる値を並べて置くだけで良い。

(defun pudding-eater(person)
  (case person
    ((henry) (setf *arch-enemy* 'stupid-lisp-alien)
     '(curse you lisp alien - you ate my pudding))
    ((johnny) (setf *arch-enemy* 'useless-old-johnny)
     '(i hope you choked on my pudding johnny))
    (otherwise '(why you eat my pudding stranger ?))))

andとorを使って条件分岐を行う

andやorは条件判断にも使うことができる。orに与えられた式のうち真になるものが見つかったら直ちに、Lispは残りの式を評価せずにすぐに心を返す。同様に、andに与えられた式のうち偽になるものが見つかったら直ちに残りを評価する手間をかけずに偽値を返す。次のコードはある数が偶数の場合だけグローバル変数を真値にセットする。

(defparameter *is-it-even* nil);;*IS-IT-EVEN*
(or (oddp 4) (setf *is-it-even* t));;T
*is-it-even*;;T

;;奇数を与えると変数の値が変わらないことがわかる。
(defparameter *is-it-even* nil);;*IS-IT-EVEN*
(or (oddp 5) (setf *is-it-even* t));;T
*is-it-even*;;NIL

Land of Lisp

Land of Lisp

perl CGI

以下のHTMLファイルは/cgi-binディレクトリにあるCGIプログラムquestionnaire.cgiを呼び出す

<!DOCTYPE HTML PUBLIC "-//W3//DTD HTML 4.0//EN">
<!-- 簡単なアンケートのHTML questionnaire.html-->
<html>
    <head>
        <title>アンケートの例</title>
    </head>

    <body>
        <h1>アンケートの例</h1>

        <p>次の質問にお応えください</p>

        <form action="cgi-bin/questionnaire.cgi" method="post">
            <dl>
                <dt>お名前</dt>
                <dd><input type="text" name="name" value=""></dd>
                <dt>最もよくお使いになっているOS</dt>
                <dd>
                    <ul>
                        <li><input type="radio" name="os"
                                  value="Windows"
                                  checked>Windows</li>
                            <li><input type="radio" name="os"
                                       value="Linux">Linux</li>
                            <li><input type="radio" name ="os"
                                       value="FreeBSD">FreeBSD</li>
                            <li><input type="radio" name ="os"
                                       value="Solaris">Solaris</li>
                            <li><input type="radio" name="os"
                                       value="MacOS">MacOS</li>
                            <li><input type="radio" name="os"
                                       value="Other">その他</li>
                    </ul>
                </dd>
            </dl>
            <p>
                <input type="submit" name="send" value="送信"><br>
                <input type="reset" value="リセット">
            </p>
        </form>
    </body>
</html>

CGIモジュール

#!/usr/bin/perl
#このcgiプログラム・スクリプトはUNIXでは実行権限を与えておく必要がある
#(chmod a+x questionnaire.cgi)

#アンケート処理CGIプログラム・スクリプト
#ユーザーが使っているOSの合計を調べる
#questionnaire.cgi

#モジュール読み込み
use CGI;
$query = new CGI;

#統計ファイルの存在チェック
if(-f "../data/statistic.log"){
    #存在するならファイルをオープンする。失敗したらエラーページを表示
    open(F, "../data/statistic.log")|| &error("ファイル /data/statistic.logをオープン出来ません($!)。\n");
    while(<F>){
        #改行文字を除く
        chomp();
        #名前とOSを取得
        ($name, $os) = split(/\t/);
        #配列@nametotalに名前を蓄積
        push(@nametotal, $name);
        #ハッシュ$ostotalに合計値を蓄積
        $ostotal{$os}++;
    }
    close(F);
}

#アンケートを解析
#名前からタブ文字を取り除く(タブ文字をファイルのでーたの区切りとして使っているため)
$name = $query->param('name');
$name =~ s/\t//g;
#名前に重複がないか解析
foreach(@nametotal){
    if($_ eq $name){
        #等しい物があった時にはエラーページを表示
        &error("お名前 $name はすでに登録されています\n");
    }
}

#変数OSに入っているOS名をキーとする値をインクリメント
$ostotal{$query->param('os')}++;

#記録に追加。失敗したらエラーページを表示
open(F, ">>../data/statistic.log")|| &error("ファイル /data/statistic.logに書き込めません($!)。\n");
print F $name, "\t", $query->param('os'), "\n";
close(F);

#表示 (UNIXではEUC-JPとする)
print $query->header(-charset=>'EUC-JP'),
    $query->start_html(-title=>"現在のアンケート結果");
print "<h2>使用OS</h2>\n";
print "<ul>\n";
#合計数を表示
print "<li><strong>$os</strong>: $count</li>\n" while(($os, $count) = each(%ostotal));
print "</ul>\n";
print $query->end_html();

sub error{
    #エラーページ表示のサブルーチン
    my($message) = @_;

    print $query->header(-charset=>'EUC-JP'),
        $query->start_html(-title=>"エラー");
    print "<h1>エラーが発生しました</h1>\n";
    print $message;
    print $query->end_html();
    #異常終了
    exit(1);
}

初めてのPerl 第6版

初めてのPerl 第6版

perl 簡単なWebブラウザ

#簡単なWebブラウザ
#browser.pl

#モジュールの使用宣言
use IO::Socket;

#URLを入力
print "URLを指定してください>";
$url = <STDIN>;

#URLをホスト名とファイルパスに分割
chomp($url);
if($url =~ /http:\/\/([^\/]+)(\/.*)/){
    $host = $1;
    $file = $2;
}else{
    die "そのURLには対応していません。\n";
}

#ソケットオブジェクト作成
$client_socket = new IO::Socket::INET(
    PeerAddr => $host,
    PeerPort => 'http',
    Proto => 'tcp',
    TimeOut => '5'
);
unless($client_socket){
    print "Socket Error:$!\n";
}

#入力をサーバーに送信
print "$host $file" . "\n";
print $client_socket "GET $file HTTP/1.0\n\n";

#出力を取得し、表示(複数行が返ってくるので、取り終わるまで繰り返す)
while($receive = <$client_socket>){
    print $receive;
}

#ソケットを閉じる
$client_socket->close();

#実行結果
# $ perl browser.pl 
# URLを指定してください>http://cruel.org/
# cruel.org /
# HTTP/1.1 200 OK
# Date: Fri, 08 Jul 2016 07:36:18 GMT
# Server: Apache/2.2.11 (Unix) PHP/5.2.9 mod_ssl/2.2.11 OpenSSL/0.9.8e
# Last-Modified: Wed, 15 Apr 2009 10:28:21 GMT
# ETag: "707c09-24-4679568177b40"
# Accept-Ranges: bytes
# Content-Length: 36
# Connection: close
# Content-Type: text/html; charset=UTF-8

# hello
# </body>
# </html>

初めてのPerl 第6版

初めてのPerl 第6版

perl ソケット

サーバースクリプト

#クライアントからの文字入力を受けてそれをそのまま返すサーバースクリプト
#echoserver.pl

#モジュールの使用宣言
use IO::Socket;

#ソケットオブジェクト作成
$server_socket = new IO::Socket::INET(
    LocalPort => '10000',
    Proto => 'tcp',
    Listen => 5,
    Reuse => 1
);
unless($server_socket){
    print "SOcket Error:$!\n";
}

#待機
$client_socket = $server_socket->accept();

#クライアントからの入力を表示
    while($string = <$client_socket>){
        print "受理:$string";
    }

#ソケットを閉じる
$client_socket->close();
$server_socket->close();

クライアントスクリプト

#文字入力をサーバーに送るクライアントスクリプト
#echoclient.pl

#モジュールの使用宣言
use IO::Socket;

#ソケットオブジェクト作成
$client_socket = new IO::Socket::INET(
    PeerAddr => 'localhost',
    PeerPort => '10000',
    Proto => 'tcp',
    TimeOut => '5'
);
unless($client_socket){
    print "Socket Error:$!\n";
}

#入力をサーバーに送信
while($string = <STDIN>){
    if($string =~ /^QUIT/){
        #QUITという文字列で始まる入力があると終了
        last;
    }
    print $client_socket "$string";
}

#ソケットを閉じる
$client_socket->close();

コマンドプロンプトウインドウを2つ起動し、まずはサーバースクリプトを実行する。
別のコマンドラインからクライアントスクリプトを実行するとこのスクリプトがサーバーに接続される。クライアント側で文字列を入力しenterキーを押すとサーバー側にその文字列が表示される。

実行結果

サーバー側

$ perl echoserver.pl 
受理:from client
受理:hello

クライアント側

$ perl echoclient.pl 
from client
hello
QUIT

初めてのPerl 第6版

初めてのPerl 第6版

perl fork関数

#forkを使って2つの処理を作る
#fork関数を使って処理を分岐し、親プロセスと子プロセスでそれぞれ異なる文字列表示を実行する
#fork.pl

if($pid = fork()){
    #親プロセス
    for($i = 1; $i <= 3; $i++){
        print "親プロセス\n";
        sleep(3);
    }
    waitpid($pid, 0);
}
elsif(defined $pid){
    #子プロセス
    for($i = 1; $i <= 5; $i++){
        print "子プロセス\n";
        sleep(1);
    }
}else{
    die "fork出来ません:$!\n";
}
#実行結果
# 親プロセス
# 子プロセス
# 子プロセス
# 子プロセス
# 子プロセス
# 親プロセス
# 子プロセス
# 親プロセス

初めてのPerl 第6版

初めてのPerl 第6版

perl 外部プログラムの実行

#system関数を使ってunixのlsコマンドを実行する
#shellに関数による実行
#shell.pl

#lsを実行
system("ls");

初めてのPerl 第6版

初めてのPerl 第6版

perl 現在のディレクトリのファイル一覧を表示する

#現在のディレクトリのファイル一覧を表示する
#ディレクトリの内容を読み込み表示する
#readdir.pl

#現在のディレクトリ(.)をオープンする
opendir(DIR, ".") || die ".をオープンできません:$!\n";

#配列に読み込む
@files = readdir(DIR);

#クローズする
closedir(DIR);

#表示
foreach(@files){
    print "$_\n";
}


#実行結果
# $ ls
# readdir.pl	test1.txt	test2.txt	test3.txt
# $ perl readdir.pl 
# .
# ..
# readdir.pl
# test1.txt
# test2.txt
# test3.txt

初めてのPerl 第6版

初めてのPerl 第6版