SlideShare a Scribd company logo
Метапрограммирование
на JavaScript
Шемсединов Тимур
НИИ Системных Технологий
Что такое метапрограммирование?
• Шаблоны и макросы, используемые при
компиляции
• Программа, которая изменяет саму
себя
• Программа, генерирующая другую
программу
• еще варианты ?
Что такое метапрограммирование?
1. Это ни каким боком не искусственный интеллект.
2. Метапрограммирование это не что-то новое, вы всегда
его использовали. Нельзя начать, но можно осознать и
применять метапрограммирование осознанно.
3. Без метаданных вообще ничего не происходит в языках
программирования для фоннеймановской архитектуры
(т.е. для архитектуры, в которой данные и инструкции
хранятся в одной памяти, и нужно различать где число,
где строка, где длина строки, где адрес, где инструкция).
Что такое метапрограммирование?
Парадигма программирования,
построенная на программном изменении
структуры и поведения программ
Что такое метапрограммирование?
«Вот что я имею в виду под производящим произведением или,
как я называл его в прошлый раз, «opera operans».
В философии существует различение между «natura naturata» и
«natura naturans» – порожденная природа и порождающая
природа. По аналогии можно было бы образовать – «cultura
culturata» и «cultura culturans». Скажем, роман «В поисках
утраченного времени» строится не как произведение, а как
«cultura culturans» или «opera operans». Это и есть то, что у
греков называлось Логосом.»
// Мераб Мамардашвили «Лекции по античной философии»
Как работает метапрограммирование?
Парадигма программирования,
построенная на программном изменении
структуры и поведения программ
1. Когда происходят изменения?
2. Что именно изменяется?
3. При помощи чего происходят изменения?
Как работает метапрограммирование?
Когда происходят изменения?
• во время разработки (Design time)
• во время компиляции (Compile time)
• во время работы приложения (Run time)
• во время выполнения задачи (Just-in-Time)
• между задачами (Lazy)
• по времени (Timer)
• по внешнему вызову (Pull)
• по событию (Push)
Как работает метапрограммирование?
Что именно изменяется?
• типы данных и структуры данных
• идентификаторы (имена классов, типов, переменных)
• вызовы (имена методов, динамическое связывание)
• параметры алгоритмов
• подстановка формул, регулярных выражений и т.д.
• динамически интерпретируется сам код
• сериализация/десериализация данных
Как работает метапрограммирование?
При помощи чего происходят изменения?
• Парсинг и трансляция синтаксических структур
• Доступ к идентификаторам по имени
• Полная интроспекция
• Индивидуация объектов первого класса:
• функций, через замыкания
• объектов, через динамическое создание и примеси
Постановка задачи
Для чего нам нужно метапрограммирование?
• Расширение функциональности,
повышение универсальности ПО
• Динамические предметные области,
когда изменения являются штатным режимом
• Упрощение межсистемной интеграции,
это отдельная тема, но очень помогает
Пример 1: данные
var names = [
"Marcus Aurelius Antoninus Augustus",
"Darth Vader",
"Victor Michailovich Glushkov",
"Gottfried Wilhelm von Leibniz",
"Mao Zedong",
"Vladimir Sergeevich Soloviov",
"Ibn Arabi",
"Lev Nikolayevich Tolstoy",
"Muammar Muhammad Abu Minyar al-Gaddafi",
"Rene Descartes",
"Fyodor Mikhailovich Dostoyevsky",
"Benedito de Espinosa"
];
Пример 1: логика (без метапрограммирования)
function filter(names) {
var result = [], name;
for (var i=0; i<names.length; i++) {
name = names[i];
if ( name.length >= 10 && name.length <= 200 &&
name.indexOf("Mich") > -1 &&
name.indexOf("V") === 0 &&
name.slice(-2) == "ov" &&
!( name.length >= 50 && name.length <= 65 &&
name.indexOf("Abu") > -1 &&
name.indexOf("Lev") === 0 &&
name.slice(-3) == "iov")
) result.push(name);
}
return result;
}
Пример 1: выделяем метаданные
var conditions = {
length: [10, 200],
contains: "Mich",
starts: "V",
ends: "ov",
not: {
length: [50, 65],
contains: "Abu",
starts: "Lev",
ends: "iov"
}
};
Пример 1: строим метамодель
function filter(names, conditions) {
var operations = {
length: function(s,v) { return s.length>=v[0] && s.length<=v[1] },
contains: function(s,v) { return s.indexOf(v) > -1 },
starts: function(s,v) { return s.indexOf(v) === 0 },
ends: function(s,v) { return s.slice(-v.length) == v },
not: function(s,v) { return !check(s,v) }
};
function check(s, conditions) {
var valid = true;
for (var key in conditions)
valid &= operations[key](s, conditions[key]);
return valid;
}
return names.filter(function(s) { return check(s, conditions); });
}
Обобщенная модель модуля
Пример 2: описание задачи
var tasks = [
{ interval:5000, get:"http://127.0.0.1/api/method1.json",
expect:"OK", save:"file1.json" },
{ interval:"8s", get:"http://127.0.0.1/api/method2.json",
put:"http://127.0.0.1/api/method4.json", save:"file2.json" },
{ interval:"7s", get:"http://127.0.0.1/api/method3.json",
expect:"Done", post:"http://127.0.0.1/api/method5.json" },
{ interval:"4s", load:"file1.json",
expect:"OK", put:"http://127.0.0.1/api/method6.json" },
{ interval:"9s", load:"file2.json", save:"file1.json",
post:"http://127.0.0.1/api/method7.json" },
{ interval:"3s", load:"file1.json", save:"file3.json" },
];
Пример 2: метамодель
function iterate(tasks) {
function closureTask(task) { return function () {
console.dir(task);
var source;
if (task.get) source = request.get(task.get);
if (task.load) source = fs.createReadStream(task.load);
if (task.save) source.pipe(fs.createWriteStream(task.save));
if (task.post) source.pipe(request.post(task.post));
if (task.put) source.pipe(request.put(task.put));
} };
for (var i=0; i<tasks.length; i++)
setInterval(closureTask(tasks[i]), duration(tasks[i].interval));
}
Пример 2: метамодель (конфигурируемая метаданными)
function iterate(tasks) {
var sources = { get: request.get,
load: fs.createReadStream };
var destinations = { save: fs.createWriteStream,
post: request.post,
put: request.put };
function closureTask(task) { return function () {
console.dir(task);
var verb, source, destination;
for (key in sources)
if (task[key]) source = sources[key](task[key]);
for (key in destinations)
if (task[key]) source.pipe(destinations[key](task[key]));
} };
for (var i=0; i<tasks.length; i++)
setInterval(closureTask(tasks[i]), duration(tasks[i].interval));
}
Пример 3: интерпретация
// Parse duration to seconds, example: duration("1d 10h 7m 13s")
function duration(s) {
var result = 0;
if (typeof(s) == 'string') {
var days = s.match(/(d+)s*d/),
hours = s.match(/(d+)s*h/),
minutes = s.match(/(d+)s*m/),
seconds = s.match(/(d+)s*s/);
if (days) result += parseInt(days[1])*86400;
if (hours) result += parseInt(hours[1])*3600;
if (minutes) result += parseInt(minutes[1])*60;
if (seconds) result += parseInt(seconds[1]);
result = result*1000;
} if (typeof(s) == 'number') result = s;
return result;
}
Пример 3: интерпретация (конфигурируемая метаданными)
function duration(s) {
if (typeof(s) == 'number') return s;
var units = {
days: { rx:/(d+)s*d/, mul:86400 },
hours: { rx:/(d+)s*h/, mul:3600 },
minutes: { rx:/(d+)s*m/, mul:60 },
seconds: { rx:/(d+)s*s/, mul:1 }
};
var result = 0, unit, match;
if (typeof(s) == 'string') for (var key in units) {
unit = units[key];
match = s.match(unit.rx);
if (match) result += parseInt(match[1])*unit.mul;
}
return result*1000;
}
Пример 4: метапрограммирование и интроспекция
Пример 4: метапрограммирование и интроспекция
var ds = wcl.AjaxDataSource({
read: { get: "examples/person/read.json" },
insert: { post: "examples/person/insert.json" },
update: { post: "examples/person/update.json" },
delete: { post: "examples/person/delete.json" },
find: { post: "examples/person/find.json" },
metadata: { post: "examples/person/metadata.json" }
});
ds.read({ id:5 }, function(err, data) {
data.phone ="+0123456789";
ds.update(data, function(err) {
console.log('Data saved');
});
});
Пример 4: метапрограммирование и интроспекция
var ds = wcl.AjaxDataSource({
introspect: { post: "examples/person/introspect.json" }
});
ds.read({ id:3 }, function(err, data) {
data.phone ="+0123456789";
ds.update(data, function(err) {
console.log('Data saved');
});
});
Пример 4: метапрограммирование и интроспекция
var ds = wcl.MemoryDataSource({ data: [
{ id:1, name:"Person 1", phone:"+380501002011",
emails:[ "person1@domain.com" ], age: 25 },
{ id:2, name:"Person 2", phone:"+380501002022",
emails:[ "person2@domain.com", "person2@domain2.com" ],
address: { city: "Kiev", street:"Khreschatit", building: "26" } },
{ id:3, name:"Person 3", phone:"+380501002033",
emails:[ "person3@domain.com" ],
tags: [ {tag:"tag1", color:"red"}, {tag:"tag2", color:"green"} ] },
]});
ds.read({ id:3 }, function(err, data) {
data.phone ="+0123456789";
ds.update(data, function(err) {
console.log('Data saved');
});
});
Приемы метапрограммирования
• Стиль описания задачи: декларативный (метаданные),
использование императивных и функциональных вставок
• Хеши (ассоциативные массивы)
заранее не знаем ключ: var a = {}; a[key] = value;
• Интерпретация строк, придумываем свои синтаксисы или
берем общепринятые (json, js, regexp ...)
• Примеси (mixins): заранее не знаем куда добавим
function mixin(a) { a.fn=function(){ ... } }
• Замыкания (closures): персонализируем функции
fn = (function(a) { return function() { return a*2 } })(value)
Последствия метапрограммирования
• Размер кода: чаще резко уменьшается,
но иногда может немного увеличиваться
• Быстродействие: незначительно снижаться, но при
грамотной реализации остается примерно тем же
• Гибкость: программный код становится более
универсальным, сфера применения ПО расширяется
• Интеграция: обычно значительно упрощается и требует
меньше изменений кода
• Удовольствие от работы: метапрограммировать интереснее
поэтому удовольствия и мотивации больше
• Скорость разработки: разрабатывать дольше, а поддерживать
значительно проще, экономится уйма времени
Метапрограммирование
на JavaScript
На Github: https://github.com/tshemsedinov/metaprogramming
На Хабре: http://habrahabr.ru/post/227753/
Метапрограммирование
на JavaScript
Спасибо за внимание
Прошу задавать вопросы
Шемсединов Тимур
НИИ Системных Технологий

