node.js

jsのローカル実装です。Linux系のOSなら簡単につかえるのでつかってみてください

node.jsってなんなの

pythonperlみたいにPC上でJavascriptを走らせるJavascriptの実行環境

$ node test.js

みたいに走る。

hello, world

console.log("Hello, World!");

これを、test.jsとかで保存して

$ node test.js

もしくは、直接インタプリタ

$ node
>console.log("Hello, World!");
"Hello, World!"

みたいになる気がします。

Javascriptでしょ?なにができるの?

Javascriptですが、何でもできます。OSのAPIを直接たたくAPIが整備されているので、ファイルをいじったり、HTTPサーバーを立てることもできます。
どれくらいというと、Perlとかができることは大体できるんじゃないでしょうか?
使える機能は以下URLを参照(ドキュメントは Node.js 4.9 のもの)
http://nodejs.jp/nodejs.org_ja/docs/v0.4/api/

なにがいいの?

1、唯一ブラウザ上で動くJavascriptがサーバー上でも使える。つまり今からはじめるなら、サーバーとクライアントばらばらに2つの言語を覚えなくてもJavascriptだけ覚えれば複雑なこともそれなりにできる。
2、なんだかんだでいろいろ変わった書き方(便利な書き方)のできるJavascriptでデスクトップアプリケーションが書ける
3、Javascriptの楽な勉強環境になる(ブラウザの面倒なデバッガで勉強しなくてもいい!
4、nonblockingioなのでry(そんなこと知ってる人はこの記事読んでないと思うので略

あと

描いてて思ったけど、GUIのライブラリってあるのかな、SDLとか。

たとえば

今日かいたWebサーバーのコード。ただしCoffeeスクリプトからの自動生成(ぉぃ
中身はdataRootにあるファイルをhash.jsonのハッシュにアクセスがあれば渡すというただのWebサーバー

(function() {
  var dataRoot, fs, hash, http, url;
  fs = require('fs');
  http = require('http');
  url = require('url');
  hash = JSON.parse(fs.readFileSync('hash.json', 'utf-8'));
  dataRoot = '/home/dasoran/cast/';
  http.createServer(function(req, res) {
    var parsedUrl, thisHash;
    parsedUrl = url.parse(req.url);
    thisHash = parsedUrl.pathname.slice(1, -1);
    if (hash[thisHash] === void 0) {
      console.log("debug:" + thisHash);
      res.writeHeader(404);
      res.end('err');
      return;
    }
    return fs.readFile(dataRoot + hash[thisHash][0], function(err, data) {
      if (err) {
        throw err;
      }
      res.writeHeader(200, hash[thisHash][1]);
      return res.end(data);
    });
  }).listen(8124);
}).call(this);

僕がプログラミング始めたきっかけ

なにやら中高生対象といわれつつ、大学生の皆さんも書かれているので便乗してみる。

PCをはじめたきっかけ

えーっとPCをはじめたのは小5のときです。母親が内職でHTMLを始めるということで、PCから回線から一式買ったところから始まりました。
当時から機械ものに興味があった私だったので、当然食いついたわけですが、しばらくするとWindows95の某NECの98のノートを頂いてHTMLをいじり始めました。ちなみに、このとき内職用に調達したマシンはMeで回線は田舎だったのでダイアルアップでした。

OSASKコミュニティに出会うまで

中1くらいまではひたすらHTML書いたり、隠しページ探し(リンクを探したりするやつ)をやったり探したりしていました。またネトゲにもはまった時期ですw
中2くらいから平行してhspやCに触り始めたのですが、Cはポインタで躓いて某ポインタ本などを買ったりしましたがなかなか進めずふらふらしていました。

OSASK

中3のはじめに、hspからおそらくあっきぃさんのページをたどってOSASKというOSのコミュニティ、IRCへ行き着きます。ここで川合さんと出会いました。某OS本の著者の方です。
このとき、OSを作りたい!と行ったのですが、ここでたまたまほかにOSを作りたいといってきたうっちゃんさんとIPLの書き方などを教わっていました。そのときはアセンブリを一週間で教わったのですが川合さん、本当に教え方がうまいです。その後Cの基本的なところを3日程度でまとめました。アセンブリからやったのでポインタがすごい簡単で驚きました。
そして、たまたまこのときOS本の執筆を始めるタイミングで、その後1年OS本の校正という名の本をタダで読ませていただくありがたい立場に立たせてもらい、プログラミングを学びました。ちなみにこの1年アセンブリにこだわり、その後フルアセンブリでOSを書くとかいってたのもこの辺の時期です。FPGAなどに触れたりCPUの創りかたを読んだ(というか頂いた)のもこの辺ですね。

高専

翌年、当然のごとく国立高専に落ち、某私立高専へ。そこで黙々とハードとOSの開発をやるつもりが(自己紹介でかなり浮いた)ロボコン部へなぜか入ることに。ちなみに回線の都合でこのころからOSASKコミュニティから離れていきます。
その後2年間アナログ回路や組み込みのコードを書きます。毎日オシロの前に座っていました。また、結局FPGAは挑戦しようとしてなかなかできなった時期でもあります。
このとき、平行して画像解析やニューラルネットワークなどに関しても調べたりします。教員に書籍を借りたりして簡単な画像解析プログラムを書いたりしていました。また、現筑波大の某CPUつくってるひとにいわれてアセンブラをCで書いたりもしました。ええ、文字列処理系の関数を使って4重ポインタとかになってましたw今思うといろいろおかしいポインタ厨でした。LLとかは一切触れませんでした。

大学

高専3年、浪人と2年ブランクをあけて大学1年からTwitterに影響されプログラミングを再開しました。といっても浪人末期にFPGAボードを買ってアナログディスプレイになんか写したり、某CPUの人にイベントドリブンなプロセッサのアセンブラ(とは呼べないなにか)を書かされたりはしていましたが。いろいろライブラリや新しい言語、勉強会などに参加し始めたのもこのあたりです。
如何に自分がおろかだったか思い知らされました。世には多くの便利なライブラリや便利な言語があり、完全にCの基本文法+標準ライブラリで書いていた私にはまったく驚きの世界でした。秋にWinPhone7のバイトでC#Pythonを始め、その後今年の初めにJavaScriptをはじめて今に至ります。

まとめ

えーっと独学期間長すぎです。大体バカですね。もっと情報あつめとけと。最近はLLもCも適所適材ということで積極的に新しい言語に手を出そうとしつつ仕事で時間がががといった感じです。Rubyとかやりたいですね。あとF#も気になってます。
また、いろいろ学んだ今言うのですが、プログラミング始めるならいまならC#ですね。昔アセンブリを進めていた時代が私にもありましたw@pi8027さんごめんなさい>_< ただ、がっつり組み込み的なCもやるならアセンブリ、やっといて損はないと思います。いまだに嫌いじゃないです。

触った言語

  1. x86asm じつはMMXとか使えません(ぁ。1年位のめりこみました。ゲーム作ったり。ただしOSASKAPIで。
  2. x86機械語 CPUの創りかた読んだ後に少し調べた程度
  3. ARM機械語 GBAで少し触った程度
  4. PICasm わが部の主力マイコンだったので2年がっつりやりました。もうやりません。
  5. AVRasm PICの代わりに導入したかった。結局自分だけでつかって電源逆刺しして8個まとめて焼いた石
  6. C 2年くらい主力でやってた。といってもC++のクラスとか導入してBetterCで使っていましたが。
  7. C++ 継承とかちゃんと調べたのは去年。StringとかVectorとかいいですよね。でも闇の軍団こわいです(ぁ
  8. Python 最近の主力。DjangoといっしょにWebのバックエンドでつかってます。出会いは某むりなバイトでGAEと。
  9. C# 某無理なバイトで使いました。ただ、C系のようでCじゃないこれ!というインパクトはすごかったです。実は自分の常識を破るのに一役かった子。そろそろ何か書いてあげたい
  10. Javascript 最近仕事でがりがり書いてる子。3ヶ月くらいこの子しか書いてない。思いのほかできるけど、重たい。というかまさかこんなにいろいろできると思ってなかった。
  11. Java Android開発で触った。

さいごに

まともなプログラムは最近書き始めた私ですが、いまはWebサービスを作るお仕事をしています。そのうち発表しますが、やっぱりプログラミング楽しいですw
ただ、やはり多くの方と触れ合いながらやったほうが楽しいし、さまざまな情報も集まるので、自分みたいに組み込みの世界の人とか、独学の人もひとまず勉強会にふらふら行ってみたりすると新しい世界が見えるかもしれません。

最近やっていること

えーっと久しぶりにブログかいてなんでこいつWebやってるんだ?ってなった人もいるかもしれないので、最近やっていることを列挙しときます。
最近は、言語的には
Python(+Django
Javascript(+jQuery
とかばりばりWeb系やってます。またJavascriptと関連して
HTML5canvas
とかもがっつりやってます。
あと、言語とかじゃないですが
Tokyo tyrant
とかも使ってたりします。
それから
・TwitterAPI(OAuth)
とかもたたいたりしてます。


まぁ大体今やっている事業で使うからやってるのですが、最近canvasへのハマりかたはやばいです。正直たのしい。
またJavascriptの構文もたのしいです。なんでもつっこめて。でも;ないくらいはさすがにエラー出して、逆に怖い・・・w

でも、やっぱりCとかでポインタゴリゴリやるのが好きというか、ポインタは友達なので、その辺ごりごりやってTwitterAPIたたいてみるかも。
そんな最近。

firefoxとchromeのcanvas実験

おひさしぶりです。いきてます。そらんです。
最近HTML5canvasをいじってます。そこで気付いたことがあったので書きます。というか、ネタはすごい勢いで増えてるんですが、エントリを書く暇がないw

本題なのですが、canvasに画像を30fpsで描画するコードを書きました。
それを書いていてわかったことは、
ChromeはdrawImageを実行するたびにRAMを確保する。
FirefoxはsrcにURLをセットしてダウンロードさせているときにRAMを確保する
という挙動をすることです。どちらも本来のサイズよりかなり大きいです。そして30fpsで動かすと、これらがガベージコレクションが追い付かないまま進んでしまうので、すぐメモリを使いきってChromeならcanvasをロックして一切描画できなくなってしまったり、Firefoxならダウンロードが止まったり、ブラウザそのものが落ちたりします。
ここで、Firefoxは、500枚ダウンロードして、20秒待って…というコードをかいたところガベージコレクションが追い付くようになり、目的の挙動をするようになりました。
ただ、Chromeのほうはcanvasそのものへの制約なので、連続的なアニメーションを避ける以上の回避策は今の実装ではなさそうです。

ちなみにFirefoxはdrawImage中、とても安定して動作していました。

以下に、Firefoxでまともに動くCodeを。Chromeだと、単純ダウンロードの場合でもこの場合でも同じようにRAMを使いきった段階でcanvasがロックされてしまいます。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>Hello, Woeld!</title>
		<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js"></script>
		<script type="text/javascript">
		<!--
			$(document).ready(function(){
				init();
				
			});
			
			//-----
			//Initializing
			//-----
			function init(){
				canvas = document.getElementById('main');
				if ( ! canvas || ! canvas.getContext ) {
					return false;
				}
				ctx = canvas.getContext('2d');
				ctx.fillStyle = 'rgb(255, 255, 255)';
				
				loaded = 0;
				for(var i=0; i<1000; i++){
					layers[i] = new Layer();
					layers[i].setImage("movie/" + ("0000"+(i + 501)).slice(-5) + ".jpg",0,0,640,360,1);
					layers[i].img.onload = function(){
						loaded++;
						$("p").html("loaded image:"+loaded);
						if(loaded == 1000){
							starttimer();
							$("p").html("loaded image:"+loaded+"nya");
							starttimer2();
						}
					}
				}
			}
			firsttimer = 0;
			
			function starttimer(){
				if(firsttimer == 0){
					var timer;
					timer = setTimeout("starttimer()", 20000);
					firsttimer = 1;
				} else {
					for(var i=loaded; i<loaded + 500; i++){
						layers[i] = new Layer();
						layers[i].setImage("movie/" + ("0000"+(i + 501)).slice(-5) + ".jpg",0,0,640,360,1);
						layers[i].img.onload = function(){
							loaded++;
							$("p").html("loaded image:"+loaded);
							if(loaded%500 == 0){
								$("p").html("loaded image:"+loaded+"nya");
								if(loaded == 9000){
									
								} else {
									timer = setTimeout("starttimer()", 20000);
									firsttimer++;
								}
							}
						}
					}
				}
			}
			
			function starttimer2() {
				setInterval("onTimerEvent()", 1000/30);
			}
			
			var t2 = -1;
			//var t2 = 2000;
			function onTimerEvent(){
				
				
				if(t2>loaded){
					t2=0;
				}
				t2++;
				
				
				//-----
				//Animation test with hatune miku!
				//-----
				var top = t2 + 1;
				
				$("div").html(t2);
				
				//-----
				//Drawing layers
				//-----
				
				ctx.globalAlpha = layers[top].alpha;
				ctx.drawImage(
					layers[top].img,
					layers[top].x,
					layers[top].y,
					layers[top].width,
					layers[top].height
				);
			}
			
			//-----
			//Layer class
			//-----
			var Layer = function(){
				this.img = new Image();
				this.setImage = function(src, x, y, w, h, a){
					this.img.src = src;
					this.x = x;
					this.y = y;
					this.width = w;
					this.height = h;
					this.alpha = a;
					this.active = 1;
				}
				this.setPos = function(x, y){
					this.x = x;
					this.y = y;
				}
			}
			
			var layers = new Array(9000);
			
		//-->
		</script>
	</head>
	<body>
		<h1>Canvas</h1>
		<canvas id="main" width="640" height="480"></canvas>
		<p></p>
		<div></div>
	</body>
</html>

改築を繰り返したコードなのでいろいろ無駄はありますが、ひとまず9000枚の画像をロードして表示するプログラムです。
ちなみに実験時は、こちらの動画をお借りしました。
http://www.nicovideo.jp/watch/sm11299633

東京

おはよーございます>ω<


今日は東京にいます。某事務所なう。いや、昨日1日で本当に濃い1日でした。昨日はセキュリティープログラミングキャンプ実施報告会と、某事務所でお話+鍋でした。


まずセキュリティープログラミングキャンプ実施報告会です。そもそもセキュリティープログラミングキャンプとは、IPAという独立行政法人がやっている合宿形式の勉強会のようなものです。今回はそれの実施報告会でした。
その中で、サイボウズの青野さんから「日本のITエンジニアは幸せになれるのか?」という基調講義がありました。その中で、青野さん自身ベンチャ=でどうやったか、また日本で起業がどうなのかのような話を聞かせていただき、いまタイムリーにほしい情報が実経験者から得られたので非常にためになりました。また、質問でも起業に関するものは多く、やはり参加者で関心を持っている方は多いんだな、という印象でした。
LTでは、久しぶりにOSを自作するとか言う話をきいて自分にもそんなときがあったなぁとしみじみしながらツッコミ入れてました(ぉぃ
あと、お昼の時間に@konny1989 さんと、@bussorenre さんとしゃべれて、特に@bussorenreさんとはいろいろ意気投合し楽しかったです。どうもありがとうございました。


その後、某事務所さんのほうでいろいろお話をさせていただき鍋をご馳走になりました。技術系ではなく、メディア系の方々と席をご一緒したのは初めてだったので本当にいろいろなお話をうかがうことができました。


1日全体を振り返って、得たものが多すぎてなかなかに混乱さえするほどに楽しかったですwお話くださった方々本当にありがとうございました。

プリンが美味しい勉強会に行ってきました。

こんにちは、そらんです。今日はプリンが美味しい勉強会こと、第5回東北情報セキュリティ勉強会に参加しました。これは、@Taka_Gerbera さんに誘われたのが、発端で行ったのですが、なかなかに面白かったです。


勉強会とのことですが、プレゼンは前半で終了して、その後お菓子休憩という雑談タイム、さらにディスカッションタイムという雑談タイムが後半に行われました。結果として、普段しゃべることのできない実際に働いている方の興味深いお話がうかがえたのですが、なによりいろんな人と楽しく話せて、交流が深められたというか、講義だけの勉強会だと懇親会だけしか場がないそのようなものがよくできて楽しかったです。変わったスタイルの勉強会だと思いましたが、むしろこの方がこういうテーマを絞れるほど人数がいない地方都市ではいいのかもしれない。


プレゼンの内容はNoSQL。結論はNo SQLではなくてNot only SQL、「適所適材」とのことでしたがこれも興味深かったです。ここ2,3日google app engineのデータストアとアプリの通信を書いているのですが、そこである要素が配列的な要素を持ちます。自分はそこをtextを複数ひっ付けてプログラムのほうで読解して解決しましたが、ドキュメント指向データベースを用いれば要素として配列などを格納できるのでこのような問題が一発で解決できます。これは、懇親会のときに、あんどろりんごの @mstssk さんとの会話で話していてわかったことなのですが、その件は今回のプレゼンの内容の理解をひとつ深めてくれました。ありがとうございます。


さいごに、ぷりんもおいしかったですが、ゼリーも美味しかったです。

WindowsPhone7その2

昨日に引き続き、書いていこうと思う。

サンプルとか

内臓ストレージにパラメーターを保存する(設定画面での設定値保持など)

これは2つのやり方があります。

  • オブジェクトの状態が変更されたときに自動保存
  • あるボタン(設定保存ボタン等)を押したときに、その時の状態を明示的に保存

まず、どちらの場合も内臓ストレージに記述するために必要なクラスを以下に示します。

using System;
using System.IO.IsolatedStorage;
using System.Diagnostics;
using System.Collections.Generic;

namespace Project
{
    public class AppSettings
    {
        IsolatedStorageSettings isolatedStore;

        //保存したい項目、及びその初期値
        const string CheckBoxSettingsKeyName = "CheckBoxSettings";

        const bool CheckBoxSettingsDefault = false;
        //ここまで

        public AppSettings()
        {
            try
            {
                isolatedStore = IsolatedStorageSettings.ApplicationSettings;
            }
            catch (Exception e)
            {
                Debug.WriteLine("Exception while using IsolatedStorageSettings: " + e.ToString());
            }
        }


        public bool AddOrUpdateValue(string Key, Object value)
        {
            bool valueChanged = false;
            try
            {
                if (isolatedStore[Key] != value)
                {
                    isolatedStore[Key] = value;
                    valueChanged = true;
                }
            }
            catch (KeyNotFoundException)
            {
                isolatedStore.Add(Key, value);
                valueChanged = true;
            }
            catch (ArgumentException)
            {
                isolatedStore.Add(Key, value);
                valueChanged = true;
            }
            catch (Exception e)
            {
                Debug.WriteLine("Exception while using IsolatedStorageSettings: " + e.ToString());
            }

            return valueChanged;
        }


        public valueType GetValueOrDefault<valueType>(string Key, valueType defaultValue)
        {
            valueType value;
            try
            {
                value = (valueType)isolatedStore[Key];
            }
            catch (KeyNotFoundException)
            {
                value = defaultValue;
            }
            catch (ArgumentException)
            {
                value = defaultValue;
            }
            return value;
        }

        public void Save()
        {
            isolatedStore.Save();
        }

        //保存したい項目の保存用メソッド
        public bool TwitterCheckBoxStatus
        {
            get
            {
                return GetValueOrDefault<bool>(CheckBoxSettingsKeyName, CheckBoxSettingsDefault);
            }
            set
            {
                AddOrUpdateValue(CheckBoxSettingsKeyName, value);
                Save();
            }
        }
        //ここまで
    }
}

こんな感じのコードを用意します。AppSettings.csとかで保存してください。使う場合、コード中コメントした2か所に追加なり変更なりだけで使えると思います。特に変わったことをしないのであれば、メソッドのところは、そのままコピペして変数名だけ書き換えれば問題ないので、実質変数名と初期値だけ決めればこのファイルは記述できます。


次に前者のオブジェクトの状態が変更されたときに自動保存の場合のコードを示します。この場合は、.xamlファイルに以下の記述を書き足せば動作します。

    xmlns:local="clr-namespace:Project"

これは、先頭のphone:PhoneApplicationPageタグ内のパラメーターです。

    <phone:PhoneApplicationPage.Resources>
        <local:AppSettings x:Key="appSettings"></local:AppSettings>
    </phone:PhoneApplicationPage.Resources>

そして、加えて保存したい項目のパラメーターとして、たとえばCheckBoxなら

        IsChecked="{Binding Source={StaticResource appSettings}, Path=CheckBoxSettings, Mode=TwoWay}"

このような記述を加えます。StaticResourceのところが先ほど作ったクラス名、PathがKey名です。またTwoWayというのは変更があれば即時保存するという意味です。
今の場合CheckBoxのチェック状態を保持したいので上のようなパラメーターにBindingしましたが、当然どのようなパラメーターに対してもできるので好きなパラメーターを割り当ててください。


ここからは、あるボタン(設定保存ボタン等)を押したときに、その時の状態を明示的に保存したい場合の記述をします。この場合.xamlファイルの変更はいりません。ButtonをClickしたイベントの部分にだけ記述します。

        private AppSettings settings = new AppSettings();
        settings.TextBoxSettings = textBox1.Text;

つまるところ、Keyに対してsetなりgetなりすればそのまま扱えます。読み出しも同様に

        textBox1.Text = settings.TextBoxSettings;

のようにできます。とっても簡単です。これで、たとえば、ユーザーIDなどを保持して、設定画面でそれを書きかえられる等が実装できます。


また、これに関連してですが、あるPageにBackボタンで戻ってきた場合、コンストラクタは呼ばれません。その代わりに新しいページを読んだ場合と同じくOnNavigatedToが呼ばれるのでOverrideすると幸せになれます。

        protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {
            userNameText.Text = settings.TextBoxSettings;
        }