がるの健忘録 このページをアンテナに追加 RSSフィード

2016-05-04

[][]他言語やる時のラーニングパターン 基本変

前提として「なんか1〜2つくらいの言語はある程度の所まで扱える」前提です。

「ある程度」ってのも難しいところなのだけど、ざっくりと書くと大体「数年以上、くらい、まじめに学習しつつ実務やってる」くらいかなぁなんとなく。

基本的に「手続き型言語及びその延長線」が想定範囲です。「関数型」はあんまり入れていないので、その辺も注意。

まぁまだ、実務だと手続き型のほうが圧倒的多数だとは思うんですがねぇ………多分。


準備

「信頼できる」一次情報の場所を把握しましょう。

その言語を開発/制定しているところ、ないしそこに「限りなく近いところ」がお勧め。

「人気があるBlog」とか「人気のある書籍」は、「なぜ人気なのか」によってお勧め出来たり出来なかったりするので、人気よりは「一次情報からの距離」で選択をしたほうが安全です。


初手

まずはその言語でHello Worldから。

「出力の仕方」と「実行環境整え」ってのが主眼。

さりげに「最後の改行」とかで癖があったりするので注意。


コメントの書式

コメントは重要なんで、とりあえず書式くらい把握しておきましょう。

「その言語にとってのポピュラーなコメント形式(例:JavaJavaDoc形式)」を合わせて把握しておくと、色々と便利です。


変数宣言と型の有無

一旦いわゆる「プリミティブな型(≒配列以外)」を把握。

あと「変数を出力する」方法を把握。「変数の前後に勝手に空白だぁの改行だぁの」が入るケースがあるので「そーゆーのを入れない方法」を把握しておくと、後でひょんな時に楽が出来ます。


文字<->数値変換(型有り言語の場合)

型あり言語の場合、どのみちやることになる可能性が高いので、文字列と数値との交換方法を把握しておく。


メモリ管理の有無

まぁ「C / C++」か「それ以外」か、の分岐のような気がひしひしとせんでもないのですが。

「自分でメモリを管理する」系なのか、そうじゃないのか、簡単に把握しておきましょう。


ポインタポインタ(参照の参照)」が持てるか持てないか

ネストしたポインタ(参照)が持てるかどうか、は、以降の色々なところで引っかかってきたりします。

