例外処理

例外処理

例外処理とは、本来ならばプログラム中で起こってはいけないことが起こってしまうことを言う。 例外が起こったときでもプログラムが異常な動作をしないよう、例外処理(exception handling)を行う必要がある。 例外をキャッチするのは、異常な状態を回復させ、処理を継続する場合のみ。

例外が発生する可能性のある側では、 throw 文を使って例外が起こったことを利用側に知らせる。

throw 例外クラスのインスタンス

この throw 文は想定外のことが起こった場所に挿入する。 throw 文によって投げられる例外は、 System.Exception クラスの派生クラスのインスタンスである。 それ以外のクラスのインスタンスを throw することは出来ない。

ex:

try
{
  例外が投げられる可能性のあるコード
}
catch(例外の種類)
{
  例外処理コード
}
finally
{
  例外発生の有無にかかわらず実行したいコード
  リソースの破棄などを行う
}

別の例外をスローする

try {

} catch (FileNotFoundException ex) {
    throw new MyAppException("ファイルが見つかりませんでした", ex)
}

変数 ex には例外オブジェクトが格納されている。
例外オブジェクトを参照することで、例外の詳細情報を知ることが出来る。

例外が発生したことを把握したい場合・例外の再スロー

try {

} catch (FileNotFoundException ex) {
    Log.Write(ex.ToString()); // Log出力
    throw;
}

特定の例外発生時に、それを無視して処理を継続させたいケースもある。 その場合は、なんの目的でその例外をキャッチするのか、なぜその例外を無視するのかをコメントで残すようにする。 例外を throw する場合、InnerException を破棄してはいけない。

参考: 例外処理 - C# によるプログラミング入門 | ++C++; // 未確認飛行 C 実戦で役立つ C#プログラミングのイディオム/定石&パターン:書籍案内|技術評論社

【Vue.js】DOM から取得してきた値を配列/連想配列化、動的に値を操作する

はじめに

Vue.js に初チャレンジしてみたので、書き残し!

デモ: https://jsfiddle.net/se1yn/tt9fffps/

.ts

var app = new Vue ({
  el: '#app',
  data: {
    itemList: [],
    totalValue: 0,
    selectVal1: 0,
    selectVal2: 0,
    selectVal3: 0,
  },
  computed:{
    isDisabled: function() {
        return ((Number(this.selectVal1) === 0) && (Number(this.selectVal2) === 0) && (Number(this.selectVal3) === 0));
    }
  },
  created: function() {
    this.calc();
  },
  methods: {
    calc: function() {
      let itemList = [];
      let itemListValues = [10, 100, 1000];
            
      $("[id^=name]").each(function () {
        // id から連番取得
        let itemNum: number = Number($(this).attr("id").match(/\d/g));
        
        // 配列にオブジェクトをpush
        itemList.push({
          "name": $("#name" + itemNum).html(),
          "hasNum": Number($("#has-num" + itemNum).html()),
          "selectValue": Number($("#select" + (itemNum)).val()) * itemListValues[itemNum - 1],
          "afterHasNum": Number($("#has-num" + itemNum).html()) - Number($("#select" + (itemNum)).val())
        });
      });

      this.itemList = itemList;
      
      if(!$.isEmptyObject(itemList)) {
        this.totalValue = itemList.map(function(row){
          return [row["selectValue"]]
        }).reduce(function(prev, current){
          return prev.concat(current);
        }).reduce(function(prev, current){
          return prev + current;
        });
      }
    },
    comfirmModal: function(isDisabled, event) {
      if(isDisabled) {
        event.preventDefault();
        return false;
      }
      alert("この内容でアイテムを換金しますか?")
    }
  }
})

勘所

data は初期値、 created で初回に一発 calc メソッドを走らせる
v-on:click="comfirmModal(isDisabled, $event)" の第2引数で event が取得できる
computed で確認ポップアップの enable/disable をセレクトボックスの値に依存させて(ウォッチさせて)切り変える

所感

・公式のガイドライン強い
・ViewModel的な値は, computed を使って get/set した方が良いのかな

参考
computed: 算出プロパティとウォッチャ — Vue.js
component: ミックスイン — Vue.js

