JavaScript、ActionScript 3.0、Cの変数や関数の宣言方法

少し間が空いてしまいました><

JavaScripterがCを始めた。の続きです。

型指定の文法に着目して、JS・AS3.0・Cの変数宣言(+初期化)を見比べてみる。

まず、JavaScriptから。
var x;
x = 100;

var y = 1.23;

var文によって、整数だろうが、浮動小数点付きの実数だろうが(オブジェクトだろうが)、お構いなしに代入できる変数が宣言されています。
ブラウザ上で実行される場合、これらの変数の実体は、windowで参照されるグローバルオブジェクトのプロパティです。

次、ActionScript 3.0。
var x:int;
x = 100;

var y:Number = 1.23;

JavaScriptに似ていますが、変数の後に型注釈がついています。
これによって、数値であるはずの変数が知らないうちに文字列になっていたり…ということが無くなります。

そして、C。
int x;
x = 100;

double y = 1.23;

こうしてみると、AS3.0よりシンプルですね。
AS3.0で変数の後に付いていた型注釈が前に出てきて、それがそのまま変数宣言となっています。

同じく、JS・AS3.0・Cの関数定義を見比べてみる。

それぞれ受け取った引数(整数)を3で割った数を返すシンプルな関数を定義してみます。

まず、JavaScriptから。
function f(z) {
	return z / 3;
}

function文によって、仮引数がzの関数fを定義していますが、zが整数であるべきということは仮引数の部分では制限できません。
zは整数でない数かも知れないし、文字列である可能性さえあります。

実数である場合はそのまま計算して返しますし、他の型である場合は自動的に型変換して計算後、値を返します。
返す値についても制限できません。

例えば、文字列を受け取った場合、除算をする段階で数値に型変換します。
変換結果が数値として有効なものでない場合にはNaNとなり、結局NaNを3で割った結果NaNが返ることになります。

次、ActionScript 3.0。
function f(z:int):Number {
	return z / 3;
}

変数の場合と同じように、JavaScriptの関数定義に、型注釈が付いた形です。
これによって、整数でない値が渡されそうになった時点できちんとエラーとして処理されます。

注意すべきは、仮引数の型名(int)だけでなく、「戻り値の型名」(Number)についても記述出来る(する必要がある)ことです。
自分がAS3.0を始めた頃は、この点で躓きました。

そして、C。
double f(int z) {
	return z / 3;
}

これまたシンプルです。

仮引数の部分は変数の場合と同様、型名が前に出てきています。

さらに、AS3.0では関数本体のブロックの直前("{"の前)にあった「戻り値の型名」も、先頭に来ていますね。

まとめ

Cって、シンプル!!

とりあえず、今回は記法の段階で躓く事はなさそうです。><

JavaScripterがCを始めた。

最近、C言語に再入門しました。それに絡んで、弾さん私がJavaScriptを初心者用の言語として選んだわけについて書いてみます。

…が、長くなりそうなのでエントリを分けます。

  1. JavaScript、ActionScript 3.0、Cの変数や関数の宣言方法
  2. 初心者用の言語としてのJavaScript

再入門の動機は?

データ構造(スタック・ツリー等)や基本的なアルゴリズム(検索・ソート等)について理解を深めたいと思ったからです。

JavaScript等でも擬似的にデータ構造を再定義することは出来ますが、直接メモリを扱いながら学習するためには、自分が調べた限りではどうしてもポインタが必要でした。

"再"入門って?

実は、Webコーダーを始めて間もない頃に「Cもやってみよう!」と意気込んで門を叩いたことがあったのです。
その時は、

  • JavaScriptではvarやfunctionで済む」ものが、なんで「intやdoubleなど、型指定が必要」なんだ!?
  • ポインタって何だ!?
  • CUI面倒!!

などなど、「?」と不満まみれであっという間に挫折してしまいました。
なので、"再"入門なのです。

で、どんな感じ?

JavaScript → ActionScript3.0とステップを踏んだ事で、型やポインタの利便性が分かり、またFirefoxfirebugFlashのtraceを日常的に使うことで、CUIに対する抵抗も無くなり、今回はすんなりと入門できそうです。

