次に、コード生成と創造性を結び付ける方法について説明します。
コード生成を理解するために、それを試してみましょう。
構造
PHPプロジェクトを作成し、そこに3つのディレクトリを追加しましょう。
1.
source-ソースコードを追加するディレクトリ。
2.
gen-コード生成スクリプトを含むディレクトリ。
3. result-
結果のあるディレクトリ。
ルートへの1つのファイル:
make.php-コード生成ルールを決定し、コード生成プロセスを開始します。
プロセス
コード生成によりmake.phpファイルが実行され、このプロセスの実行方法に関する指示が含まれます。
一般的には、次のようになります。
手順make.php + ソースディレクトリのソースコード-> genディレクトリのスクリプトによる処理->結果を結果ディレクトリに生成します。始めましょう
開始するには、処理せずに
ソースから
結果にデータをコピーしてみましょう。 将来、このデータの処理を実装できるように、各ファイルの内容を読み取り、書き込みます。
ソースから
結果を生成する前に、
結果をクリアする必要があります。その
ために、
genディレクトリに次の内容の
clear.phpを作成します。
機能クリア()
{
full_delete(dirname(__ FILE__)。 '/../result'、false );
}
関数 full_delete( $ dir 、 $ delete_me )
{
if (! $ dh = @opendir( $ dir )) return ;
while ( false !==( $ obj = readdir( $ dh ))){
if ( $ obj == '。' || $ obj == '..' ) continue ;
もし
(!@unlink(
$ dir 。
' /'。$
obj ))full_delete(
$ dir 。
' /'。$
obj 、
true );
}
closedir(
$ dh );
if (
$ delete_me )@rmdir(
$ dir );
}
ここでは、php.netで見つけたfull_delete関数を使用し、ほとんど変更しませんでした。
ここで処理を考えてみましょう。
ソースディレクトリに
index.phpファイルを作成し、次のように記述します。
echo 'Hello world!' ;
次の2つの理由でPHPタグを提供していません。
1.あなたはそれらをどこに置くかを自分で理解しています。
2. Habrはそれらを食べます。gen / filter.phpファイルにフィルターを作成しましょう:
関数フィルター( $ input )
{
$出力 = $入力 ;
return $ output ;
}
そして、
make.phpに指示を書くことができます:
'gen / clear.php' が必要です 。
'gen / filter.php' が必要です 。
クリア();
$ index = file_get_contents( 'source / index.php' );
file_put_contents( 'result / index.php' 、フィルター( $ index ));
どうした
私たちは特定の概念を実装しましたが、これはまだ役に立たないものの、特定の可能性を秘めています。
フィルターを改良しましょう!
プリプロセッサ
私たちのシステムを試してみましょう。 PHPのラムダ式が本当に恋しいです。 それらの類似性の一部を実験として実装できます。
私はいつもusort関数を使用することを好まなかったので、別の関数を作成する必要があり、create_functionを使用することはまったく楽しいものではありませんでした。 いくつかの制限されたラムダ構文を実装しましょう。
私は `文字を使用しないので(shell_exec関数への単純化されたアクセスを実装しています)、ラムダ式に簡単に寄付できます。 ラムダ式の実験的な構文:
`引数リスト->アクション`
例:
` $ var1 、 $ var2- > $ var1 + $ var2`
このような構成を処理するには、ファイル
gen / filter.phpに filter_lambda関数を記述します。
$ uid = 0 ;
関数 filter_lambda( $ input )
{
グローバル $ uid ;
$ additional_code = '' ;
while (( $ spos = strpos( $ input 、 '' ' ))!== false )
{
$ epos = strpos( $ input 、 '' ' 、 $ spos + 1 );
$ expr = substr( $ input 、 $ spos + 1 、 $ epos-$ spos - 1 );
$ divider_pos = strpos( $ expr 、 '->' );
$ vars = trim(substr( $ expr 、 0 、 $ divider_pos ));
$ body = trim(substr( $ expr 、 $ divider_pos + 2 ));
$ additional_code 。= "function lambda_ $ uid ( $ vars ){return( $ body );} \ n" ;
$ input = substr( $ input 、0、 $ spos )。 "'lambda_ $ uid '" .substr( $ input 、 $ epos +1);
$ uid ++;
}
return ( $ additional_code != '' ? "<?php \ n $ additional_code ?>" : '' )。 $入力 ;
}
次に、フィルター関数を改良します。
関数フィルター( $ input )
{
$出力 = $入力 ;
$ output = filter_lambda( $ output );
return $ output ;
}
結果
これで、
source / index.phpファイルに書き込むことができます。
$数 =配列( 'much long' 、 'short' 、 'longer' );
usort( $ numbers 、 `$ value1、$ value2- > strlen($ value1)> strlen($ value2)` );
foreach ( $ キー としての 数字 == 値 )
{
echo " $ key : $ value <br/>" ;
}
make.phpを実行し、
result / index.phpを取得します。
<?php
function lambda_0( $ value1 、 $ value2 ){ return (strlen( $ value1 )> strlen( $ value2 ));}
?> <?php
$数 = 配列 ( 'much long' 、 'short' 、 'longer' );
usort( $ numbers 、 'lambda_0' );
foreach ( $ キー としての 数字 == 値 )
{
echo " $ key : $ value <br/>" ;
}
?>
残念ながら、PHPにはラムダ式はなく、この方法でさえ完全ではありません-ラムダ式で(環境から)変数を使用することはできません。
おわりに
このかなり単純な実験は、ソースコードに規則を追加し、単純な規則から複雑な規則を作成する方法を示しています。 この実験は完璧とはほど遠いです。理想的には、解析などを使用する必要がありますが、経験によりコードの前処理とコード生成の力を感じることができます。
さらに一歩
素材を統合して、次のような興味深いタスクを実現することを提案します。
1.
make.phpに各ファイルを書き込まないように、
ソースディレクトリからphpファイルを再帰的に処理します。
2.条件付き生成(Cなど)の実装を試みます-#define、#ifdef、#elif、#endifの類似物。