おいちゃんの手元で近しいあたりだと、C、C++はもちろん持てるのですが、Perlも可能なので、気をつけないと「根の深いネスト」に苦しめられます(苦笑

PHPは「持てない」のと、この手の場合大抵「変数の持ち方に言語なりの工夫がある」ので、そーゆー言語で下手に「意図的な参照渡し」とかすると地獄経由悲劇行きになりやすいので注意しませう。


if文の把握とswitch文の有無の把握

ifはまぁ大抵あるので、else / elseif 含め、書式を把握。

switchは合ったり無かったりするので、まず有無から確認。

「波括弧の有無」とかも一応含むけど、書くほどのお話でもないよね?


文字列比較の確認

数値の比較はわりと「どこも似たり寄ったり」なのですが。

一方で、文字列の比較は、割合と各言語によって方言があったり癖があったりするので、確認をしておきませう。

特に「オブジェクトの強い系の言語」の場合、気をつけないと「文字列の一致ではなくて、インスタンスの一致」を見ちゃったりする可能性があるので。

「(違うインスタンスでも)文字列的に同一なら一致」の方法は、ちゃんと把握しておきましょう。

この辺、後述の「イミュータブルな変数」とかにも引っかかってくるケースがあります。


loopの把握

いわゆるfor / while文系なのですが。

C言語のfor文」がポピュラーなのか、それとも「Range-based for loop」なforがポピュラーなのか、まずその言語の「スタンダード」を把握しておきませう。

Range-based for loop系の場合「一定範囲の数値を作る方法(大抵は、generator)」を合わせて捕捉しておきましょう。


配列の把握

「どんなタイプの配列を持っているか」は、意外と言語毎に異なるので、一通り「配列群」を総ざらえで把握しておくとよいでしょう。

また、種類が豊富であれば豊富であるほど「理由がある」もんなので、ある程度使い分けられるようにする…か、ド最悪「とりあえずコレ使おう」っていう目星をつけておきましょう。


イミュータブルな変数」の把握

配列の把握に似ているっていうかベン図的に重なる部分があるのですが。

言語毎に、部分的に「この変数イミュータブル(不変)な!」っていうモノがあったりして、安全性観点から「使う事が推奨される」事も多々あったりするので、押さえておきましょう。

C++constは、一旦この辺の範疇としておきます(C++以外で、引数とか戻り値とかのconstとかってあるのかしらん??)


関数とクラスの書式

この辺は比較的似たり寄ったりになりやすいんだけど(without JavaScript)、とりあえず基本的な記法を把握。

ちなみにどんな言語であっても基本的に「1ファイル1クラス、ファイル名はクラス名」ってのは揃えておいたほうが圧倒的に無難です。

あと「関数(クラス)の中に関数(クラス)が書けるかどうか」「無名関数(含むラムダ式)、無名クラスは作成可能か」「関数引数として使えるか」とかあたりは調べておくと無難です。

またこの辺は言語毎に「同じ単語を違う意味で使っている」ケースが増える箇所なので、「その言語におけるこの用語の意味」を、一度ちゃんと調べ直しておくと、変な先入観で死なずに済みます。


「破壊的[メソッド|関数]」に対する印象値

極論大まかに「メモリを死守する系は破壊的関数を是としたがる傾向があり」「安全性とかを死守する系は破壊的メソッドに殺意を抱く傾向がある」と思われるのですが*1

やり方を知る事も大切ですが、それ以上に「その言語はどちらをより好む傾向があるのか」を大まかに把握しておくと、変なトラップに引っかかりにくくなります。


変数のスコープの確認

大まかには「関数スコープ」なのか「ブロックスコープ」なのか。

あと、スコープの外側に変数がある場合に「見れない」のか「繰り上がるのか」とか、変数宣言の仕方によっては「関数内で宣言しているのにglobalになっちゃうよママン orz」とか(例:JavaScript)。

そのあたりはしっかりと押さえておきましょう。


クラスの継承とかの書式の確認

継承(extend)とかMixinとかtraitとかinterfaceとかabstractとかvirtualとかnamespaceとか、あとついでにアクセス修飾子(private / protected / public)の有無(Perlにはないんだ…)とか、そこら辺の「少し突っ込んだ」概念を把握しておきましょう。


その言語独自の演算子の確認

結構「その言語固有、ないしそれに近しい演算子」はあるので。

演算子は一旦、レジュメ的に総ざらいして「参照出来る」状態にしておくと取りあえず楽です。


ここら辺くらいまで来ると、多分「とりあえずその言語で書かれたソースコードが大体読める」んじゃなかろうかと思われます。

なので、ここら辺くらいまできたら、数本くらい「その言語で書かれたあんまり長くないコード」を読んで、不明点を逐次調べていくと、大体「とりあえず書く」くらいまでならあんまり困らなくなると思うのです。


[][][]他言語やる時のラーニングパターン フレームワーク

新しいフレームワーク触るときの手出しの仕方のパターンを合わせて。


URLルーティング設定の確認と、場合によっては破り方

まぁ大体「書かなくてもデフォルトで動く」ケースが多いのですが(その場合は「まずHello World」へ)。

「明示的な記述が必要な場合」は、まず、1Page分でもよいので、調べて記述しておきましょう。

あと「特別なルール(このURLならこっちの処理にしたい、など)」は、調査コストとの兼ね合いになります…が、ヒネたものでなければある程度フォローされている可能性が高いので、適宜調査して実験して、実装しましょう*2


まずHello World

もっぱら「空っぽの処理無し」+「テンプレートファイルの位置と書式」の確認。

あとは「そもそもそのフレームワークインストールがうまくいってるか?」の確認も込み。


設定ファイルの把握

以降随時チェックにはなると思うのですが(で、大抵の場合、デフォルトで動いたりもするのですが)。

とりあえず

デバッグモードの on/off

DB設定周り

・時刻、言語(文字コード)周りの設定

テンプレートエンジン周りの設定

あたりは最低限確認をしておくとよいです。


用語の確認

特に昨今の場合、MVCないしそれに近しいお名前はちょいちょいと見受けられる…のですが、特にCとM(中でもM)の意味が、言語によってフレームワークによって、下手すると本気で「別物ぢゃん!!」レベルで違うので。

新しいところに言ったら、一旦心の中のお茶碗を空っぽにして、「その言語/フレームワークにおけるこの用語の意味」を、知っている単語ほど、再確認しておきましょう。


テンプレート変数を渡す

大体「単値」「配列(正確にはhash配列配列) )」「if文の書式」の3つが別れば大体いけます。