次回は覚え書きの意味も含めて、JavaScriptActionScript 3.0、Cの変数や関数の宣言方法を並べて書いてみます。

Flex2で正多角形を描画

あの福井市の小学生、その驚くべき発見とは 続きが楽しみ!!
こういう問題は、やはり手で触れられるもので工作してみるのが一番の近道ですね。
これに関連した(つもりだった)前回の自分のエントリ、「周囲の長さと面積の関係」について考えたは、かなり的外れというか、レベルの低い話だったみたいです><
4隅が集まる点をグリグリと強調してあったのに、それにも気づきませんでした…。

が、せっかくなので的を思いっきり外してFlex2で遊びながら考えてみました。

前回の、

  • あと、nが大きい方が面積が大きい。
  • nをどんどん増やしていくと円に限りなく近づく。
  • ということは、外周が同じ図形の中では、円が一番面積が大きい。

のあたりを、外周がlの正n角形に限定して、Flashで描画しつつ計ってみます。

まず、実際に動作するデモ。

Polygon Demo

外周を適当に決めて、角の数を増やしていくと面積(書き忘れましたが図形に重なっている数字)も増えていくのが見えますね。

次に、ソースコード

計算、図形描画をActionScriptで。

Polygon.as

package {
	import mx.controls.Image;

	public class Polygon extends Image {
		private var _l:Number;
		private var _n:uint;
		private var a:Number;
		private var s:Number;
		private var r:Number;
		private var h:Number;
		[Bindable]
		public var area:Number;
		
		private function calculateArea():void {
			a = 2 * Math.PI / n;
			s = l / n;
			r = s / 2 / Math.sin(a / 2);
			h = s / 2 / Math.tan(a / 2);
			area = (s * h / 2) * n;
		}
		
		private function draw():void {
			graphics.clear();
			graphics.lineStyle(1,0x666666);
			graphics.moveTo(r, 0);
			for (var i:uint = 1; i <= n; i++) {
				var x:Number = Math.cos(a * i) * r;
				var y:Number = Math.sin(a * i) * r;
				graphics.lineTo(x, y);
			}
		}
		
		public function get l():Number {
			return _l;
		}
		public function set l(length:Number):void {
			_l = length;
			calculateArea();
			draw();
		}
		
		public function get n():uint {
			return _n;
		}
		public function set n(count:uint):void {
			_n = count;
			calculateArea();
			draw();
		}
	}
	
}
外っ面をMXMLで。

Main.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:my="*"
layout="absolute" backgroundColor="0xffffff">

	<mx:HBox verticalAlign="middle" x="10" y="10">
		<mx:Label text="外周の長さが(約)" />
		<mx:NumericStepper minimum="100" maximum="500" stepSize="10" value="250" id="stepper01" />
		<mx:Label text="pxの" />

		<mx:NumericStepper minimum="3" maximum="360" value="3" id="stepper02" />
		<mx:Label text="角形" />
	</mx:HBox>

	<my:Polygon l="{stepper01.value}" n="{stepper02.value}"
		x="100" y="150" rotation="-90" id="polygon01" />
	<mx:Text text="{polygon01.area}" x="100" y="150" color="#663333" />
</mx:Application>

Polygonクラスのプロパティたち

ActionScriptソース内のプロパティたちは、先に紙に描いた絵に書き込んだ英字をそのまま使いました。

スキャナーがないので、清書しました。これです。

これに加えて、面積のarea、外周のl、角の数のnです。

この図はたまたま八角形ですが、もちろん角の数は任意。それぞれ内角の二等分線を中心まで引いている、と見てください。

絵とcalculateArea関数を見比べて、複数の合同な二等辺三角形に分けて面積を出し、それをまた足し併せて全体の面積を出していることが分かるでしょうか…。

もっとシステマチックな計算方法があるのかもしれません。ご存知の方がいらっしゃいましたら、是非ヒントをください><

まとめ。というか、再び挫折

…と、ここまではよいのですが、これは結局何の証明にもなっていませんね。