More Related Content

PPTX
Примеры быстрой разработки API на масштабируемом сервере приложений Impress д...
PPTX
Node.js введение в технологию, КПИ #ITmeetingKPI
PPTX
Windows Azure and node js
PPTX
HTML 5: будущее уже сегодня, Сергей Байдачный, Microsoft Ukraine
PPTX
Impress Application Server for node.js (ru)
PPTX
Bytecode
PDF
Незаурядная Java как инструмент разработки высоконагруженного сервера
PDF
Распределенные системы в Одноклассниках
Примеры быстрой разработки API на масштабируемом сервере приложений Impress д...
Node.js введение в технологию, КПИ #ITmeetingKPI
Windows Azure and node js
HTML 5: будущее уже сегодня, Сергей Байдачный, Microsoft Ukraine
Impress Application Server for node.js (ru)
Bytecode
Незаурядная Java как инструмент разработки высоконагруженного сервера
Распределенные системы в Одноклассниках

What's hot (20)

PDF
Выжимаем из сервера максимум (Андрей Паньгин)
PDF
JavaScript Базовый. Занятие 08.
PPT
Node.JS: возможности для РНР-разработчика
PDF
JavaScript Базовый. Занятие 07.
PPT
MongoDB basics in Russian
PDF
What's in a metrics? Ruby Russia 2018
PPTX
Оптимизация работы с данными в мобильных приложениях / Святослав Иванов, Артё...
PDF
Очередной скучный доклад про логгирование
PDF
JavaScript Базовый. Занятие 04.
PDF
Introduction in Node.js (in russian)
PDF
Basis.js – «под капотом»
PDF
JavaScript Базовый. Занятие 02.
PDF
Практика совместного использования Lua и C в opensource спам-фильтре Rspamd /...
PPTX
MongoDB в продакшен - миф или реальность?
PDF
Web осень 2013 лекция 3
PDF
Web осень 2013 лекция 1
PDF
Быстрое прототипирование бэкенда игры с геолокацией на OpenResty, Redis и Doc...
PPTX
MongoDB. Области применения, преимущества и узкие места, тонкости использован...
PDF
Java tricks for high-load server programming
PDF
Модульность и управляемая многопоточность встраиваемых С++ приложений - трудн...
Выжимаем из сервера максимум (Андрей Паньгин)
JavaScript Базовый. Занятие 08.
Node.JS: возможности для РНР-разработчика
JavaScript Базовый. Занятие 07.
MongoDB basics in Russian
What's in a metrics? Ruby Russia 2018
Оптимизация работы с данными в мобильных приложениях / Святослав Иванов, Артё...
Очередной скучный доклад про логгирование
JavaScript Базовый. Занятие 04.
Introduction in Node.js (in russian)
Basis.js – «под капотом»
JavaScript Базовый. Занятие 02.
Практика совместного использования Lua и C в opensource спам-фильтре Rspamd /...
MongoDB в продакшен - миф или реальность?
Web осень 2013 лекция 3
Web осень 2013 лекция 1
Быстрое прототипирование бэкенда игры с геолокацией на OpenResty, Redis и Doc...
MongoDB. Области применения, преимущества и узкие места, тонкости использован...
Java tricks for high-load server programming
Модульность и управляемая многопоточность встраиваемых С++ приложений - трудн...
Ad

