プロじゃないのでコピペでコーディング!

四半世紀に迫ろうとするベテラン・コピペ・プログラマーが送るコピペの元。 張って動けば良し!動かなければなんで?そんな私をサポートするブログです。 ま、動けば良いと本人が思ってるなら、これでも良いんじゃね?って思ったら生暖かく見守って頂き、こりゃ目に余る!って思ったら、優しく教えてやってください。

例外設計

みなさん、コピペに励んでいらっしゃいますでしょうか?

今日も私は絶賛コピペ中です。

この世はコピペでできていると胸を張ったものの、コピペが通用しない世界もあります。

その一つが例外のハンドリング。

もちろんコピペも可能ですが、なんの役にも立っていないことは、ご承知の通りです。

try {
    hogehoge;
} catch(Exception e){
    fugafuga;
}

こんなコピペでも、欲しいと思う人はいないと思いますが、もしもいらっしゃったら...もう少し手元のツールに期待を寄せてみたほうが良いと思います。昨今の開発ツールは、選択したところを対象にtry/catchはサクッと作ってくれちゃうと思います。

この投稿で扱うのは、コピペの話ではありません。なるべくコピペの精神に沿って、難しいことを覚えず、楽をして、まぁまぁきちんと動くというところを目指した場合、どうしたものかについて、考えてみる投稿です。

参考にしたのはこちらのサイト。もちろんストック済みです。 qiita.com

非常に示唆に富む、そして重要な幾つかの参考文献を抑えて、とても参考になる投稿です。ナンチャッテな私は、理解した気は十分、理解度30%に満たない悲しい存在だと思います。

さて、一つだけツッコミを入れてみると、呼び出し元でチェックしておけば、呼び出し先でチェックが不要になる例がありますが、ライブラリみたいにみんなからガシガシ呼ばれる場合には呼び出し先でチェックした方が手数は減りますね。

あと、すべて自分の息のかかったコードなら良いですが、今時のアプリ開発はその契約の及ばないコードが紛れることは避けられず、すべてをこの論法で解決できるわけでもないように思います。

やはりこの手の話は、机上だけで展開すると完結してる風に読めてしまうことがありますが、自分アプリを実例にとって検証と反省を込めた再設計を経て、自分なりの考察する必要がありそうですね。

ということで、なんの結論もない、なんの知見もない、無駄投稿でした。

思えば、このブログも、本来はQiitaでやれば良い内容かも知れませんが、そこまでの自信が有りません。より本職に近い少しだけ自信を持って書ける物だけ、Qiitaで書くという使い分けがなんとなくあります。

Java: Stringでswitch構文をつかう

概要

最近のJavaってばswitch構文でStringが使える。今使おうと思って思い出した。

以前は使えないことに全く違和感を覚えていなかったが、人様の心理からすると使えないなんてあり得ないわけで、まさに低級言語のなを欲しいままにするJavaさまだったわけで。

詳細

String str = "aaa";

switch (str) {
case "aaa":
    System.out.println("strはaaaだってさ");
    break;
case "bbb":
    System.out.println("strはbbbだってさ");
    break;
default:
    System.out.println("どれでもないってどういうことよ");
}

昔はこんなこと出来なったわけで。いまでも==で比較したい一心なわけで。(違うか)

で、かゆいところに手が届くのかと思いきや、いけてない点が少なくとも1つはあって。 それは我らが「ぬるぽ」さま。

ぬるぽって、どんだけ素人なんだよ、どんだけ英語読めないんだよ-。

えーと、このコードの前でNPE対応してください。defaultで捕まえてくれれば良いのに...

出直してこい>switch構文

さいごに

個人的にはswitchって嫌いです。Javaなんてこの世に無かった頃から。

書いていて美しくない気がするし。
そもそも、break書くとか何だよ
if-elseより効率の良いコード吐くかも?って何だよ。

Objective-C: アラートをあげる UIAlertView, UIAlertController

概要

タイトル通り単純明快。 アラートをあげる方法です。