http://qiita.com/phi/items/723aa59851b0716a87e3http://qiita.com/phi/items/723aa59851b0716a87e3
https://javascript.programmer-reference.com/jquery-isemptyobject/
http://qiita.com/_shimizu/items/dd72a0f32647abd40fd7

Vue.js 事始め

環境

node: v6.11.0
npm: v3.10.10

Install

下記のコマンドで package.json を作成、
webpack, vue のインストールを行う。

npm init
npm install -g webpack
npm install --save-dev vue

webpack.config.json

const path = require('path');

module.exports = {
    entry: {
        'js/main': './src/js/main.js'
    },
    output: {
        path: path.join(__dirname, 'public'),
        filename: '[name].js'
    },
+    resolve: {
+        alias: {
+            'vue$': 'vue/dist/vue.common.js'
+        }
+    }
}

npm でインストールした vue はランタイム限定ビルドのため、 完全ビルドを利用する場合は、バンドラでエイリアスを設定する必要がある(上記のコードの + 部分)。
https://jp.vuejs.org/v2/guide/installation.html#ランタイム-コンパイラとランタイム限定の違い

index.html

<div id="app">
  {{ message }}
</div>

main.js

var app = new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue!'
  }
})

webpack コマンドを打って、

> webpack

index.html をブラウザで開き、 Hello Vue! が画面に出力されれば OK

Hello Vue!

参考:
はじめに — Vue.js
https://goodlife.tech/web/vue-js/

Visual Studio Code で C# コンソールアプリケーション実行とデバッグ

環境構築/実行

[1] .NET Core のサイトから .NET Core SDK を install
※自分は下記から .NET Core SDK 1.1 RC4 を選択 github.com

[2] コマンドラインでテンプレートを作成

dotnet new console
dotnet restore
dotnet run

f:id:danker512:20170713011106p:plain

[3] デバッグ実行(F5)

C#7 の Taple を使ってみる

  1. VSC の 拡張機能 で NugetPackageManager をインストール
  2. コマンドパレット(Ctrl+Shift+P)から NugetPackageManager -> System.ValueTuple -> 4.3.0 を選択

f:id:danker512:20170713011635p:plain

※「preLaunchTask build が見つかりませんでした」系の error が一度発生したが、VSC再起動で解決。

参考:
.NET Core のバージョンが難しい - しばやん雑記
Running C# 7 Code With Visual Studio Code Editor
【.NET Core 1.1】dotnet new コマンドで作成できるテンプレートのまとめ: Shion のブログ
Visual Studio Code でサクッと C# のコンソールアプリをデバッグしよう - Windows 編 - Xamarin 日本語情報

Tour of Heroes

The Hero Editor

app.components.ts

import { Component } from '@angular/core';

export class Hero {
  id: number;
  name: string;
}

@Component({
  selector: 'my-app',
  template: `
    <h1>Hello {{name}}</h1>
    <h2>{{hero.name}} details!!</h2>
    <div><label>id: </label>{{hero.id}}</div>
    
    <div>
      <label>name: </label>
      <input [(ngModel)]="hero.name" placeholder="name">
    </div>
  `
})

export class AppComponent {
  name = 'Tour of Heroes';
  hero: Hero = {
    id: 1,
    name: 'Windstorm'
  } 
}

app.modele.ts

import { NgModule }      from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule }   from '@angular/forms'; <-

import { AppComponent }  from './app.component';

@NgModule({
  imports:      [ BrowserModule, FormsModule ], <-
  declarations: [ AppComponent ],
  bootstrap:    [ AppComponent ]
})

export class AppModule { }

Master/Detail

app.component.ts

import { Component } from '@angular/core';

const HEROES: Hero[] = [
  { id: 11, name: 'Mr. Nice' },
  { id: 12, name: 'Narco' },
  { id: 13, name: 'Bombasto' },
  { id: 14, name: 'Celeritas' },
  { id: 15, name: 'Magneta' },
  { id: 16, name: 'RubberMan' },
  { id: 17, name: 'Dynama' },
  { id: 18, name: 'Dr IQ' },
  { id: 19, name: 'Magma' },
  { id: 20, name: 'Tornado' }
];

export class Hero{
    id: number;
    name: string;
}

