質問するログイン新規登録

回答編集履歴

2

本筋と離れた箇所を末尾に移動

2016/11/14 04:55

投稿

miyabi-sun
miyabi-sun

スコア21505

answer CHANGED
@@ -7,45 +7,16 @@
7
7
  Usageもわずか数行で済みます。
8
8
  例えば計算式をDBに登録したいという要望があっても、バリデーションチェックにわずか1〜2行しかかかりません。
9
9
 
10
+ (4)までやるのは反対です。
10
- もう一つ手段値が複数欲しという要望含まているの
11
+ 問題解決の仕方シンプルで分かやすもの1つあば十分す。
11
- Node.jsでよくあるコールバック関数にしてしまうやり方もありでしょう(try~catchはなくなりますが…)
12
12
 
13
- ```JavaScript
14
- var evalCalc = function(it, cb) {
15
- // チェック
16
- if (syntaxError) {
17
- cb errors, NaN;
18
- return;
19
- }
20
- // 計算
21
- cb null, result;
22
- }
23
-
24
- evalCalc('1+2', function(err, result) {
25
- if (err) {
26
- console.error(err);
27
- }
28
- console.log(result);
29
- });
30
- ```
31
-
32
13
  [2][3]に関しては変動を許容すると、Usageやコアのソースコードがそれだけ追加されます。
33
- 十分なUsageやコードを書くコスト、読むコストを払うだけの機能であれば十分ありですが、
14
+ 十分なUsageやコードを書くコスト、読むコストを払うだけの機能であれば十分ありでしょう。
34
- evalCalcはそれだけの規模なのか否かという話になりますが、質問文を読む限り利用者目線では無しです。
15
+ evalCalcはそれだけの規模なのかという話になりますが、質問文を読む限り利用者目線では無しです。
35
16
 
36
17
  ただし、プロジェクトやチーム単位で設計や思想が異なるものなので、許容されるケースなら積極的に使った方が良いでしょう。
37
18
  例えばjQueryとか…個人がオレオレな書き方すると一貫性がなくなり極めて汚いですからね。
38
19
 
39
- > Promise の可否
40
-
41
- [MDNのPromise](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise)では下記のように定義されています。
42
-
43
- > Promiseオブジェクトは処理の延期(deferred)と非同期処理のために使われます。Promiseはまだ完了していないが、いずれ完了する処理を表します。
44
-
45
- evalという同期的な
46
-
47
- ---
48
-
49
20
  > [1] 関数を一つにするか複数に分けるか
50
21
 
51
22
  必要な数だけ分かれて欲しいです。
@@ -114,3 +85,39 @@
114
85
  PHPにin_arrayという配列から一致する要素があればtrueを返す標準関数がありますが、
115
86
  デフォルトは==で比較して、第三引数にtrueを入れると===になる糞仕様です。
116
87
  このように設計者と開発者の感覚がミスマッチすると、毎回最終引数に無駄なtrueを書き込むハメになりますから他の逃げ方が良いと思います。
88
+
89
+ ---
90
+
91
+ > Promise の可否
92
+
93
+ [MDNのPromise](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise)では下記のように定義されています。
94
+
95
+ > Promiseオブジェクトは処理の延期(deferred)と非同期処理のために使われます。Promiseはまだ完了していないが、いずれ完了する処理を表します。
96
+
97
+ evalという同期的な処理の為にPromiseを使うのは流石に冗長過ぎるかなぁ…と感じます。
98
+
99
+ ---
100
+
101
+ 「別解」
102
+
103
+ 戻り値が複数欲しいというのが根本の質問だと思いますので、
104
+ Node.jsでよくあるコールバック関数にしてしまうやり方も非推奨ながら手段の一つではあります。
105
+
106
+ ```JavaScript
107
+ var evalCalc = function(it, cb) {
108
+ // チェック
109
+ if (syntaxError) {
110
+ cb errors, NaN;
111
+ return;
112
+ }
113
+ // 計算
114
+ cb null, result;
115
+ }
116
+
117
+ evalCalc('1+2', function(err, result) {
118
+ if (err) {
119
+ console.error(err);
120
+ }
121
+ console.log(result);
122
+ });
123
+ ```

1

頓珍漢な回答だったので修正。

2016/11/14 04:55

投稿

miyabi-sun
miyabi-sun

スコア21505

