無精で短気で傲慢なプログラマ

UNIX や web やプログラムの技術的なことを中心に。

社会人の技術レベル その2

社会人の技術レベル のつづき

へにかさんのコメント:
> ある程度枯れたソースを流用したほうが、トラブルが少ない、という理由
> かも知れません。

ごもっともです。
 - コピペによる短期的な修正量削減・リスク軽減をとるか
 - コピペをせずに中・長期的な修正量削減tと、美しい設計による保守コスト削減をとるか
という話なわけで、どちらにするかはそのときの状況判断次第です。

しかし「コピペをせずにすむ技術力を持ちつつ、状況次第ではコピペする」
ならば理解できますが、わたしの見る限り技術力がないのでコピペしかできない
人がほとんどでした。

一般論で終わってしまうのも嫌なので具体的な例を出します。DB からデータを
取得して、CSV ファイル 10個に出力するプログラムがあるとします。10 ファイルを
まとめてオープンする処理を書かせるとします。すると、

  fp1 = fopen(CSV_OUT_1, "w");
  if ( fp1 == NULL ){
    char errmsg[ERRMSG_LEN];
    sprintf(errmsg, "CSVファイルオープンエラー");
    err_fp = fopen(LOGFILE, "a");
    fprintf(err_fp, errmsg);
    fclose(err_fp);
    EXEC SQL ROLLBACK;
    EXEC SQL DISCONNECT;
    exit(1);
  }
  fp2 = fopen(CSV_OUT_2, "w");
  if ( fp2 == NULL ){
    char errmsg[ERRMSG_LEN];
    sprintf(errmsg, "CSVファイルオープンエラー");
    err_fp = fopen(LOGFILE, "a");
    fprintf(err_fp, errmsg);
    fclose(err_fp);
    EXEC SQL ROLLBACK;
    EXEC SQL DISCONNECT;
    fclose(fp1);
    exit(1);
  }
  fp3 = fopen(CSV_OUT_3, "w");
  if ( fp3 == NULL ){
    char errmsg[ERRMSG_LEN];
    sprintf(errmsg, "CSVファイルオープンエラー");
    err_fp = fopen(LOGFILE, "a");
    fprintf(err_fp, errmsg);
    fclose(err_fp);
    EXEC SQL ROLLBACK;
    EXEC SQL DISCONNECT;
    fclose(fp1);
    fclose(fp2); ← ★ここがどんどん増えていくことに注意
    exit(1);
  }
  … 以下 fp4~fp10 略。


というソースを平気で書いたりする。

おいおい、って感じですよね (ちなみに、どのファイルをオープンしようとして
エラーになったのかわからないし、errno も記録していない。ひどいのになると
いきなり exit しておしまいってのもよく見ました)。

わたしなら、

  char *csv_outfile[] = {CSV_OUT_1, CSV_OUT_2, CSV_OUT_3 ... };
  FILE *csv_fp[(csv_outfile)/sizeof(csv_outfile[0])];
  for ( i=0 ; i<sizeof(csv_outfile)/sizeof(csv_outfile[0]) ; i++ ){
    csv_fp[i] = fopen(csv_outfile[i], "w");
    if ( csv_fp[i] == NULL ){
      /* 可変長引数なログ出力関数 logging を作る */
      logging("CSVファイル [%s] オープンエラー。errno[%s]",
              csv_outfile[i], strerror(errno));
      /* わたしはこういう場合は fclose せず OS にまかせますが、まぁ一応 */
      for ( ; i>=0 ; i-- ){
        fclose(csv_fp[i]);
      }
      EXEC SQL ROLLBACK;
      EXEC SQL DISCONNECT;
      exit(1);
    }
  }


と書きます。ログファイルに

  CSVファイル[/foo/bar/hoge.csv](ほげシステム出力用CSV)] オープンエラー。
   errno[Permission Denied]

などとファイルの種類 (ほげシステム~ってところ) を出力したいがために、

  typedef struct {
    char filename[FILE_MAX]; /* ファイル名 */
    char description[256];   /* 説明用文章。エラー発生時などに使用 */
    FILE *fp;
  } csv_info_t;
  csv_into_t csv_info[] = {
    {CSV_OUT_1, "ほげシステム出力用CSV"},
    {CSV_OUT_2, "ほげ料金請求額CSV"},
    {CSV_OUT_3, "ふが料金請求額CSV"},
    ...
  };
  for ( i=0 ; i<sizeof(csv_info)/sizeof(csv_info[0]) ; i++ ){
    csv_info_t *csv_p = &csv_info[i];
    csv_p->fp = fopen(csv_p->filename, "w");
    if ( csv_p->fp == NULL ){
      logging("CSVファイル [%s](%s)オープンエラー。errno[%s]",
      csv_p->filename, csv_p->description, strerror(errno));
      ..
    }
  }


とさらにもう一段抽象化するかもしれません。

