回答編集履歴

2

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

2016/11/14 04:55

投稿

miyabi-sun
miyabi-sun

スコア21158

test CHANGED
@@ -16,14 +16,200 @@
16
16
 
17
17
 
18
18
 
19
+ (4)までやるのは反対です。
20
+
19
- もう一つ手段値が複数欲しという要望含まているの
21
+ 問題解決の仕方シンプルで分かやすもの1つあば十分す。
22
+
23
+
24
+
20
-
25
+ [2][3]に関しては変動を許容すると、Usageやコアのソースコードがそれだけ追加されます。
26
+
27
+ 十分なUsageやコードを書くコスト、読むコストを払うだけの機能であれば十分ありでしょう。
28
+
21
- Node.jsでよくあるコールバック関数にしてしまうやり方もありでしょう(try~catchはななりますが…)
29
+ evalCalcはそれだけの規模のかという話になりますが、質問文を読む限り利用者目線では無しです。
30
+
31
+
32
+
33
+ ただし、プロジェクトやチーム単位で設計や思想が異なるものなので、許容されるケースなら積極的に使った方が良いでしょう。
34
+
35
+ 例えばjQueryとか…個人がオレオレな書き方すると一貫性がなくなり極めて汚いですからね。
36
+
37
+
38
+
39
+ > [1] 関数を一つにするか複数に分けるか
40
+
41
+
42
+
43
+ 必要な数だけ分かれて欲しいです。
44
+
45
+ (2)のアプローチは現実的に最善な落とし所のように感じますし、
46
+
47
+ もし私に仕事を任せると(2)にそっくりなこんな感じのコードが納品されるでしょう。
48
+
49
+
50
+
51
+ 個人的にはSyntaxチェックをしてくれる関数は別途あって欲しいので、
52
+
53
+ Syntaxのチェック自体の処理は軽そうなので、多少冗長ですがこのようにしました。
22
54
 
23
55
 
24
56
 
25
57
  ```JavaScript
26
58
 
59
+ var Calculation = {
60
+
61
+ errors_of: function(expr) {
62
+
63
+ var errors;
64
+
65
+ // 各種チェック
66
+
67
+ return errors.map(function(it){
68
+
69
+ return new SyntaxError(it);
70
+
71
+ });
72
+
73
+ },
74
+
75
+ eval: function(expr) {
76
+
77
+ var result;
78
+
79
+ var errors = this.errors_of(expr);
80
+
81
+ if (errors.length > 0) {
82
+
83
+ throw errors[0];
84
+
85
+ }
86
+
87
+ // 計算実行
88
+
89
+ return result;
90
+
91
+ }
92
+
93
+ }
94
+
95
+
96
+
97
+ var errors, expr;
98
+
99
+
100
+
101
+ // エラー1個でいい
102
+
103
+ try {
104
+
105
+ console.log(Calculation.eval(expr));
106
+
107
+ } catch (e) {
108
+
109
+ console.error(e.message);
110
+
111
+ }
112
+
113
+
114
+
115
+ // エラー複数欲しい
116
+
117
+ errors = Calculation.errors_of(expr);
118
+
119
+ if (errors.length == 0) {
120
+
121
+ console.log(Calculation.eval(expr));
122
+
123
+ } else {
124
+
125
+ errors.forEach(function(it){
126
+
127
+ console.error(it.message);
128
+
129
+ });
130
+
131
+ }
132
+
133
+ ```
134
+
135
+
136
+
137
+ > [2] 出力値を固定するか、変動するか
138
+
139
+
140
+
141
+ 今回の例は失敗時に例外を返す為に戻り値は固定されていますが、基本的に戻り値の変動は避けて欲しいです。
142
+
143
+ PHPの標準関数には成功すると数値、失敗するとfalseが返る関数がありますが、
144
+
145
+ 0はfalsyだけど成功扱いだから比較する時は`$result === false`にしてね。アホか。
146
+
147
+
148
+
149
+ (1)の例は違和感を極限まで削る事に成功していますが、JavaScriptのErrorは1個想定なので
150
+
151
+ errorsプロパティに配列が入ったオレオレExceptionになるわけですよね。
152
+
153
+ 出来ればオレオレExceptionはUsageに書きたくないし読みたくないところです…
154
+
155
+
156
+
157
+ (1)の妥協案としては、
158
+
159
+ エンジニアの一般的な感性からすればExceptionならばe.messageで文字列を取り出したいので、
160
+
161
+ messageをgetterメソッドを定義して、`this.errors.map(function(it){return it.message}).join(',')`みたいにカンマで区切って返すようにする感じですかね。
162
+
163
+
164
+
165
+ > [3] 入力値を固定するか、変動するか
166
+
167
+
168
+
169
+ PHPにin_arrayという配列から一致する要素があればtrueを返す標準関数がありますが、
170
+
171
+ デフォルトは==で比較して、第三引数にtrueを入れると===になる糞仕様です。
172
+
173
+ このように設計者と開発者の感覚がミスマッチすると、毎回最終引数に無駄なtrueを書き込むハメになりますから他の逃げ方が良いと思います。
174
+
175
+
176
+
177
+ ---
178
+
179
+
180
+
181
+ > Promise の可否
182
+
183
+
184
+
185
+ [MDNのPromise](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise)では下記のように定義されています。
186
+
187
+
188
+
189
+ > Promiseオブジェクトは処理の延期(deferred)と非同期処理のために使われます。Promiseはまだ完了していないが、いずれ完了する処理を表します。
190
+
191
+
192
+
193
+ evalという同期的な処理の為にPromiseを使うのは流石に冗長過ぎるかなぁ…と感じます。
194
+
195
+
196
+
197
+ ---
198
+
199
+
200
+
201
+ 「別解」
202
+
203
+
204
+
205
+ 戻り値が複数欲しいというのが根本の質問だと思いますので、
206
+
207
+ Node.jsでよくあるコールバック関数にしてしまうやり方も非推奨ながら手段の一つではあります。
208
+
209
+
210
+
211
+ ```JavaScript
212
+
27
213
  var evalCalc = function(it, cb) {
28
214
 
29
215
  // チェック
@@ -57,177 +243,3 @@
57
243
  });
58
244
 
59
245
  ```