calculateArea関数の最後のarea = (s * h / 2) * n、これの右辺をlとnのみの式に戻して、「nに比例」とか「nが独立変数の二次関数」とかになれば証明できるのですが、nがtanの中に入ってしまった時点で今の自分はお手上げでした…。

やはりもう一度、数学をやり直さなければいけません><

Dreamweaverのテンプレート・ライブラリで失敗

覚書用のブログのはずが、すっかり算数で恥をかくブログになってしまっているので、ここらで一つWebオーサリングツールネタを…。
と言いつつこれも恥ネタなんですが、失敗を繰り返さないために書き留めます。

状況

企業のエンドユーザー向けサイト(数百ページのモックアップ)を引き継ぐ。
外枠(ヘッダとかフッターとか横のメニューとか)はDreamweaverのテンプレート・ライブラリで固められていた。
引き継ぎ前も含めて、複数人がファイルの更新や追加をしている。

なにをしたか

外枠部分の小さな修正があったので、Dreamweaverのテンプレート機能をつかって更新した。

なにをやらかしたか

何ページかでレイアウトがガッチャガチャ。
(システム屋さんの部署でサーバサイドのプログラムに取り込んでもらう直前に判明。)

で、どうしたか

HTMLのソースコードSubversionで管理しているので、直前のリビジョンとdiffとってマズい所を抽出、修正。

原因

自分の確認不足。テンプレート機能に関する認識の甘さ。

いやいや、もっと具体的に

テンプレート機能を使って作成したページも、所詮は個別のファイル(当たり前ですが…)。
いくつかのファイルで、Editableに設定されていない部分が他のエディタで直接編集・追加されていました。
head要素内にstyle要素が追加されていたり、特定ページのみサイドメニューの項目数が減っていたり。
それをテンプレートを再適用することでごっそり巻き戻してしまったのです。

繰り返さないために

テンプレート機能を信用しない><
…違いますね。この機能は正しく使えば便利なものであるはず。
今回のケースでは、まずモックアップ作成に携わるデザイナー・コーダー間で、修正段階でこの機能を「使う」か「使わない」か、統一すべきでした。
そして使う場合には、Editableでない部分を直接修正してはいけません。
なにより、大量のファイルに再適用する場合は、バックアップとの差分を取り、想定外の部分が上書きされていないかザッと確認する慎重さが必要でした。

ボソボソ…

テンプレート怖い…
そもそも外枠PHPで…

「周囲の長さと面積の関係」について考えた

id:m-hiyamaさんの、福井市の小学生が驚くべき発見というエントリについて、自分なりに考えてみました。

短く言うと、まずある図形があって、その外周を図ったらnLでしたよ、と。
その図形についての情報がこれだけだと、その図形の面積は求められませんよ、というお話です。
id:m-hiyamaさんのところでは、図表も交えて分かり易く書いてあります。

で、一昔前の小学生がこの問題についてある発見をしました、というお話でした。
そこで、「おしゃっ!!」とオトナゲなく張り切って考えてみるわけです。

…結局、自分には法則性を見つけることが出来ませんでした。
なので、取り敢えず面積の最大値について気づいたことを書き留めておきます。

  • まず、外周が固定されているn角形の内角(ラジアン)の和が(n-2)πを超えると面積は最大でなくなる。
  • つまり、同じ外周なら、どこも凹んでいない図形が一番面積が大きい。
  • あと、nが大きい方が面積が大きい。
  • nをどんどん増やしていくと円に限りなく近づく。
  • ということは、外周が同じ図形の中では、円が一番面積が大きい。

真円とはっきり言えないのは、自分が「楕円の外周」から「半径の最大値と最小値」の「それぞれの変化の範囲」を出す方法を知らないからです…><

[追記] n角形の中でも、正n角形が一番面積が大きくなる気がする。やっぱり真円が最大? [/追記]

どれもこれも証明もなしに書いているので、かなり危ういです。
時間を作って検証します。

で、これって、もしかして義務教育で習うことだったりしますか!?

最近の心境をば。

id:amachang氏の遅延評価的勉強法を拝見し、丁度思う事があったので書き置きます。
[ネタ]とカテゴライズされていますが、今の自分にとって、かなり羨ましくもあり共感できる内容でした。