@Component({
    selector: 'my-app',
    template: `
        <h1>Tour of Heroes</h1>
        <h2>My Heroes</h2>
        <ul class="heroes">
            <li *ngFor="let hero of heroes" [class.selected]="hero === selectedHero" (click)="onSelect(hero)">
                <!-- each hero goes here -->
                <span class="badge">{{hero.id}}</span> {{hero.name}}
            </li>
        </ul>

        <div *ngIf="selectedHero">
          <h2>{{selectedHero.name}} details!</h2>
          <div><label>id: </label>{{selectedHero.id}}</div>
          <div>
            <label>name: </label>
            <input [(ngModel)]="selectedHero.name" placeholder="name"/>
          </div>
        </div>
    `,
    styles: [`
      .selected {
        background-color: #CFD8DC !important;
        color: white;
      }
      .heroes {
        margin: 0 0 2em 0;
        list-style-type: none;
        padding: 0;
        width: 15em;
      }
      .heroes li {
        cursor: pointer;
        position: relative;
        left: 0;
        background-color: #EEE;
        margin: .5em;
        padding: .3em 0;
        height: 1.6em;
        border-radius: 4px;
      }
      .heroes li.selected:hover {
        background-color: #BBD8DC !important;
        color: white;
      }
      .heroes li:hover {
        color: #607D8B;
        background-color: #DDD;
        left: .1em;
      }
      .heroes .text {
        position: relative;
        top: -3px;
      }
      .heroes .badge {
        display: inline-block;
        font-size: small;
        color: white;
        padding: 0.8em 0.7em 0 0.7em;
        background-color: #607D8B;
        line-height: 1em;
        position: relative;
        left: -1px;
        top: -4px;
        height: 1.8em;
        margin-right: .8em;
        border-radius: 4px 0 0 4px;
      }
    `]
})

export class AppComponent {
    title = 'Tour of Heroes';
    public heroes = HEROES;
    selectedHero: Hero;
    onSelect(hero: Hero): void { this.selectedHero = hero; }
}

Multiple Components

app.module.ts

import { NgModule }      from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule }   from '@angular/forms';

import { AppComponent }  from './app.component';
import { HeroDetailComponent } from './hero-detail.component';

@NgModule({
  imports:      [ BrowserModule, FormsModule ],
  declarations: [ AppComponent, HeroDetailComponent ],
  bootstrap:    [ AppComponent ]
})

export class AppModule { }

app.components.ts

import { Component } from '@angular/core';
import {Hero} from './hero';


const HEROES: Hero[] = [
  { id: 11, name: 'Mr. Nice' },
  { id: 12, name: 'Narco' },
  { id: 13, name: 'Bombasto' },
  { id: 14, name: 'Celeritas' },
  { id: 15, name: 'Magneta' },
  { id: 16, name: 'RubberMan' },
  { id: 17, name: 'Dynama' },
  { id: 18, name: 'Dr IQ' },
  { id: 19, name: 'Magma' },
  { id: 20, name: 'Tornado' }
];

@Component({
    selector: 'my-app',
    template: `
        <h1>Tour of Heroes</h1>
        <h2>My Heroes</h2>
        <ul class="heroes">
            <li *ngFor="let hero of heroes" [class.selected]="hero === selectedHero" (click)="onSelect(hero)">
                <!-- each hero goes here -->
                <span class="badge">{{hero.id}}</span> {{hero.name}}
            </li>
        </ul>
        <hero-detail [hero]="selectedHero"></hero-detail>
    `,
    styles: [`
      .selected {
        background-color: #CFD8DC !important;
        color: white;
      }
      .heroes {
        margin: 0 0 2em 0;
        list-style-type: none;
        padding: 0;
        width: 15em;
      }
      .heroes li {
        cursor: pointer;
        position: relative;
        left: 0;
        background-color: #EEE;
        margin: .5em;
        padding: .3em 0;
        height: 1.6em;
        border-radius: 4px;
      }
      .heroes li.selected:hover {
        background-color: #BBD8DC !important;
        color: white;
      }
      .heroes li:hover {
        color: #607D8B;
        background-color: #DDD;
        left: .1em;
      }
      .heroes .text {
        position: relative;
        top: -3px;
      }
      .heroes .badge {
        display: inline-block;
        font-size: small;
        color: white;
        padding: 0.8em 0.7em 0 0.7em;
        background-color: #607D8B;
        line-height: 1em;
        position: relative;
        left: -1px;
        top: -4px;
        height: 1.8em;
        margin-right: .8em;
        border-radius: 4px 0 0 4px;
      }
    `]
})