こんな感じです。
f:id:kzthrk:20160316223221p:plain

詳細

コードは、以下の通りです。あ、キャンセル側に「OK」という文字列をアサインしているひねくれた例なのでご注意を。

- (IBAction)PushButton:(id)sender {
    
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"タイトル"
                                                    message:@"メッセージそのもの"
                                                   delegate:self
                                          cancelButtonTitle:@"OK"
                                          otherButtonTitles:@"開く", nil];
    [alert show];

}

- (void)alertView:(UIAlertView*)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
    switch (buttonIndex) {
        case 0:
            [self cancelButton];
            break;
        case 1:
            [self otherButton];
            break;
    }
}

- (void)cancelButton {
    NSLog(@"cancel");
}
- (void)otherButton {
    NSLog(@"other");
}

とまぁ、ここまで書いて思い出しました。昨今、このやり方は古いっすってXcodeさんに警告されることを... でも、古いiOSもサポートするなら使うんでしょ?っていまさらiOS7とかないか。

今からの人は、こちら

で、ついでなので、新しい方も書いてみます。
いや、正確に表現しておきます「コピペしてみました」ですね。

- (IBAction)PushButton:(id)sender {

    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"タイトル"
                                                                             message:@"メッセージ"
                                                                      preferredStyle:UIAlertControllerStyleAlert];

    [alertController addAction:[UIAlertAction actionWithTitle:@"はい"
                                                        style:UIAlertActionStyleDefault
                                                      handler:^(UIAlertAction *action) {
        [self yesButtonPushed];
    }]];
    
    [alertController addAction:[UIAlertAction actionWithTitle:@"いいえ"
                                                        style:UIAlertActionStyleDefault
                                                      handler:^(UIAlertAction *action) {
        // cancelボタンが押された時の処理
        [self noButtonPushed];
    }]];

    [self presentViewController:alertController animated:YES completion:nil];
}
- (void)yesButtonPushed {
    NSLog(@"はい");
}
- (void)noButtonPushed {
    NSLog(@"いいえ");
}

概要の画面ショットは、このサンプルを動かしたときにキャプチャしたものです。

まとめ

なんで、こういうのって変えるんですかね? そして、変えるにしても古いのと新しいので両方面倒みるのが、下々の者っていうのも若干納得がいかないです。

まぁ、コピペするならあんまり関係ないけど。

C# WebBrowserコンポーネントのサンプル

概要

フォームにWebBrowserコンポーネントを配置し、JavaScriptとNativeの連携をしたり、Nativeから任意のURLへ画面遷移させたり。

詳細

配置するコンポーネントはこれですね。

f:id:kzthrk:20160315233044p:plain

以下のソースコード

を指示しています。

webBrowser1.ScriptErrorsSuppressed = true;
webBrowser1.ObjectForScripting = new JavaScript(webBrowser1);
webBrowser1.Navigate(new Uri("http://cheatsheet.hatenablog.com"));

object[] args = { "arg1" };
webBrowser1.Document.InvokeScript("JSfunc1", args);

JavaScript.cs

namespace WindowsFormsApplication1 {

    [System.Runtime.InteropServices.ComVisibleAttribute(true)]

    public class JavaScript {
        private System.Windows.Forms.WebBrowser WebBrowser { get; set; }

        public JavaScript(System.Windows.Forms.WebBrowser dstWebBrowser) {
            this.WebBrowser = dstWebBrowser;
        }

        // JavaScriptから呼ばれるネイティブのメソッド
        public void CSfunc1(string value) {
            MessageBox.Show("CSfunc1: " + value);
        }
    }
}

HTML(JavaScript含む)

<html>
<head>
  <meta charset="UTF-8"> 
  <script>
  function JSfunc1(arg) {
    alert('JSfunc1! : ' + arg);
  }
  
  var jsdata1 = 'jsdata1';
  function clk() {
    window.external.CSfunc1(jsdata1);
  }
  </script>
</head>

<body>
  <input type='button' value='JavaScript To Native' onClick='clk()'>