まず、自分は氏とは正反対…とまではいきませんが、わりとドキュメントから入るタイプの人間です。
そして、必要な部分を限定して学ぶにしても、寄り道が物凄く多いし長い。
さらに、話はすっ飛びますが、仕事で手がけたサイトにJavaScriptのライブラリを取り入れたことがありません。


で、結論から言うと、これらの勉強方法や考え(以降、敢えて悪癖と呼ぶ。)を少し改めようと思っています。
以降、それに至った経緯を書きますが、考えがまとまっていない上に、長くなると思います。


ここ数ヶ月、Webに携わる者としての自分の立ち位置みたいなものを考えていて、それに絡んで悪癖について考える機会も多くありました。

悪癖の原因についての自問自答は、

  • 覗こうと思えば覗ける「ブラックボックス」は、中身を理解しないと気がすまない。
  • 「需要」に対して、「自分が提供するもの」が可能な限りミニマム且つシンプルでないと気がすまない。

というあたりの自身の性格に収束しました。

「じゃ、コンピュータ触れないじゃん。」とツッコミが入りそうですが。


例えばFlex2のUIコンポーネント群は、MXMLに簡単に記述できるように、誤解を恐れずに言えば「ブラックボックス」として使えるように、フレームワークに組み込まれています。
しかし、その実体はASファイルに記述されたクラスです。
テキストエディタさえあれば覗ける「ブラックボックス」なんです。


これは、日々生み出される、JavaScriptのライブラリについても言えることです。
それぞれのライブラリで提供される独自クラスも、便利な関数群も、「ブラックボックス」であると共に全てその設計図が覗けるものです。


例えばここに、今作ろうとしているWebアプリケーションに利用できる、あるクロスブラウザな便利な関数があります。

それがどのように各ブラウザをフックしているのか。
どんな独自クラスに依存しているか。
その独自クラスはどういう作りなのか。
上に書いた自分の性格ですから、覗かずにはいられない。
辿っているうちに理解できない部分があれば、ドキュメント・リファレンス漁りが始まる。
汎用性の為に熟考を重ねて作りこまれた、「今回のWebアプリケーションにとって冗長な点」が気になってしょうがない。

チートシートさえあれば使えるはずの便利な関数を使うために、莫大な時間を費やすことになります。


こういうことを繰り返して、果てはプロジェクト毎に自前のスクリプトを書き続けて、悪癖に悩んで考えて、ようやく気づきました。
多くのライブラリ・クラスたちは、それぞれの言語に精通した、それも世界中の先人たちが議論を重ねて生み出した「道具」なんだと。
もちろんそれらを読み解いて学ぶこともとても大事な勉強です。
しかし、もっと大事なのはそれらを効果的に使って、エンドユーザにとって便利なものを作ることであるはずです。
また、より便利な新しい道具作りに貢献することであるはずです。
自分も、もう少し使う側にシフトしなければと思いました。


…以上、案の定支離滅裂になりましたが、最近のco-scheのコーディングに関しての心境です。


さて!
思い立ったが吉日、早速今コーディング中のサイトにjQueryを組みこんでみました。
これが、便利なこと便利なこと。

<ul id="globalMenu">
	<li><a href="javascript:;">foo1</a><ul>
		<li><a href="javascript:;">bar1</a></li>
		<li><a href="javascript:;">bar2</a></li>
	</ul></li>
	<li><a href="javascript:;">foo2</a><ul>
		<li><a href="javascript:;">bar3</a></li>
		<li><a href="javascript:;">bar4</a></li>
	</ul></li>
</ul>

みたいにリストでマークアップした階層型メニューを作るのに、windowの読みこみ待ってボタンそれぞれfor文回してリスナーつけてこいつらをクロスブラウザに…なんてこと考えなくても、

$(function(){
	$('#globalMenu > li').hover(
		function(){	$('ul', this).fadeIn(); },
		function(){	$('ul', this).fadeOut(); }
	);
});

で済んでしまいます(CSS省略)。
$関数のセレクタが素敵ですね。


結局、遅延評価的勉強法とはかけ離れた内容になってしまいました><