export class AppComponent {
    title = 'Tour of Heroes';
    public heroes = HEROES;
    selectedHero: Hero;
    onSelect(hero: Hero): void { this.selectedHero = hero; }
}

hero-detail.component.ts

import { Component, Input } from '@angular/core';
import {Hero} from './hero';

@Component({
  selector: 'hero-detail',
  template: `
    <div *ngIf="hero">
      <h2>{{hero.name}} details!</h2>
      <div><label>id: </label>{{hero.id}}</div>
      <div>
        <label>name: </label>
        <input [(ngModel)]="hero.name" placeholder="name"/>
      </div>
    </div>
  `
})

export class HeroDetailComponent {
    @Input() hero: Hero;
}

hero.ts

export class Hero {
  id: number;
  name: string;
}

Services

hero.service.ts

import { Injectable } from '@angular/core';

import { Hero } from './hero';
import { HEROES } from './mock-heroes';

@Injectable()

export class HeroService {
  getHeroes(): Promise<Hero[]> {
    return Promise.resolve(HEROES);
  }
}

app.component.ts

import { Component, OnInit } from '@angular/core';
import { Hero } from './hero';
import { HeroService } from './hero.service';

@Component({
    selector: 'my-app',
    template: `
        <h1>Tour of Heroes</h1>
        <h2>My Heroes</h2>
        <ul class="heroes">
            <li *ngFor="let hero of heroes" [class.selected]="hero === selectedHero" (click)="onSelect(hero)">
                <!-- each hero goes here -->
                <span class="badge">{{hero.id}}</span> {{hero.name}}
            </li>
        </ul>
        <hero-detail [hero]="selectedHero"></hero-detail>
    `,
    styles: [`
      .selected {
        background-color: #CFD8DC !important;
        color: white;
      }
      .heroes {
        margin: 0 0 2em 0;
        list-style-type: none;
        padding: 0;
        width: 15em;
      }
      .heroes li {
        cursor: pointer;
        position: relative;
        left: 0;
        background-color: #EEE;
        margin: .5em;
        padding: .3em 0;
        height: 1.6em;
        border-radius: 4px;
      }
      .heroes li.selected:hover {
        background-color: #BBD8DC !important;
        color: white;
      }
      .heroes li:hover {
        color: #607D8B;
        background-color: #DDD;
        left: .1em;
      }
      .heroes .text {
        position: relative;
        top: -3px;
      }
      .heroes .badge {
        display: inline-block;
        font-size: small;
        color: white;
        padding: 0.8em 0.7em 0 0.7em;
        background-color: #607D8B;
        line-height: 1em;
        position: relative;
        left: -1px;
        top: -4px;
        height: 1.8em;
        margin-right: .8em;
        border-radius: 4px 0 0 4px;
      }
    `],
    providers: [HeroService]
})

export class AppComponent implements OnInit {
  title = 'Tour of Heroes';
  heroes: Hero[];
  selectedHero: Hero;
 
  constructor (private heroService: HeroService) { }
 
  getHeroes(): void {
    this.heroService.getHeroes().then(heroes => this.heroes = heroes);
  }
 
  ngOnInit(): void {
    this.getHeroes();
  }
 
  onSelect(hero: Hero): void {
    this.selectedHero = hero;
  }
}

mock-heroes.ts

import { Hero } from './hero';
 
export const HEROES: Hero[] = [
  { id: 11, name: 'Mr. Nice' },
  { id: 12, name: 'Narco' },
  { id: 13, name: 'Bombasto' },
  { id: 14, name: 'Celeritas' },
  { id: 15, name: 'Magneta' },
  { id: 16, name: 'RubberMan' },
  { id: 17, name: 'Dynama' },
  { id: 18, name: 'Dr IQ' },
  { id: 19, name: 'Magma' },
  { id: 20, name: 'Tornado' }
];

Routing