あと、テンプレートに渡す変数デフォルトで「HTMLエスケープされているかされていないか」の確認。

万が一「されていないがデフォルト」の場合、テンプレートエンジンなりviewクラスなりをラッピングして「デフォルトエスケープ」に倒せるように全力を尽くしましょう!!

デフォルトエスケープの場合、とりあえず「エスケープさせない設定」の方法を調べておきましょう。


DBハンドルの取得

大体の場合「どっかに設定するとどこかでとれる」と思われるので、その「どっか」を把握しましょう。


テーブル名、カラム名、その他制約の確認

特にORマッパー系を使うものの場合、テーブル名やカラム名に一定の制約やルールがあるものがあるので。

その辺は把握しておきましょう。

「そのルールの破り方」は、必要そうなら合わせて調査。ただ「ルールを破るコストが高い」可能性も結構あるので、「ルールに合うように仕様変更が可能」であれば、仕様変更しちゃったほうが、コスト安かもしれないですが。


単純なCRUDの作成

もうちょっと端的には「SQLの発行の仕方(またはORマッパーの使い方)」と、特にSQLを自力発行する場合は「プリペアドステートメント機構の使い方」のあたりをしっかりと把握しましょう。

「複数のやり方がある」可能性が高いので、とりあえず「今回想定しているやり方」だけ押さえておく、でもよいと思いますし、「フレームワークの推奨のやり方」を合わせて押さえておく、というのもよりよいかと思います。


Cookieの設定の仕方とセッション保持のやり方とセッションデータの持ち回りかた

とりあえずセッションは、些か狭義に「サーバ側で情報が保持できる仕組み」と定義しておきます。

クライアントサイドに情報を持ってもらう方法としてのCookie」と「サーバサイドで情報を持たせるためのセッション」の、それぞれの書式を把握しましょう。


「管理画面」の作り方

業務系前提ですが、大抵「frontと管理画面」を作る事になると思うので。

一旦「そのフレームワークにおける、ポピュラーな管理画面の作り方」を把握しておきましょう。

いや「別プロジェクトで全部作る」でもよいのですが、frontと管理画面で「同じクラスとか関数とか設定値とか使いたい」シーンも多いので、それを「全部copyでやる」と些かしんどいのではないかなぁ、と思うので、その辺込みで「ちゃんとしてる」方法を見つけるとよいと思います。


「環境別」設定ファイルの作り方

開発、ステージング、本番で設定ファイルの「一部」が異なる(「一部」は一緒)だと思うので。

可能であれば「環境別のconfigと環境共通のconfig(場合によっては含む定数)」と、それらを「いかに環境別に振り分けるか」の手段を想定しておきましょう。

大体は「環境変数の値でif文でスイッチ」とか多いのですが、おいちゃんは「シンボリックリンクで振り分け」とかやるほうがよりお好みなので、まぁ適宜。



この辺までくると多分「普通のものなら」なんとか書けると思うので。

書けるようになってから「コントローラーのダイエット」とか「ちょっとこまっしゃくれたコード」とか「テクニカルなテクニシャン」とか、考えていくようにしましょう。


以上、もっそおおざっぱですが。

*1:色々大げさ

*2:ヒネたものの場合、調査コストと相談しましょう

2011-11-10

[][]ををPHPよ、お前は何でそんなにダメなのか

PHPは、駄目な言語でもありますが、一方でダメな言語でもあります。