60
-
61
-
62
-
63
- [2][3]に関しては変動を許容すると、Usageやコアのソースコードがそれだけ追加されます。
64
-
65
- 十分なUsageやコードを書くコスト、読むコストを払うだけの機能であれば十分ありですが、
66
-
67
- evalCalcはそれだけの規模なのか否かという話になりますが、質問文を読む限り利用者目線では無しです。
68
-
69
-
70
-
71
- ただし、プロジェクトやチーム単位で設計や思想が異なるものなので、許容されるケースなら積極的に使った方が良いでしょう。
72
-
73
- 例えばjQueryとか…個人がオレオレな書き方すると一貫性がなくなり極めて汚いですからね。
74
-
75
-
76
-
77
- > Promise の可否
78
-
79
-
80
-
81
- [MDNのPromise](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise)では下記のように定義されています。
82
-
83
-
84
-
85
- > Promiseオブジェクトは処理の延期(deferred)と非同期処理のために使われます。Promiseはまだ完了していないが、いずれ完了する処理を表します。
86
-
87
-
88
-
89
- evalという同期的な
90
-
91
-
92
-
93
- ---
94
-
95
-
96
-
97
- > [1] 関数を一つにするか複数に分けるか
98
-
99
-
100
-
101
- 必要な数だけ分かれて欲しいです。
102
-
103
- (2)のアプローチは現実的に最善な落とし所のように感じますし、
104
-
105
- もし私に仕事を任せると(2)にそっくりなこんな感じのコードが納品されるでしょう。
106
-
107
-
108
-
109
- 個人的にはSyntaxチェックをしてくれる関数は別途あって欲しいので、
110
-
111
- Syntaxのチェック自体の処理は軽そうなので、多少冗長ですがこのようにしました。
112
-
113
-
114
-
115
- ```JavaScript
116
-
117
- var Calculation = {
118
-
119
- errors_of: function(expr) {
120
-
121
- var errors;
122
-
123
- // 各種チェック
124
-
125
- return errors.map(function(it){
126
-
127
- return new SyntaxError(it);
128
-
129
- });
130
-
131
- },
132
-
133
- eval: function(expr) {
134
-
135
- var result;
136
-
137
- var errors = this.errors_of(expr);
138
-
139
- if (errors.length > 0) {
140
-
141
- throw errors[0];
142
-
143
- }
144
-
145
- // 計算実行
146
-
147
- return result;
148
-
149
- }
150
-
151
- }
152
-
153
-
154
-
155
- var errors, expr;
156
-
157
-
158
-
159
- // エラー1個でいい
160
-
161
- try {
162
-
163
- console.log(Calculation.eval(expr));
164
-
165
- } catch (e) {
166
-
167
- console.error(e.message);
168
-
169
- }
170
-
171
-
172
-
173
- // エラー複数欲しい
174
-
175
- errors = Calculation.errors_of(expr);
176
-
177
- if (errors.length == 0) {
178
-
179
- console.log(Calculation.eval(expr));
180
-
181
- } else {
182
-
183
- errors.forEach(function(it){
184
-
185
- console.error(it.message);
186
-
187
- });
188
-
189
- }
190
-
191
- ```
192
-
193
-
194
-
195
- > [2] 出力値を固定するか、変動するか
196
-
197
-
198
-
199
- 今回の例は失敗時に例外を返す為に戻り値は固定されていますが、基本的に戻り値の変動は避けて欲しいです。
200
-
201
- PHPの標準関数には成功すると数値、失敗するとfalseが返る関数がありますが、
202
-
203
- 0はfalsyだけど成功扱いだから比較する時は`$result === false`にしてね。アホか。
204
-
205
-
206
-
207
- (1)の例は違和感を極限まで削る事に成功していますが、JavaScriptのErrorは1個想定なので
208
-
209
- errorsプロパティに配列が入ったオレオレExceptionになるわけですよね。
210
-
211
- 出来ればオレオレExceptionはUsageに書きたくないし読みたくないところです…
212
-
213
-
214
-
215
- (1)の妥協案としては、
216
-
217
- エンジニアの一般的な感性からすればExceptionならばe.messageで文字列を取り出したいので、
218
-
219
- messageをgetterメソッドを定義して、`this.errors.map(function(it){return it.message}).join(',')`みたいにカンマで区切って返すようにする感じですかね。
220
-
221
-
222
-
223
- > [3] 入力値を固定するか、変動するか
224
-
225
-
226
-
227
- PHPにin_arrayという配列から一致する要素があればtrueを返す標準関数がありますが、
228
-
229
- デフォルトは==で比較して、第三引数にtrueを入れると===になる糞仕様です。
230
-
231
- このように設計者と開発者の感覚がミスマッチすると、毎回最終引数に無駄なtrueを書き込むハメになりますから他の逃げ方が良いと思います。
232
-
233
-

1

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

2016/11/14 04:55

投稿

miyabi-sun
miyabi-sun

スコア21158

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