escript
- это просто некоторый код erlang, и no match error
происходит, когда что-то справа от знака равенства (который является оператором совпадения в erlang) не совпадает с тем, что включено левая сторона знака равенства. Вот простой пример:
1> X = 20.
20
2> 3 = X.
** exception error: no match of right hand side value 20
Поскольку 3
не соответствует значению X
, то есть 20
, вы получаете ошибку соответствия, за которой следует любое значение правой части, которое в этот случай - 20.
В вашем случае значение с правой стороны - это опубликованный вами кортеж, что, очевидно, является ошибкой, возвращаемой любым выражением, которое было справа от рассматриваемого знака равенства. Например:
3> {ok, file} = file:open("non-existent", read).
** exception error: no match of right hand side value {error,enoent}
В этом примере file:open()
возвратил кортеж, начинающийся с атома error
:
{error, enoent}
, который никогда не может соответствовать кортежу с левой стороны. знака равенства, начинающегося с атома ok
:
{ok, file}
Что-то в коде сценария, который вы запустили, создал malformed_url
.
Точный синтаксис, который вы хотите, невозможен в JavaScript. То, как исполняется JavaScript, должно измениться довольно фундаментально. Например:
var name = getUserById(id).andand().name;
// ^
// |-------------------------------
// if getUserById returns null, execution MUST stop here |
// otherwise, you'll get a "null is not an object" exception
Однако JavaScript не работает таким образом. Это просто не так.
Следующая строка выполняет почти то, что вы хотите.
var name = (var user = getUserById(id)) ? user.name : null;
Но удобочитаемость не масштабируется до более крупных примеров. Например:
// this is what you want to see
var initial = getUserById(id).andand().name.andand()[0];
// this is the best that JavaScript can do
var initial = (var name = (var user = getUserById(id)) ? user.name : null) ? name[0] : null;
И есть побочный эффект этих ненужных переменных. Я использую эти переменные, чтобы избежать двойного поиска. Переменные портят контекст, и если это очень важно, вы можете использовать анонимные функции:
var name = (function() {return (var user = getUserById(id)) ? user.name : null;})();
Теперь пользовательская переменная очищена правильно, и все счастливы. Но вау! как много печатать! :)
Вы хотите dojo .behavior .
dojo.behavior.add({
'#cool_input': {
onKeyUp: function(evt) { ... }
}
});
Я не знаю Dojo, но не был должен Ваше первое чтение в качестве примера
dojo.addOnLoad(function() {
var coolInput = dojo.byId('cool_input');
if(coolInput)
coolInput.onkeyup = function() { ... };
});
Иначе Вы могли бы закончить тем, что пытались получить доступ к элементу, прежде чем DOM был создан.
Назад к Вашему вопросу: В JavaScript я реализовал бы andand()
как
function andand(obj, func, args) {
return obj && func.apply(obj, args || []);
}
Ваш пример мог затем быть записан как
dojo.addOnLoad(function() {
andand(dojo.byId('cool_input'), function() {
this.onkeyup = function() { ... };
});
});
который не является действительно что намного короче, чем использование явного if
оператор - итак, почему беспокойство?
Я никогда не использовал додзе, но большинство платформ JavaScript (при контакте с DOM) возвращает элемент вызова, когда метод называют от объекта элемента (плохая формулировка, извините). Так andand () было бы неявно.
dojo.addOnLoad(function() {
dojo.byId('cool_input').onkeyup(function(evt) { /*event handler code*/
});
});
Как насчет чего-то вроде этого:
function andand(elt, f) {
if (elt)
return f(elt);
return null;
}
Звоните как это:
andand(dojo.byId('cool_input'), function(elt) {
// this function gets called with elt = the input iff it exists
dojo.addOnLoad(function() {
elt.onkeyup = function() { ... };
});
});
Насколько я знаю, что нет встроенной функции JavaScript, которая имеет ту же самую функциональность. Я думаю лучшее решение, хотя должен запросить классом вместо идентификатора и использовать dojo.forEach (...), поскольку Вам гарантируют непустой элемент в forEach закрытии.
Вы могли всегда использовать эквивалентный JavaScript:
dojo.byId('cool_input') && dojo.byId('cool_input').whateverYouWantToDo(...);
Для списка:
Array.prototype.andand = function(property, fn) {
if (this.filter(property).length > 0) this.map(fn);
}