answer CHANGED
@@ -1,20 +1,116 @@
1
- 4)でやるなら[npm phantom](https://github.com/amir20/phantomjs-node)を参考にしてみてはどうでしょう。
2
- Calculation「俺自身がPromise1実装だ!だからeval発火するようにすればい」
1
+ (最初回答文は頓珍漢なの削りました、読む場合は履歴を追って下さ。)
3
2
 
4
- 私個人感性として、計算される対象「Calculation」`1+2`文字列自身で、
3
+ 今回スタンスSyntaxError最初1個だけいいじゃんと考えていますが
5
- それ評価してくれる「Calculator」さんに計算をお願いするのが自然な気がしたの書いした
4
+ 類似の複数エラーべきケースもあと思うので、前提を満たすように考えいき
6
- いまいちだったら無視してください。
7
5
 
6
+ まずは結論からですが、(2)でシンプルで行数も少なくて一番好きです。
7
+ Usageもわずか数行で済みます。
8
+ 例えば計算式をDBに登録したいという要望があっても、バリデーションチェックにわずか1〜2行しかかかりません。
9
+
10
+ もう一つの手段は戻り値が複数欲しいという要望が含まれているので、
11
+ Node.jsでよくあるコールバック関数にしてしまうやり方もありでしょう(try~catchはなくなりますが…)
12
+
8
13
  ```JavaScript
9
- var calculation = '1+2';
10
- Calculator
11
- .eval(calculation)
12
- .then(function(it){
13
- console.log(it);
14
- })
15
- .catch(function(errors){
16
- errors.forEach(function(it){
14
+ var evalCalc = function(it, cb) {
15
+ // チェック
16
+ if (syntaxError) {
17
+ cb errors, NaN;
18
+ return;
19
+ }
20
+ // 計算
21
+ cb null, result;
22
+ }
23
+
24
+ evalCalc('1+2', function(err, result) {
25
+ if (err) {
17
- console.error(it);
26
+ console.error(err);
27
+ }
28
+ console.log(result);
29
+ });
30
+ ```
31
+
32
+ [2][3]に関しては変動を許容すると、Usageやコアのソースコードがそれだけ追加されます。
33
+ 十分なUsageやコードを書くコスト、読むコストを払うだけの機能であれば十分ありですが、
34
+ evalCalcはそれだけの規模なのか否かという話になりますが、質問文を読む限り利用者目線では無しです。
35
+
36
+ ただし、プロジェクトやチーム単位で設計や思想が異なるものなので、許容されるケースなら積極的に使った方が良いでしょう。
37
+ 例えばjQueryとか…個人がオレオレな書き方すると一貫性がなくなり極めて汚いですからね。
38
+
39
+ > Promise の可否
40
+
41
+ [MDNのPromise](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise)では下記のように定義されています。
42
+
43
+ > Promiseオブジェクトは処理の延期(deferred)と非同期処理のために使われます。Promiseはまだ完了していないが、いずれ完了する処理を表します。
44
+
45
+ evalという同期的な
46
+
47
+ ---
48
+
49
+ > [1] 関数を一つにするか複数に分けるか
50
+
51
+ 必要な数だけ分かれて欲しいです。
52
+ (2)のアプローチは現実的に最善な落とし所のように感じますし、
53
+ もし私に仕事を任せると(2)にそっくりなこんな感じのコードが納品されるでしょう。
54
+
55
+ 個人的にはSyntaxチェックをしてくれる関数は別途あって欲しいので、
56
+ Syntaxのチェック自体の処理は軽そうなので、多少冗長ですがこのようにしました。
57
+
58
+ ```JavaScript
59
+ var Calculation = {
60
+ errors_of: function(expr) {
61
+ var errors;
62
+ // 各種チェック
63
+ return errors.map(function(it){
64
+ return new SyntaxError(it);
18
65
  });
66
+ },
67
+ eval: function(expr) {
68
+ var result;
69
+ var errors = this.errors_of(expr);
70
+ if (errors.length > 0) {
71
+ throw errors[0];
72
+ }
73
+ // 計算実行
74
+ return result;
75
+ }
76
+ }
77
+
78
+ var errors, expr;
79
+
80
+ // エラー1個でいい
81
+ try {
82
+ console.log(Calculation.eval(expr));
83
+ } catch (e) {
84
+ console.error(e.message);
85
+ }
86
+
87
+ // エラー複数欲しい
88
+ errors = Calculation.errors_of(expr);
89
+ if (errors.length == 0) {
90
+ console.log(Calculation.eval(expr));
91
+ } else {
92
+ errors.forEach(function(it){
93
+ console.error(it.message);
19
94
  });
95
+ }
20
- ```
96
+ ```
97
+
98
+ > [2] 出力値を固定するか、変動するか
99
+
100
+ 今回の例は失敗時に例外を返す為に戻り値は固定されていますが、基本的に戻り値の変動は避けて欲しいです。
101
+ PHPの標準関数には成功すると数値、失敗するとfalseが返る関数がありますが、
102
+ 0はfalsyだけど成功扱いだから比較する時は`$result === false`にしてね。アホか。
103
+
104
+ (1)の例は違和感を極限まで削る事に成功していますが、JavaScriptのErrorは1個想定なので
105
+ errorsプロパティに配列が入ったオレオレExceptionになるわけですよね。
106
+ 出来ればオレオレExceptionはUsageに書きたくないし読みたくないところです…
107
+
108
+ (1)の妥協案としては、
109
+ エンジニアの一般的な感性からすればExceptionならばe.messageで文字列を取り出したいので、
110
+ messageをgetterメソッドを定義して、`this.errors.map(function(it){return it.message}).join(',')`みたいにカンマで区切って返すようにする感じですかね。
111
+
112
+ > [3] 入力値を固定するか、変動するか
113
+
114
+ PHPにin_arrayという配列から一致する要素があればtrueを返す標準関数がありますが、
115
+ デフォルトは==で比較して、第三引数にtrueを入れると===になる糞仕様です。
116
+ このように設計者と開発者の感覚がミスマッチすると、毎回最終引数に無駄なtrueを書き込むハメになりますから他の逃げ方が良いと思います。