Routing に関しては、理解するのに時間が掛かった。
重要だと思う部分を列挙してみる。
server-side rendering で言うと、Controller に近いのかな。 コード内の不明な箇所は F12 (VisualStudioCode) で定義に移動して行くと繋がりが見えてくる気がする!

  • Routing is another name for navigation. The router is the mechanism for navigating from view to view.
    Routing はナビゲーションの別の名前。Router は View と View を繋ぐメカニズム。
  • RouterModuleは、外部オプションなので package のような形で読み込む
  • Routing 専用のクラスは RoutingModule へ

Router outlet

Route は Path を HeroRoute に一致させ、HeroesComponentを表示させる。 ただし、Router にコンポーネントの表示先を伝える必要があるため、テンプレートの最後に <router-outlet> 要素を追加する。 RouterOutlet は、RouterModule によって提供されるディレクティブの1つである。

app.module.ts

import { NgModule }       from '@angular/core';
import { BrowserModule }  from '@angular/platform-browser';
import { FormsModule }    from '@angular/forms';

import { AppComponent }         from './app.component';
import { DashboardComponent }   from './dashboard.component';
import { HeroDetailComponent }  from './hero-detail.component';
import { HeroesComponent }      from './heroes.component';
import { HeroService }          from './hero.service';

import { AppRoutingModule }     from './app-routing.module';

@NgModule({
  imports: [
    BrowserModule,
    FormsModule,
    AppRoutingModule
  ],
  declarations: [
    AppComponent,
    DashboardComponent,
    HeroDetailComponent,
    HeroesComponent
  ],
  providers: [ HeroService ],
  bootstrap: [ AppComponent ]
})
export class AppModule { }

app-routing.module.ts

import { NgModule }             from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

import { DashboardComponent }   from './dashboard.component';
import { HeroesComponent }      from './heroes.component';
import { HeroDetailComponent }  from './hero-detail.component';

const routes: Routes = [
  { path: '', redirectTo: '/dashboard', pathMatch: 'full' },
  { path: 'dashboard',  component: DashboardComponent },
  { path: 'detail/:id', component: HeroDetailComponent },
  { path: 'heroes',     component: HeroesComponent }
];

@NgModule({
  imports: [ RouterModule.forRoot(routes) ],
  exports: [ RouterModule ]
})
export class AppRoutingModule {}

app.component.ts

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  template: `
    <h1>{{title}}</h1>
    <nav>
      <a routerLink="/dashboard" routerLinkActive="active">Dashboard</a>
      <a routerLink="/heroes" routerLinkActive="active">Heroes</a>
    </nav>
    <router-outlet></router-outlet>
  `,
  styleUrls: ['./app.component.css'],
})

export class AppComponent {
  title = 'Tour of Heroes';
}

heroes.component.ts

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';

import { Hero } from './hero';
import { HeroService } from './hero.service';

@Component({
  selector: 'my-heroes',
  templateUrl: './heroes.component.html',
  styleUrls: [ './heroes.component.css' ]
})

export class HeroesComponent implements OnInit {
  heroes: Hero[];
  selectedHero: Hero;

  constructor(
    private router: Router,
    private heroService: HeroService) { }

  getHeroes(): void {
    this.heroService.getHeroes().then(heroes => this.heroes = heroes);
  }

  ngOnInit(): void {
    this.getHeroes();
  }

  onSelect(hero: Hero): void {
    this.selectedHero = hero;
  }

  gotoDetail(): void {
    this.router.navigate(['/detail', this.selectedHero.id]);
  }
}

hero.service.ts

import { Hero } from './hero';
import { HEROES } from './mock-heroes';
import { Injectable } from '@angular/core';

@Injectable()
export class HeroService {
  getHeroes(): Promise<Hero[]> {
    return Promise.resolve(HEROES);
  }

  getHeroesSlowly(): Promise<Hero[]> {
    return new Promise(resolve => {
      // Simulate server latency with 2 second delay
      setTimeout(() => resolve(this.getHeroes()), 2000);
    });
  }

  getHero(id: number): Promise<Hero> {
    return this.getHeroes()
               .then(heroes => heroes.find(hero => hero.id === id));
  }
}

参考:https://angular.io/tutorial/