今回は「ダメ」な部分をクローズアップ。


あ、先に。

ゆどちゃんに謝意。


本題。

標準関数、というものがございます。

「標準」です。割合と「最低限以下程度の、明らかに足りないことも多い」ものです。

まぁ、PHPは比較的「潤沢な」バリエーションがございます。

このあたりは「使いやすい」といわれる所以でございましょう。


日付・時刻 関数、というものがございます。

http://jp.php.net/manual/ja/ref.datetime.php


一番良く使うのはそのまんま、date関数とtime関数

ただ、一覧をみると、たかが日付とも侮れない、結構な量の関数がございます。


で。

今回おいちゃんは、ちょいと「とあることをしたくて」色々調べていたのですが。

ゆどちゃんから「それ、標準関数でたしかありますよ?」と聞いて調べたですよ。


http://jp.php.net/manual/ja/function.date-sunrise.php

date_sunrise ― 指定した日付と場所についての日の出時刻を返す


http://jp.php.net/manual/ja/function.date-sunset.php

date_sunset ― 指定した日付と場所についての日の入り時刻を返す


…まてこら。

なんでこれが「標準関数」として存在する?

誰得


誤差のほどはよぉわかりませんが。

もうちょっと正確に書くと。なんか調べてる限りでは「そこそこ面倒そうな数式が出てきている」一方で、5.3.8のソースコードを見る限り、そこまでややこい数字計算をやっているようには見えないので、誤差が重要な場合、確認はしたほうがいいとは思うのですが。

ががが。


いや…まさかこんなもんまで標準で存在しているとは。

明らかに「ダメ」でございます。発想が狂ってます。着眼点が奇天烈です。