</body>
</html>

まとめ

あまりおすすめしません。特に、キャッシュ周りとか、確実にはまります。 レンダリングエンジンとかJavaScriptエンジンは、最新なふりはしてくれるのですが、それと同じバージョンのInternet Explorerでの挙動と違う部分があり、それが乗り越えられない部分があります。

間違ってもハイブリッド・アプリ的な考え方で使おうとは思わない方が良いですよ。

C# HTTPリクエストのサンプル

概要

HTTP リクエストを送るサンプルです。
いろんな要素があると思います。使うクラスが違うとか、同期/非同期とか、とか。
一例ということで。

詳細

private static string SendHttpRequest(string url, string jsonStr) {

    try {
        //文字コードを指定する
        Encoding encoding = System.Text.Encoding.GetEncoding("utf-8");

        //WebRequestの作成
        System.Net.WebRequest req = System.Net.WebRequest.Create(url);

        if (jsonStr.Length == 0) {
            //GETリクエスト
            req.Method = "GET";
            req.ContentType = "application/json";
            req.Headers.Add("X-AUTH-TOKEN", authToken);

        } else {
            //POST送信するデータを作成
            byte[] postDataBytes = Encoding.UTF8.GetBytes(jsonStr);

            req.Method = "POST";
            req.ContentType = "application/json";
            req.ContentLength = postDataBytes.Length;
            req.Headers.Add("X-AUTH-TOKEN", authToken);

            //データをPOST送信するためのStreamを取得
            Stream reqStream = req.GetRequestStream();
            //送信するデータを書き込む
            reqStream.Write(postDataBytes, 0, postDataBytes.Length);
            reqStream.Close();
        }

        //サーバーからの応答を受信するためのWebResponseを取得
        System.Net.WebResponse res = req.GetResponse();
        System.IO.Stream resStream = res.GetResponseStream();
        System.IO.StreamReader sr = new System.IO.StreamReader(resStream, encoding);

        string responseBody = sr.ReadToEnd();
        sr.Close();

        return responseBody;

    } catch (Exception ex) {
        return "*** fail ***";
    }
}



さいごに

こうなってくると、ただの備忘録ですね。

C# サブ画面で縁なしWindowにしたい

概要

需要あるかな? まぁ、どうやって動いているかということについて理解する上では、意味があるかも?

  • パソコンの画面が2画面ありました。
  • サブ画面にWindowを移動させました。
  • そこで縁なし(FormBorderStyle.None)にしたいと思いました。
  • メイン画面で縁なしになりました。

そんな残念な私に送る福音です。

詳細

なぜだか、その役割を ボタン7 が担いました。 1行目のscreenを取得して、それをLocationにセットしたのがすべてですね。

これをやっておかないと、いくらWindowをサブ画面に移動させておいても、メイン画面で縁なしになるはずです。

private void button7_Click(object sender, EventArgs e) {

    System.Windows.Forms.Screen screen = System.Windows.Forms.Screen.FromControl(this);
    this.Location = screen.Bounds.Location;
    this.FormBorderStyle = FormBorderStyle.None;
    this.Height = 768;
    this.Width = 1024;
    this.button7.Visible = false;
}


まとめ

まぁ、だれも必要としないかな...

C# リソースで定義した文字列を取得

概要

これも本格的なアプリではあまりやらないかと思いますが、なんちゃってアプリの設定値をどこに保管する?って考えたときに、1つの選択肢になるかと思います。
プロジェクト > xxxのプロパティ のリソースで定義した文字列の取得方法です

詳細

ここに保管した文字列を取得する方法です。

f:id:kzthrk:20160311235525p:plain

コード自体は簡単です。

string str = WindowsFormsApplication1.Properties.Resources.SampleString;


さいごに

この手のことは、知っていれば簡単です。逆に言うと、知らないと全然分からないです。ということは、私は覚える必要は全くないことの証だと思っています。コピペ・プログラマでなくても、コピペ推奨な部分ですね。