もし何かの事情があってファイルオープン処理は 10回書かざるをえないとしても、

  char *csv_outfile[] = {CSV_OUT_1, CSV_OUT_2, CSV_OUT_3 ... };
  FILE *csv_fp[(csv_outfile)/sizeof(csv_outfile[0])];
  memset(csv_fp, NULL, sizeof(csv_fp));
  csv_fp[0] = fopen(CSV_OUT_1, "w");
  if ( csv_fp[0] == NULL ){
    sprintf(errmsg, "CSVファイル [%s] オープンエラー。errno[%s]",
            CSV_OUT_1, strerror(errno));
    goto err;
  }
  csv_fp[1] = fopen(CSV_OUT_2, "w");
  if ( csv_fp[1] == NULL ){
    sprintf(errmsg, "CSVファイル [%s] オープンエラー。errno[%s]",
            CSV_OUT_2, strerror(errno));
    goto err;
  }
  (略)
  return RET_OK;

 err:
  err_fp = fopen(LOGFILE, "a"); /* ログオープンエラー処理略 */
  fprintf(err_fp, "%s\n", errmsg);
  fclose(err_fp);
  for ( i=0 ; i<(sizeof(csv_fp)/sizeof(csv_fp[0]) ; i++ ){
    if ( csv_fp[i] != NULL ){
      fclose(csv_fp[i]);
    }
  }
  EXEC SQL ROLLBACK;
  EXEC SQL DISCONNECT;
  return RET_NG;


などとエラー処理は一箇所にまとめてほしいものです。でもそれすらできません。

新人がしょーもないソースを書くのは仕方がないですが、それを指導するのは
先輩のはず。でも、その先輩にも技術力がないので指摘することができない。

かなりレベルが低い例で恐縮ですが、わたしの言うコピペというのはこういう
情けないレベルの話です。「ある程度枯れたソースを流用」云々以前の問題です。

こういう低レベルな悩みはないのであれば、へにかさんの会社 or 部署のレベルが
高いか、組み込み系全体のレベルが業務系よりは高いのかなぁと思ったりします。

まだまだ続きます。

P.S.
へにかさん、いろいろご心配頂いて申し訳ありません。とりあえず今はとても
楽しくやっております。上記のような汚いソースを書く輩がいたら、
 「こんな汚いソースは初めて見ました」
と言って (嫌な奴)、何度でも書き直させます。
スポンサーサイト

PageTop

コメント


管理者にだけ表示を許可する
 

安心しました。

> とりあえず今はとても 楽しくやっております。
あぁ、安心しました。楽しくやれている、と言うのが、一番です。いやいやながらやっているのって、辛いだけですし。

>上記のような汚いソースを書く輩がいたら、
> 「こんな汚いソースは初めて見ました」
>と言って (嫌な奴)、何度でも書き直させます。
はは、凄いですね。まぁ、それも程々に。
今は恐らく20台だからそれも通じますけど、30台だと、相手を腐らせず奮起させて成長させる事も、重要な能力の一つになってきますので、今のうちに相手の反応を見ながら、そっち方面の研究も進めておいたほうが良いですよ。

> こういう低レベルな悩みはないのであれば、へにかさんの会社 or 部署のレベルが
> 高いか、組み込み系全体のレベルが業務系よりは高いのかなぁと思ったりします。
僕自身の能力はともかく、専門の部署のレベルは相当高いですよ。←自分のレベルが低いのにどうやったら「高い」と言い切れるのが、自分自身、不思議ですが、そう感じています。

> まだまだ続きます。
楽しみに待っております。

へにか | URL | 2005-10-26(Wed)04:52 [編集]


> いやいやながらやっているのて、辛いだけですし。

激しく同感であります。

> はは、凄いですね。まぁ、それも程々に。

コーチング・ティーチング技術についても色々と話したいのですが、個人差が
大きい・正解がない・文章でやりとりしても一般論に終始してしまう、という
理由からやめておきます。まぁ「汚いソース」云々は人を選んで言っている
つもりですが、これまでひとりだけ怒り出した人に出会いましたので、まだまだ
未熟ということなのでしょう。精進します。

> 専門の部署のレベルは相当高いですよ。

よくわかりませんが、そうなんだろうなぁと思います。一度そういうところに
入ってみたいものですが、もう無理かもしれませんねぇ。

「嫌気がさしてるのでは?」とご心配いただきましたが、まわりのレベルが
低いこと自体は嫌なわけではありません (それは 2年目あたりであきらめた)。

レベルが低いなら低いなりに教育する楽しみがあります。あんな汚いソースを
書いていた人がこんな美しいソースを…とか、CVS 導入時にあれだけ反対して
いた先輩が別プロジェクトで CVS を導入しようと言い出したとか、NULL の
恐ろしさをしつこく語ったおかげで何も言わなくても新規テーブルに NOT NULL
制約が付くようになった…などなど (またしても低レベルな話で恐縮ですが)。

わたしの力量ではレベル 1 の人をレベル 10 に引き上げることはできませんが、
レベル 3 なら何とか、という感じです。でもそれはそれで楽しいものです。
というわけで、新しいところでもダメ出しし続ける毎日です。

68user | URL | 2005-10-27(Thu)02:15 [編集]


> レベルが低いなら低いなりに教育する楽しみがあります。
普通ならストレスをためるところを、楽しみに昇華させられる、ということは、精神衛生上、良いことです。ですので、これは素晴らしいとこと思います。

> レベル 3 なら何とか
十分すぎますよ。
> レベル 10 に引き上げる
僕の知っている限り、ほとんど見たことがないです。

これまでの、やり取りの中で、思った以上に楽しみながらお仕事をやられているのがわかって、個人的にはとても嬉しく思います。これからも、良い調子でお仕事を進めていってくださいね。

追伸;
> 一般論に終始してしまう
僕の場合、つい、一般論を持ち出してしまう傾向があります。
年とった証拠だよなぁ、と、気が付かされました。実際、既に中年の部類に入ってしまってますし。
自戒を込めつつ、この点について、感謝致します。

へにか | URL | 2005-10-27(Thu)05:12 [編集]


> 僕の場合、つい、一般論を持ち出してしまう傾向があります。

文字だけのやりとりで怒り方の良し悪しを語るのは非常に難しいので、
一般論になってしまうのは致し方ないと思います。

なお、私信は画面上からは見えないようにしましたが、消したわけでは
ありませんのでご了承ください。

68user | URL | 2005-10-31(Mon)01:14 [編集]