Similar to Метапрограммирование с примерами на JavaScript (20)

PPTX
разработка бизнес приложений (7)
PDF
Архитектура в Agile: слабая связность
PDF
ES2015+: давно пора!
PDF
2015-12-06 Евгений Тюменцев - Разработка надежных параллельных, распределенны...
PPTX
course js day 2
PPT
18.08.2012 meta ruby
PDF
Как выглядит современный фронтенд
PDF
C# Desktop. Занятие 01.
POTX
Как жить в согласии с SOLID?
PDF
Парадигмы программирования
PDF
Node.js for enterprise 2021 - JavaScript Fwdays 3
PPTX
Декларативно функциональный стиль в PHP
PDF
Модифицируемость программных систем
PPTX
Иван Стеценко: ЯП Zephir. Панацея или лечение?
PDF
Обзор ES2015(ES6)
PPT
Подробная презентация JavaScript 6 в 1
PDF
Гатиятов Руслан, технический директор ООО “Дроид Лабс”: “Система управления п...
PDF
Теории и практики функционального программирования.
PPTX
парадигмы программирования и шаблоны проектирования
разработка бизнес приложений (7)
Архитектура в Agile: слабая связность
ES2015+: давно пора!
2015-12-06 Евгений Тюменцев - Разработка надежных параллельных, распределенны...
course js day 2
18.08.2012 meta ruby
Как выглядит современный фронтенд
C# Desktop. Занятие 01.
Как жить в согласии с SOLID?
Парадигмы программирования
Node.js for enterprise 2021 - JavaScript Fwdays 3
Декларативно функциональный стиль в PHP
Модифицируемость программных систем
Иван Стеценко: ЯП Zephir. Панацея или лечение?
Обзор ES2015(ES6)
Подробная презентация JavaScript 6 в 1
Гатиятов Руслан, технический директор ООО “Дроид Лабс”: “Система управления п...
Теории и практики функционального программирования.
парадигмы программирования и шаблоны проектирования
Ad