…こーゆーところがあるから、PHPって憎めない(笑


ちなみに、作りたかったのは、これ。

http://www.gjmj.net/wareki.php

デザインがないのはいつものことなので気にしないように & 「デザインあててやってもいいよ」とかいう奇特な御仁がいたら、ご連絡ください。

おいといて。


何かってぇと、いわゆる「24節気」と、江戸のころの不定時法の日本語表記を出したかったっていう、ただそれだけ。

月齢を出そうかとも思ってるんだけど…いい画像がなくてねぇ。現状保留。


いや。

久しぶりに、PHP関数みて馬鹿笑いしました(笑

2008-07-02

[][][]date_parseにおける「日付フォーマットにエラーがある場合」とは?

んと…大分前に嵌ったのですが。

「日付のvalidateをどうすんべ」ってのが発端でございました。


例えば

  $s = 'yyyymmdd';

という文字列をdate_parseすればエラーなのは当然でございます。

まぁ…

http://php.benscom.com/manual/ja/function.date-parse.php

返り値

成功した場合に日付情報を含む配列、 失敗した場合に FALSE を返します。

を一瞬読み間違えると

  $s = 'yyyymmdd';
  $ret = date_parse($s);
  if (false === $ret) {
    // エラー処理
  }

と書いてそれなりに痛い目にあうのですが orz


上述における「失敗した場合」というのは「パース結果が異常である」ではなくて「パース処理そのものが何らかの事情でこけた」です。

おいといて。


んじゃまぁってんで読み進めますと

日付フォーマットにエラーがある場合は、 'errors' 要素にエラーメッセージが格納されます。

とか書いてあります。

  $s = 'yyyymmdd';
  $ret = date_parse($s);
var_dump($ret);

で確かめてみますと、確かに

["warning_count"]=>

int(1)

["warnings"]=>

array(1) {

[6]=>

string(29) "Double timezone specification"

}

["error_count"]=>

int(1)

["errors"]=>

array(1) {

[0]=>

string(47) "The timezone could not be found in the database"

}

となっておりますふむり。

error_count使ってもよござんしょうし、errorsがどうなっているかをチェックしてもよござんしょうし。

よっしゃ日付のvalidateはこれでばっち「ぐ〜*1」とか考えると大きな落とし穴にはまります。

  $s = '99999999';
  $ret = date_parse($s);
var_dump($ret);

こんなコードで試してみましょう。

["warning_count"]=>

int(0)

["warnings"]=>

array(0) {

}

["error_count"]=>

int(0)

["errors"]=>

array(0) {

}

………まてこら。なんていうか…多分全国幾多のプログラマの予想とは反してるんじゃないかと思うのですが如何でしょうか?

ちなみに。validateをチェックする時に、本当の本当に見るべき場所は、ここ。

["year"]=>

int(9999)

["month"]=>

bool(false)

["day"]=>

bool(false)

["hour"]=>

bool(false)

["minute"]=>

bool(false)

["second"]=>

bool(false)

んと…「日付だけの時と日時の時とでチェックする場所が当然変わる」のですが、この辺をis_boolあたりで丹念にチェックする必要があります。


以前に、無駄に一瞬嵌ったので、思い出しつつめもり。

…相変わらずきしょい仕様だ orz

*1: (C)えどはるみ

2008-02-21

[][]ステップ数換算に思うこと

一応、発想元はここの話。

第15回 下請法 外部委託における元請けの義務を知る

http://itpro.nikkeibp.co.jp/article/COLUMN/20080207/293168/

契約交渉開始の段階で,下請け会社は「プログラムの規模は3万5000ステップ相当」としていたので,再下請け会社は当初3000万〜3300万円の概算金額を提示していたが,その後の交渉の結果,最終的に委託代金は2862万円になった。

ところが実際に開発を始めてみると,プログラム規模は10万1000ステップに上った。このため再下請け会社が下請け会社を被告として3万5000ステップを超える作業工数に対する報酬として1億4618万円を請求する訴訟を起こした。「2862万円という代金は3万5000ステップの規模を前提にしたものであり,それを超えた場合は追加費用が発生する」,というのが原告(再下請け会社)側の主張だった。

裁判所は,「被告が提供した機能仕様書と詳細設計書に基づいて,契約締結までに原告がより正確な見積もり額を算定することは可能だった」としたうえで,「契約書には対価を総額2862万円とすることは記載されているが,プログラム規模の記載はない。このため,受託業務の規模が3万5000ステップ程度であることを前提として委託代金を決定した事実は契約には存在しない」と判断し,原告の請求を棄却した。(東京地方裁判所1997年6月12日判決,判例時報1546号29頁)

んと………。

例えば。以前に本当にあった怖い話ですが。

とある、まぁかなり大きいプロジェクトの共通ルーチンを作成してたです。で、ほかの人のルーチンと比較しても、自分のルーチンは明らかに10倍以上の頻度でcallされてたです(ンなもんキャリア1年の餓鬼にやらせるなよっていいたいけど確か書類上は8年のキャリアだったからなぁ… orz)。

当然ながら性能が出ないってことで、うちのルーチンに「速度削れ〜」命令が出てたです。

その時の計測単位。ダイナミックステップ。簡単に言うと「マシン語換算で何命令走るか」。ええ確かに速度に直結します。1.5GのCPUなら、1命令は1/1.5G 秒。15命令だったロジックを10命令に落とせれば、5/1.5G 秒速度が縮まります。

………ええありえないですよ本当の話ですが。

OSも某F社様のOSだったのでOSチームとやり取りできたのは行幸だったのですが。

何せ頂戴した文章が、例えば

memcpy(第一引数、第二引数、第三引数)

第三引数が4の倍数の場合、15DS + 第三引数*5DS。

第三引数が4の倍数ではないが2の倍数の場合、18DS + 第三引数*6DS。

第三引数が上述以外の場合、20DS + 第三引数*7DS。

とかなんとか。そ〜ゆ〜感じ(数字は適当 & DSはダイナミックステップの略)。

このフェイズってか世界観において、ステップ数は色々な意味で意味があるです。


時は流れてって別にそんなに経過してませんが。

Cとかだと………うんまぁまだ「step数=規模」って感覚は強いのかな? と。

もちろん

  i += 10;

という処理を

  i += 1;
  i += 1;
  i += 1;
  i += 1;
  i += 1;
  i += 1;
  i += 1;
  i += 1;
  i += 1;
  i += 1;

という風にするテクニックとかが「step数によって金額が決まる現場」において存在しないわけでもなかったのですが。

さすがに

  i += 1;
  i += 1;
  i -= 1;
  i += 1;
  i += 1;
  i -= 1;
  i += 1;
  i += 1;
  i -= 1;
  i += 1;
  i += 1;
  i += 1;
  i += 1;
  i -= 1;
  i += 1;
  i += 1;
  i -= 1;
  i += 1;
  i += 1;
  i += 1;

と書く現場はなかったであろうと信じたいのですが*1

それでもまだ、ある程度「自力でごりんごりんしなきゃいけない言語」において、step数は多少なり目安になる部分が0ではなかったのではなかろうかと推測します。目安以上のものではないにしても。


んでもって、今。

いい加減OOP華やかりしこのご時勢に、プログラム上の1stepに何の意味があるのかは、どこまでも限りなく果てしなく疑問です。


でまぁそんなこんなを考えるとっていうか考えるまでもなくなのですが。

「作り手がどれくらい苦労するか」ではなくて「買い手にとっていくらくらいのメリットがあるのか」が、値段の本質になってもよいのではないかなぁと。

もちろん「製造コスト」ってのはあるわけで、だからこそ「安けりゃ作らねぇよ」的発言が成り立ちうるのですが。


まぁ1986年に締結した契約云々の文言があるので。そのころはまだそうだったんだろうし今は違うんだろうなぁと思いたいのですがええ。

でもいまだにstep換算とかエラー率とかで東奔西走するお話も耳に入ってきたりするので。

ふらりぶらりと、メモ。

*1:とはいっても、規定のstep数にあと100stepだけ足りない、とかいうところで本当に絶対にやらなかったのかと聞かれると「どうなんでしょうねぇ」としかいえませんが

2008-02-16

[][][][][]来たよ 来たよ ハイエナ 来たよ orz

ほぉら来たハイエナが。

http://itpro.nikkeibp.co.jp/article/COLUMN/20080108/290642/

Ruby:高生産性でビジネスに急拡大,課題は大規模への展開


先に。

Ruby on Railsを作ったのは,David Heinemeier Hanssonというデンマーク出身の技術者で,今は,カナダに住んでいます。なぜRubyを使ったんですか,と彼に聞いたら「美しいプログラムを書けるから」と。

ここはわからんでもない。個人的には「プライベート&身内で使うなら面白い」と「集団とか有象無象に使わせるには怖すぎる」が半々ってイメージなのですが。

でもねでもね。

話題が先行するも生産性の高さが魅力

実際「日経ソフトウエア」で記事を作っていて,手順を順番に示すような記事で,J2EE(Java2 Enterprise Edition)とRuby on Railsで同じものを作ると,感覚的に2倍から3倍,J2EEの方が手順が多いと感じます。

とか。この辺がこわい。

ハイエナな皆様は、きっと

ただ何もかも楽になるかというとそうでもありません。Ruby on Railsで楽になれる部分は,主に設定の部分です。これまで,データベースはこれで,テーブル名はこれでという設定をXMLでゴリゴリ書かなければいけなかったのが,Ruby on Railsでは一定の規約に基づいて自動的にスケルトン・プログラムを生成してくれます。“いつも同じ面倒な作業”から解放されて,本来実装すべきビジネス・ロジックだけに注力できるようになります。

なんて部分はすぽ〜んとすこり〜んと抜けて、ただ「何倍も楽にかける == 何倍も早く作成出来る == 数分の一のコストで出来る」って思うだけだろうから。

Javaは知らない。Visual Basicはちょっとやったことがある。で,Rubyの本を1冊だけ買ってきて,読んで,作ってしまったんです。

ここもこわい。多分ここから導き出されるのは「プログラミングに対してずぶのド素人でも本を一冊与えて読ませればモノが作れる == 初心者安く買いたたけてらき〜」。


…うん最近ちょっと悲観的な部分多いんだけどね orz

なにせ…様々な質と方向性で山盛りな量のハイエナども見ちゃってるしねぇ orz

不安に思いつつ、しばらくは見守る感じかなぁ?

しばらくの後も見守る以上の事が出来る自信は全然ないんだけど orz