More from Timur Shemsedinov (20)

PDF
How to use Chat GPT in JavaScript optimizations for Node.js
PDF
IT Revolution in 2023-2024: AI, GPT, business transformation, future professi...
PDF
Multithreading in Node.js and JavaScript
PDF
Node.js threads for I/O-bound tasks
PDF
Node.js Меньше сложности, больше надежности Holy.js 2021
PDF
Rethinking low-code
PDF
Hat full of developers
PDF
FwDays 2021: Metarhia Technology Stack for Node.js
PDF
Node.js for enterprise - JS Conference
PDF
Node.js in 2021
PDF
Node.js middleware: Never again!
PDF
Patterns and antipatterns
PDF
Race-conditions-web-locks-and-shared-memory
PDF
Asynchronous programming and mutlithreading
PDF
Node.js in 2020 - part 3
PDF
Node.js in 2020 - part 2
PDF
Information system structure and architecture
PDF
Node.js in 2020 - part 1
PDF
Web Locks API
PDF
Node.js in 2020
How to use Chat GPT in JavaScript optimizations for Node.js
IT Revolution in 2023-2024: AI, GPT, business transformation, future professi...
Multithreading in Node.js and JavaScript
Node.js threads for I/O-bound tasks
Node.js Меньше сложности, больше надежности Holy.js 2021
Rethinking low-code
Hat full of developers
FwDays 2021: Metarhia Technology Stack for Node.js
Node.js for enterprise - JS Conference
Node.js in 2021
Node.js middleware: Never again!
Patterns and antipatterns
Race-conditions-web-locks-and-shared-memory
Asynchronous programming and mutlithreading
Node.js in 2020 - part 3
Node.js in 2020 - part 2
Information system structure and architecture
Node.js in 2020 - part 1
Web Locks API
Node.js in 2020

Метапрограммирование с примерами на JavaScript

  • 2. Что такое метапрограммирование? • Шаблоны и макросы, используемые при компиляции • Программа, которая изменяет саму себя • Программа, генерирующая другую программу • еще варианты ?
  • 3. Что такое метапрограммирование? 1. Это ни каким боком не искусственный интеллект. 2. Метапрограммирование это не что-то новое, вы всегда его использовали. Нельзя начать, но можно осознать и применять метапрограммирование осознанно. 3. Без метаданных вообще ничего не происходит в языках программирования для фоннеймановской архитектуры (т.е. для архитектуры, в которой данные и инструкции хранятся в одной памяти, и нужно различать где число, где строка, где длина строки, где адрес, где инструкция).
  • 4. Что такое метапрограммирование? Парадигма программирования, построенная на программном изменении структуры и поведения программ
  • 5. Что такое метапрограммирование? «Вот что я имею в виду под производящим произведением или, как я называл его в прошлый раз, «opera operans». В философии существует различение между «natura naturata» и «natura naturans» – порожденная природа и порождающая природа. По аналогии можно было бы образовать – «cultura culturata» и «cultura culturans». Скажем, роман «В поисках утраченного времени» строится не как произведение, а как «cultura culturans» или «opera operans». Это и есть то, что у греков называлось Логосом.» // Мераб Мамардашвили «Лекции по античной философии»
  • 6. Как работает метапрограммирование? Парадигма программирования, построенная на программном изменении структуры и поведения программ 1. Когда происходят изменения? 2. Что именно изменяется? 3. При помощи чего происходят изменения?
  • 7. Как работает метапрограммирование? Когда происходят изменения? • во время разработки (Design time) • во время компиляции (Compile time) • во время работы приложения (Run time) • во время выполнения задачи (Just-in-Time) • между задачами (Lazy) • по времени (Timer) • по внешнему вызову (Pull) • по событию (Push)
  • 8. Как работает метапрограммирование? Что именно изменяется? • типы данных и структуры данных • идентификаторы (имена классов, типов, переменных) • вызовы (имена методов, динамическое связывание) • параметры алгоритмов • подстановка формул, регулярных выражений и т.д. • динамически интерпретируется сам код • сериализация/десериализация данных
  • 9. Как работает метапрограммирование? При помощи чего происходят изменения? • Парсинг и трансляция синтаксических структур • Доступ к идентификаторам по имени • Полная интроспекция • Индивидуация объектов первого класса: • функций, через замыкания • объектов, через динамическое создание и примеси
  • 10. Постановка задачи Для чего нам нужно метапрограммирование? • Расширение функциональности, повышение универсальности ПО • Динамические предметные области, когда изменения являются штатным режимом • Упрощение межсистемной интеграции, это отдельная тема, но очень помогает
  • 11. Пример 1: данные var names = [ "Marcus Aurelius Antoninus Augustus", "Darth Vader", "Victor Michailovich Glushkov", "Gottfried Wilhelm von Leibniz", "Mao Zedong", "Vladimir Sergeevich Soloviov", "Ibn Arabi", "Lev Nikolayevich Tolstoy", "Muammar Muhammad Abu Minyar al-Gaddafi", "Rene Descartes", "Fyodor Mikhailovich Dostoyevsky", "Benedito de Espinosa" ];
  • 12. Пример 1: логика (без метапрограммирования) function filter(names) { var result = [], name; for (var i=0; i<names.length; i++) { name = names[i]; if ( name.length >= 10 && name.length <= 200 && name.indexOf("Mich") > -1 && name.indexOf("V") === 0 && name.slice(-2) == "ov" && !( name.length >= 50 && name.length <= 65 && name.indexOf("Abu") > -1 && name.indexOf("Lev") === 0 && name.slice(-3) == "iov") ) result.push(name); } return result; }
  • 13. Пример 1: выделяем метаданные var conditions = { length: [10, 200], contains: "Mich", starts: "V", ends: "ov", not: { length: [50, 65], contains: "Abu", starts: "Lev", ends: "iov" } };
  • 14. Пример 1: строим метамодель function filter(names, conditions) { var operations = { length: function(s,v) { return s.length>=v[0] && s.length<=v[1] }, contains: function(s,v) { return s.indexOf(v) > -1 }, starts: function(s,v) { return s.indexOf(v) === 0 }, ends: function(s,v) { return s.slice(-v.length) == v }, not: function(s,v) { return !check(s,v) } }; function check(s, conditions) { var valid = true; for (var key in conditions) valid &= operations[key](s, conditions[key]); return valid; } return names.filter(function(s) { return check(s, conditions); }); }
  • 16. Пример 2: описание задачи var tasks = [ { interval:5000, get:"http://127.0.0.1/api/method1.json", expect:"OK", save:"file1.json" }, { interval:"8s", get:"http://127.0.0.1/api/method2.json", put:"http://127.0.0.1/api/method4.json", save:"file2.json" }, { interval:"7s", get:"http://127.0.0.1/api/method3.json", expect:"Done", post:"http://127.0.0.1/api/method5.json" }, { interval:"4s", load:"file1.json", expect:"OK", put:"http://127.0.0.1/api/method6.json" }, { interval:"9s", load:"file2.json", save:"file1.json", post:"http://127.0.0.1/api/method7.json" }, { interval:"3s", load:"file1.json", save:"file3.json" }, ];
  • 17. Пример 2: метамодель function iterate(tasks) { function closureTask(task) { return function () { console.dir(task); var source; if (task.get) source = request.get(task.get); if (task.load) source = fs.createReadStream(task.load); if (task.save) source.pipe(fs.createWriteStream(task.save)); if (task.post) source.pipe(request.post(task.post)); if (task.put) source.pipe(request.put(task.put)); } }; for (var i=0; i<tasks.length; i++) setInterval(closureTask(tasks[i]), duration(tasks[i].interval)); }
  • 18. Пример 2: метамодель (конфигурируемая метаданными) function iterate(tasks) { var sources = { get: request.get, load: fs.createReadStream }; var destinations = { save: fs.createWriteStream, post: request.post, put: request.put }; function closureTask(task) { return function () { console.dir(task); var verb, source, destination; for (key in sources) if (task[key]) source = sources[key](task[key]); for (key in destinations) if (task[key]) source.pipe(destinations[key](task[key])); } }; for (var i=0; i<tasks.length; i++) setInterval(closureTask(tasks[i]), duration(tasks[i].interval)); }
  • 19. Пример 3: интерпретация // Parse duration to seconds, example: duration("1d 10h 7m 13s") function duration(s) { var result = 0; if (typeof(s) == 'string') { var days = s.match(/(d+)s*d/), hours = s.match(/(d+)s*h/), minutes = s.match(/(d+)s*m/), seconds = s.match(/(d+)s*s/); if (days) result += parseInt(days[1])*86400; if (hours) result += parseInt(hours[1])*3600; if (minutes) result += parseInt(minutes[1])*60; if (seconds) result += parseInt(seconds[1]); result = result*1000; } if (typeof(s) == 'number') result = s; return result; }
  • 20. Пример 3: интерпретация (конфигурируемая метаданными) function duration(s) { if (typeof(s) == 'number') return s; var units = { days: { rx:/(d+)s*d/, mul:86400 }, hours: { rx:/(d+)s*h/, mul:3600 }, minutes: { rx:/(d+)s*m/, mul:60 }, seconds: { rx:/(d+)s*s/, mul:1 } }; var result = 0, unit, match; if (typeof(s) == 'string') for (var key in units) { unit = units[key]; match = s.match(unit.rx); if (match) result += parseInt(match[1])*unit.mul; } return result*1000; }
  • 22. Пример 4: метапрограммирование и интроспекция var ds = wcl.AjaxDataSource({ read: { get: "examples/person/read.json" }, insert: { post: "examples/person/insert.json" }, update: { post: "examples/person/update.json" }, delete: { post: "examples/person/delete.json" }, find: { post: "examples/person/find.json" }, metadata: { post: "examples/person/metadata.json" } }); ds.read({ id:5 }, function(err, data) { data.phone ="+0123456789"; ds.update(data, function(err) { console.log('Data saved'); }); });
  • 23. Пример 4: метапрограммирование и интроспекция var ds = wcl.AjaxDataSource({ introspect: { post: "examples/person/introspect.json" } }); ds.read({ id:3 }, function(err, data) { data.phone ="+0123456789"; ds.update(data, function(err) { console.log('Data saved'); }); });
  • 24. Пример 4: метапрограммирование и интроспекция var ds = wcl.MemoryDataSource({ data: [ { id:1, name:"Person 1", phone:"+380501002011", emails:[ "person1@domain.com" ], age: 25 }, { id:2, name:"Person 2", phone:"+380501002022", emails:[ "person2@domain.com", "person2@domain2.com" ], address: { city: "Kiev", street:"Khreschatit", building: "26" } }, { id:3, name:"Person 3", phone:"+380501002033", emails:[ "person3@domain.com" ], tags: [ {tag:"tag1", color:"red"}, {tag:"tag2", color:"green"} ] }, ]}); ds.read({ id:3 }, function(err, data) { data.phone ="+0123456789"; ds.update(data, function(err) { console.log('Data saved'); }); });
  • 25. Приемы метапрограммирования • Стиль описания задачи: декларативный (метаданные), использование императивных и функциональных вставок • Хеши (ассоциативные массивы) заранее не знаем ключ: var a = {}; a[key] = value; • Интерпретация строк, придумываем свои синтаксисы или берем общепринятые (json, js, regexp ...) • Примеси (mixins): заранее не знаем куда добавим function mixin(a) { a.fn=function(){ ... } } • Замыкания (closures): персонализируем функции fn = (function(a) { return function() { return a*2 } })(value)
  • 26. Последствия метапрограммирования • Размер кода: чаще резко уменьшается, но иногда может немного увеличиваться • Быстродействие: незначительно снижаться, но при грамотной реализации остается примерно тем же • Гибкость: программный код становится более универсальным, сфера применения ПО расширяется • Интеграция: обычно значительно упрощается и требует меньше изменений кода • Удовольствие от работы: метапрограммировать интереснее поэтому удовольствия и мотивации больше • Скорость разработки: разрабатывать дольше, а поддерживать значительно проще, экономится уйма времени
  • 27. Метапрограммирование на JavaScript На Github: https://github.com/tshemsedinov/metaprogramming На Хабре: http://habrahabr.ru/post/227753/
  • 28. Метапрограммирование на JavaScript Спасибо за внимание Прошу задавать вопросы Шемсединов Тимур НИИ Системных Технологий