Monthly Archives: Липень 2013

Must have для сучасних IDE та редакторів

LightTable LogoНаразі у мене є два улюблених редактори для коду: Sublime Text та LightTablevim, хоч любові до гробу не склалося, оскільки я в чистій консолі не так часто працюю, але він теж гарний). Про перший зараз мабуть не знає лише лінивий. У нього багато всяких крутих можливостей для редагування, плюс він дуже круто розширюється завдяки масі доступних плагінів. Але! Все те, що зараз пропонує Саблайм — це необхідний мінімум, без якого я вже не уявляю комфортної роботи, тому на цьому питанні я зупинятись не буду. Набагато цікавіше жити днем завтрашнім і оцінити куди надалі розвиваються редактори. А для того, аби оцінити це, прошу переглянути відео “Inventing on a Principle” (“Винаходячи за принципом”). Його, я впевнений, багато хто вже бачив, тому перепрошую за повторення, можете одразу читати далі. Хто не бачив — обов’язково подивіться. Причому тут його показано не лише для програмування, а й інших сфер як-то радіоелектроніка, обробка відео, тощо. Дуже цікава штука, насолоджуйтесь (до речі, у кого проблеми з англійською — там є російські субтитри):

LightTable concept screenshot Але то все концепт… Гарна ідея, але (мабуть) не тривіальна в реалізації, і невідомо коли ми вже зможемо використати щось подібне в реальній роботі. Чи відомо? Насправді розробники вже можуть помацати перші реалізації цієї ідеї за допомогою LightTable. LightTable наразі єдина робоча реалізація про яку я знаю, тому якщо існують інші — скажіть, я хочу спробувати 😉 Про цей редактор я дізнався суто випадково, коли копав більше інформації про Clojure (власне LT написаний на Clojure і це була перша мова яку він підтримував). Звісно, там все не настільки аж неймовірно як у відео вище, але все ж JavaScript’овий приклад, який зробили з виходом версії 0.4 уже вражає:

Згодом з’явилась ціла серія відео про використання ClojureScript в LightTable в аналогічному стилі. Перше відео тут, далі по списку в Related на Ютюбі.

Звісно, в реальному житті все не настільки райдужно: в LightTable поки нема багатьох можливостей, до яких я вже звик в Sublime Text, тому у більшості випадків я не можу повністю перейти на нього. Плюс справжня real-time розробка наразі є лише для JavaScript, ClojureScript та, в принципі, Clojure. Для останньої та для Python є підтримка трохи простішої, але теж корисної фічі inline evaluation: це REPL прямо у вікні редактора — кльова фіча, я постійно нею користуюсь. Хоча насправді подібна штука не нова і є навіть в Visual Studio 2010 — це інтерактивна консоль для F# (можна подивитись приклад роботи тут).

Must have для сучасних IDE та редакторів

LightTable LogoНаразі у мене є два улюблених редактори для коду: Sublime Text та LightTablevim, хоч любові до гробу не склалося, оскільки я в чистій консолі не так часто працюю, але він теж гарний). Про перший зараз мабуть не знає лише лінивий. У нього багато всяких крутих можливостей для редагування, плюс він дуже круто розширюється завдяки масі доступних плагінів. Але! Все те, що зараз пропонує Саблайм — це необхідний мінімум, без якого я вже не уявляю комфортної роботи, тому на цьому питанні я зупинятись не буду. Набагато цікавіше жити днем завтрашнім і оцінити куди надалі розвиваються редактори. А для того, аби оцінити це, прошу переглянути відео “Inventing on a Principle” (“Винаходячи за принципом”). Його, я впевнений, багато хто вже бачив, тому перепрошую за повторення, можете одразу читати далі. Хто не бачив — обов’язково подивіться. Причому тут його показано не лише для програмування, а й інших сфер як-то радіоелектроніка, обробка відео, тощо. Дуже цікава штука, насолоджуйтесь (до речі, у кого проблеми з англійською — там є російські субтитри):



LightTable concept screenshot Але то все концепт… Гарна ідея, але (мабуть) не тривіальна в реалізації, і невідомо коли ми вже зможемо використати щось подібне в реальній роботі. Чи відомо? Насправді розробники вже можуть помацати перші реалізації цієї ідеї за допомогою LightTable. LightTable наразі єдина робоча реалізація про яку я знаю, тому якщо існують інші — скажіть, я хочу спробувати ;) Про цей редактор я дізнався суто випадково, коли копав більше інформації про Clojure (власне LT написаний на Clojure і це була перша мова яку він підтримував). Звісно, там все не настільки аж неймовірно як у відео вище, але все ж JavaScript’овий приклад, який зробили з виходом версії 0.4 уже вражає:

Згодом з’явилась ціла серія відео про використання ClojureScript в LightTable в аналогічному стилі. Перше відео тут, далі по списку в Related на Ютюбі.

Звісно, в реальному житті все не настільки райдужно: в LightTable поки нема багатьох можливостей, до яких я вже звик в Sublime Text, тому у більшості випадків я не можу повністю перейти на нього. Плюс справжня real-time розробка наразі є лише для JavaScript, ClojureScript та, в принципі, Clojure. Для останньої та для Python є підтримка трохи простішої, але теж корисної фічі inline evaluation: це REPL прямо у вікні редактора — кльова фіча, я постійно нею користуюсь. Хоча насправді подібна штука не нова і є навіть в Visual Studio 2010 — це інтерактивна консоль для F# (можна подивитись приклад роботи тут).

“Складні речі – доступно, прості – робляться самі”

Якщо перефразувати девіз мови Perl “Зробити прості речі простими, а складні можливими” для LISP, то вийде “Зробити складні речі доступними, а прості робляться самі”
– Всеволод Дьомкін, Grammarly. З презентації на HotCode 2013

Clojure Logo

У мене тут в чорновиках стільки записів — треба їх потроху публікувати. Але вони всі вже здоровезні, і я все не можу їх довести до ладу, тому я подумав, що варто робити з них менші і таки виводити в світ. Сьогодні я вирішив написати першу замітку про Clojure. Це, мабуть, наразі самий новий, але вже дуже популярний діалект LISP, що працює поверх JVM. Перші спроби наковбасити щось на Clojure у мене сталися ще кілька місяців тому, коли я написав простенький конвертор тест-кейсів з Testlink в TFS, але то було зроблено на колінці і окрім того, що я його написав дуже швидко, там пишатись особливо нема чим: це моя перша програмка на чомусь LISP-подібному не рахуючи простеньких завдань в універі, тому код страшненький, без всяких крутих ліспових фішечок типу макросів, з багами, але працює 🙂

Про Clojure я дізнався суто випадково на конференції Javascript Framework Days навесні цього року з презентації Олександра Соловйова про ClojureScript (це така підмножина мови, що транслюється в JavaScript, типу як CoffeeScript). До речі, рекомендую подивитись саму презенташку про FRP та ClojureScript – вона весела, динамічна, а мені не потрібно буде розповідати про те, що являють собою LISPоподібні мови і Clojure в тому числі.

А ось нижче приклад простенької задачки яку буквально на днях мну вирішив для себе. Суть полягає в тому, щоб розпарсити старий допотопний HTML на сайтах філармонії, театру Франка, органного залу та інших подібних закладів у iCalendar формат, аби їх можна було б собі підключити собі в Outlook чи Google Calendar. Парсити доводиться звичайний html, бо жоден з цих сайтів та агрегаторів не додумався зробити цього сам, або хоча б видавати афішу в rss-форматі (якщо хтось знає де є такі — скажіть). Вгадайте скільки рядків займає подібна програмка навіть на Python з будь-якими лібами 😉

Готовий закластися, що навіть на Python буде більше ніж це:

(ns eventic.core
  (:require [net.cgrand.enlive-html :as html]
            [clj-time.format :as time]
            [clj-ical.format])
  (:import java.net.URL java.nio.charset.Charset)) 
  
; хелпер для завантаження сторінки (штатний рідер enlive не шарить кодувань)
(defn fetch-page [url]
  (-> url java.net.URL. .getContent (java.io.InputStreamReader. "WINDOWS-1251") html/html-resource))
  
; закачуємо сторінку
(def p
  (fetch-page "http://www.filarmonia.com.ua/ua.afisha"))
  
; хелпер для конвертації дат виду "30.07.2013" в datetime
(defn to-date [date]
  (time/parse (time/formatter "dd.MM.yyyy") date))
  
; переводимо усі теги <br> в n, а всі інші теги прибираємо зберігаючи текст
(defn extractor [content]
  (map #(apply str (-> % (html/at [:br] (html/content "n") [:*] html/unwrap))) content)) 

; вибираємо дати і конвертуємо в date-time формат
(def dates
  (map #(-> % :content first to-date)
        (html/select p [:table :tr :td :p :span])))
    
; вибираємо заголовки
(def titles
  (map #(-> % :content first str)
        (html/select p [:table :tr :td :h2])))

; вибираємо описи одразу переводячи їх в plain text
(def descriptions 
  (rest (extractor
    (html/select p [:table :tr :td [:p (html/attr? :align)]]))))

; робимо структуру наповнення для iCalendar
(def ical
  (map #(vec (zipmap [:dtstart :summary :description] %))
        (map vector dates titles descriptions)))

; записуємо в файл
(spit "filarmony.ics"
  (->> (clj-ical.format/write-object
         (apply conj [:vcalendar] (map #(apply conj [:vevent] %) ical)))
       with-out-str))

І все. На виході отримуємо готовий файл у iCalendar форматі з усім необхідним. Можливо з першого погляду здаватиметься, що це якась тарабарщина, але насправді Clojure вчиться дуже швидко. Достатньо пари годин на день і вже за 3-4 дні можна писати маленькі корисні штуки для себе (я раніше постійно використовував Python для цього, але тепер в мене з’явилася нова робоча конячка 🙂 ). І суть навіть не в тому, що цей код компактний сам по собі. Суть в тому, що Clojure має такі засоби, що дозволяють створювати бібліотеки на кшталт Enlive, які надзвичайно потужні і прості в користуванні одночасно, а відповідно код що їх використовує стає простішим і його легше підтримувати.

А тим часом я думаю як це все оформити в простенький сервіс, який можна буде розгорнути на Google App Engine — все ж Clojure на JVM працює. Я вже надивився прикладів і презентацій на “Hackers with Attitude”, тож хочу тепер сам спробувати (і згодом описати це).

P.S. Ну і хто досі не читав “Перемогти посередність” Пола Грема, дуже рекомендую 😉

“Складні речі – доступно, прості – робляться самі”

Якщо перефразувати девіз мови Perl
“Зробити прості речі простими, а складні можливими” для LISP,
то вийде “Зробити складні речі доступними, а прості робляться самі”

— Всеволод Дьомкін, Grammarly.
З презентації на HotCode 2013

Clojure Logo

У мене тут в чорновиках стільки записів — треба їх потроху публікувати. Але вони всі вже здоровезні, і я все не можу їх довести до ладу, тому я подумав, що варто робити з них менші і таки виводити в світ. Сьогодні я вирішив написати першу замітку про Clojure. Це, мабуть, наразі самий новий, але вже дуже популярний діалект LISP, що працює поверх JVM. Перші спроби наковбасити щось на Clojure у мене сталися ще кілька місяців тому, коли я написав простенький конвертор тест-кейсів з Testlink в TFS, але то було зроблено на колінці і окрім того, що я його написав дуже швидко, там пишатись особливо нема чим: це моя перша програмка на чомусь LISP-подібному не рахуючи простеньких завдань в універі, тому код страшненький, без всяких крутих ліспових фішечок типу макросів, з багами, але працює :)

Про Clojure я дізнався суто випадково на конференції Javascript Framework Days навесні цього року з презентації Олександра Соловйова про ClojureScript (це така підмножина мови, що транслюється в JavaScript, типу як CoffeeScript). До речі, рекомендую подивитись саму презенташку про FRP та ClojureScript – вона весела, динамічна, а мені не потрібно буде розповідати про те, що являють собою LISPоподібні мови і Clojure в тому числі.

А ось нижче приклад простенької задачки яку буквально на днях мну вирішив для себе. Суть полягає в тому, щоб розпарсити старий допотопний HTML на сайтах філармонії, театру Франка, органного залу та інших подібних закладів у iCalendar формат, аби їх можна було б собі підключити собі в Outlook чи Google Calendar. Парсити доводиться звичайний html, бо жоден з цих сайтів та агрегаторів не додумався зробити цього сам, або хоча б видавати афішу в rss-форматі (якщо хтось знає де є такі — скажіть). Вгадайте скільки рядків займає подібна програмка навіть на Python з будь-якими лібами ;)

Готовий закластися, що навіть на Python буде більше ніж це:

(ns eventic.core
  (:require [net.cgrand.enlive-html :as html]
            [clj-time.format        :as time]
            [clj-ical.format])
  (:import java.net.URL
           java.nio.charset.Charset))

; хелпер для завантаження сторінки (штатний рідер enlive не шарить кодувань)
(defn fetch-page [url]
  (-> url java.net.URL.
    .getContent (java.io.InputStreamReader. "WINDOWS-1251") html/html-resource))

; закачуємо сторінку
(def p (fetch-page "http://www.filarmonia.com.ua/ua.afisha"))

; хелпер для конвертації дат виду "30.07.2013" в datetime
(defn to-date [date]
  (time/parse (time/formatter "dd.MM.yyyy") date))

; переводимо усі теги <br> в \n, а всі інші теги прибираємо зберігаючи текст
(defn extractor [content]
  (map #(apply str
    (-> %  (html/at [:br] (html/content "\\n") [:*] html/unwrap))) content))

; вибираємо дати і конвертуємо в date-time формат
(def dates
  (map #(-> % :content first to-date) (html/select p [:table :tr :td :p :span])))
; вибираємо заголовки
(def titles
  (map #(-> % :content first str) (html/select p [:table :tr :td :h2])))
; вибираємо описи одразу переводячи їх в plain text
(def descriptions
  (rest (extractor (html/select p [:table :tr :td [:p (html/attr? :align)]]))))

; робимо структуру наповнення для iCalendar
(def ical
  (map #(vec (zipmap [:dtstart :summary :description] %))
    (map vector dates titles descriptions)))

; записуємо в файл
(spit "filarmony.ics"
  (->> (clj-ical.format/write-object
    (apply conj [:vcalendar] (map #(apply conj [:vevent] %) ical))) with-out-str))

І все. На виході отримуємо готовий файл у iCalendar форматі з усім необхідним. Можливо з першого погляду здаватиметься, що це якась тарабарщина, але насправді Clojure вчиться дуже швидко. Достатньо пари годин на день і вже за 3-4 дні можна писати маленькі корисні штуки для себе (я раніше постійно використовував Python для цього, але тепер в мене з’явилася нова робоча конячка :) ). І суть навіть не в тому, що цей код компактний сам по собі. Суть в тому, що Clojure має такі засоби, що дозволяють створювати бібліотеки на кшталт Enlive, які надзвичайно потужні і прості в користуванні одночасно, а відповідно код що їх використовує стає простішим і його легше підтримувати.

А тим часом я думаю як це все оформити в простенький сервіс, який можна буде розгорнути на Google App Engine — все ж Clojure на JVM працює. Я вже надивився прикладів і презентацій на “Hackers with Attitude”, тож хочу тепер сам спробувати (і згодом описати це).

P.S. Ну і хто досі не читав “Перемогти посередність” Пола Грема, дуже рекомендую ;)

Коли здається що щось не так – RTFM!

Вчора знайшов помилку в веб-сервері Nginx. Мені на Google+ підказали, що насправді я неправильно прочитав документацію, тому що “з версії 0.6.7 шлях до файлу є відносним директорії з файлом конфігурації nginx.conf, а не відносним префіксній директорії.” Хоча звісно незрозуміло чому такий виняток, бо в документації про префіксну директорію, написано що вона “used for all relative paths set by configure (except for paths to libraries sources) and in the nginx.conf configuration file. It is set to the /usr/local/nginx directory by default.” Про такий виняток не написано. Але все одно помилився тут таки я.

Сьогодні знову помилився:

os.path.join('a', 'b', '/c/d.jpg')
# out: '/c/d.jpg'
# WTF? 
os.path.join('a', 'b', 'c/d.jpg')
# out: 'a/b/c/d.jpg'

До того думав що join просто викидає всі зайві слеші, а потім додає якщо бракує. А виявилось, що якщо будь-який з аргументів – абсолютний шлях, всі попередні компоненти (на Windows, включаючи всі попередні мітки дисків, якщо такі були) викидаються, і з’єднання продовжується.

І ні, замість того аби зразу прочитати документацію, я ще спробував чи не треба додати слеша в один з двох перших аргументів.


Filed under: Кодерство, Нещоденник Tagged: nginx, Python

Журнал роботи в Google Sheets та розширення його функцій з JavaScript

Коли я два тижні тому на роботі признався начальнику що вже все зробив, мій начальник вирішив поділитись мною з іншим начальником. Тепер я не можу все зробити, тому що один начальник проводить по дві наради на день на якій мене питають що я зробив, а інший начальник проводить одну нараду на день, на якій теж питають що я зробив. Крім того треба щодня писати звіти, по кожному проекту окремо, бо це впливає на бюджет проектів і на мою зарплатню. І щоб мені було легше пояснити одному начальнику що я сидів на нараді в іншого, та навпаки, я вирішив записувати що роблю протягом дня. Ну звісно виявилось що не багато роблю, але ви коли-небудь пробували записувати що робите? Якщо більше ніж 5 годин корисної роботи на добу – ви мій герой, навчіть мене.

Власне спочатку я хотів завести табличку по методології Pomodoro. Але, виявилось що Pomodoro – це занадто складно коли тебе три наради на день, якщо не рахувати переписок зі співробітниками в Skype. Тому я вирішив просто записувати час початку виконання і час закінчення.

В Google Sheets є дві корисні комбінації клавіш:

  1. Ctrl + ; – вставляє в клітинку дату
  2. Ctrl + Shift + ; – вставляє в клітинку час. В мене чомусь в форматі AM/PM.

Цього було б досить, але рахувати тривалість задач доводиться вручну. Незручно. Якщо є табличка:

A B C D
1 Time started Task Time finished Duration
2 1:32 PM Project A daily stand-up 1:51 PM 0:19

Хочеться щоб колонка D заповнювалась формулою. Але якщо написати в D2 =C2 - A2, воно видасть: “#VALUE!” – Помилка: не число: 1:51 PM. Тому треба використати функції.

Десь я чув фразочку що електронні таблиці – це функціональна мова програмування. Ах. :) Функцій там купа. Клітинок аби зберігати результати їх роботи – теж досить. Але вчити всі ті функції – ну їх.

На щастя Google Docs можна скриптувати за допомогою JavaScript! Ну й правда, не Visual Basic-ом ж користуватись у браузерному застосунку.

Як ми це робимо? Натискаємо “Інструменти” -> “Редактор сценаріїв”. Відкриється онлайновий редактор коду. Вставляємо туди щось таке:

// (c) Salman A     http://stackoverflow.com/a/1788084/816449
function date_diff(date1, date2) {
  if (date2 < date1) {
    date2.setDate(date2.getDate() + 1);
  }
  return date2 - date1;
}

function fmtmsec(msec) {
  var hh = Math.floor(msec / 1000 / 60 / 60);
  msec -= hh * 1000 * 60 * 60;
  var mm = Math.floor(msec / 1000 / 60);
  msec -= mm * 1000 * 60;
  return hh + ':' + mm;
}

function parsetime(cell) {
    var part = cell.match(/(\d+):(\d+)(?: )?(am|pm)?/i);
    var hh = parseInt(part[1], 10);
    var mm = parseInt(part[2], 10);
    var ap = part[3] ? part[3].toUpperCase() : null;
    if (ap === "AM") {
        if (hh == 12) {
            hh = 0;
        }
    }
    if (ap === "PM") {
        if (hh != 12) {
            hh += 12;
        }
    }
    return new Date(2000, 0, 1, hh, mm, 0);
}

function time_diff(arg1, arg2) {
  try {
    arg1 = parsetime(arg1);
    arg2 = parsetime(arg2);
  } catch (e) {
    return '';
  };
  return fmtmsec(date_diff(arg1, arg2));
};

function test() {
  Logger.log(time_diff('9:12 PM', '10:30 PM'));
}

Даємо модулю назву, на зразок Time diff, зберігаємо. В нашій табличці відкриваємо “Інструменти” -> “Менеджер сценаріїв” та переконуємось що наш сценарій там видно.

Тепер, в клітинці D2 можна писати =time_diff(A2;C2). І не поставте кому між аргументами. Буде синтаксична помилка яку я довго шукав в JavaScript, в той час як виявилось що проблема була в записі формули. І це ніби все.

Так просто що мені аж сподобалось.


Filed under: Інструменти, Кодерство, Павутина Tagged: Лайфхаки, JavaScript, робота

Гроші ніби є, а користуватись ними в мене не виходить

KredoDirect – система набагато краща за iBank 2 UA (як корабель назвеш, так й попливеш), бо не треба ставити ніяку Java від Oracle, а можна зразу зайти й користуватись. Біфіт я ненавиджу щирою ненавистю і добре що в Авалі в мене вже закінчились гроші. Залишилось тепер лише закрити карточку.

Біда з KredoDirect в тому, що я коли створював для нього новий пароль, неправильно ввів майстер пароль. Вчора з другої спроби знову ввів його неправильно і залогінився, але так і не встиг заплатити пенсійному фонду, тому що система розлогінює вас при будь-якому натисненні кнопки “назад”. Подумав – висплюсь, зранку заплачу.

Зранку мало не заплакав. Бо не можу згадати як саме я неправильно написав майстер-пароль. Пам’ятаю лише що пароль який виходить в результаті починається з літери z. Тоді я вирішив взяти алгоритм перебору одруківок від Пітера Норвіга, і перебрати можливі помилки в майстер паролі аби подивитись які з них дають мені пароль схожий на мій. Написав таку програму:

from getpass import getpass

from oplop import create

alphabet = 'abcdefghijklmnopqrstuvwxyz,/.][\';`1234567890-=\\'

def edits1(word):
    splits     = [(word[:i], word[i:]) for i in range(len(word) + 1)]
    deletes    = [a + b[1:] for a, b in splits if b]
    transposes = [a + b[1] + b[0] + b[2:] for a, b in splits if len(b)>1]
    replaces   = [a + c + b[1:] for a, b in splits for c in alphabet if b]
    inserts    = [a + c + b     for a, b in splits for c in alphabet]
    return set(deletes + transposes + replaces + inserts)

n = 0
for mp in edits1(getpass('master password:')):
    p = create('kredodirect', mp)
    if p[0] == 'z':
        n += 1
        print
        print n
        print mp, p

Отримав 31 варіант помилки і паролі які виходять в результаті. Десь на перевірці четвертого пароля мені сказало: “Доступ до Інтернет сервісу заблокований”, і цим моя атака грубою силою закінчилась. :( Українським пенсіонерам доведеться ще трохи почекати на свою пенсію. А мені доведеться йти в банк. Там треба купити картку з одноразовими ключами за 40 грн, так сказала техпідтримка. :(

А ще вчора спробував купити квитки додому. Квиток в одну сторону чомусь вже коштує 57 грн. Недавно за ці гроші до Києва можна було доїхати. Стільки готівки я при собі не мав, а був в той час в центральних квиткових касах. Вони працюють до восьмої вечора, довелось раніше з роботи піти аби до них дістатись. І виявилось, що картки Visa вони не приймають. Якийсь задрипаний мінімаркет під моїм будинком приймає, а центральні квиткові каси Львівської залізниці – ні. Я просто не знаю що сказати…

А ще треба закрити картки в інших банках але кожного разу коли я мимо них проходжу – відділення не працює. Я не знаю, мені для цього відпустку брати, чи що?


Filed under: Кодерство, Нещоденник Tagged: гроші, зле, Python

Дундер

Сьогодні в маршрутці читав деяку документацію і офігівав з терміну dunder-init. Прийшов на роботу, погуглив, виявляється dunder розшифровується як double underscore, а dunder-init означає __init__. Термін створено для того аби було простіше читати код вголос (тому що “underscore underscore init underscore underscore” забирає багато сил). Але використовувати це в друкованому тексті я б не радив, бо ж збиває з пантелику.

І на цьому Бунькопедія сьогодні призупиняє свою роботу, тому що почався чудовий понеділок, і пора взятись за написання всіх цих дундерів.


Filed under: Кодерство, Конспекти Tagged: переклад, Python

Javascript чудовий

Настільки чудовий що дехто навіть мене ревнує. Ну бо логічно, якщо б JavaScript не був таким класним, я б проводив з ним час лише на роботі, а тут займаюсь ним ще й коли іноді ночами не спиться… Останні два тижні на роботі я вже не JavaScript розробник, а DevOps, що є зовсім новою для мене професією, в якій я такий нуб, що повозившись пів дня з 503 помилками сервера я просто змінив для нього користувача з nginx на root і все запрацювало. Звичайно це страшно, але якщо є екстремальне програмування, то повинно ж ще бути екстремальне розгортання, правда? :D Але про те який з мене сисадмін я напишу коли зроблю все правильно, а поки що про JavaScript.

З ним, і трошки з CSS я на дозвіллі вправляюсь на власному сайті http://bunyk.github.io/. І нарешті вже я веб-розробник з сайтом. Бо якось дивно було, в резюме написано що веб-розробник, а крім Python майже нічого не знав…

В JavaScript є свої косяки. Про деякі розповідають у вже класичній презентації WAT!. Хоча node.js в мене деякі штуки показує не так як в тій презентації:

> [] + {}
'[object Object]'
> {} + []
'[object Object]'
> {} + {}
'[object Object][object Object]'

Ну але блін, кому захочеться додавати об’єкти? Якщо ви мали на увазі extend, то така функція є багатьох популярних бібліотеках. Тому якщо про косяки знати – вони не страшні. Достатньо про косяки написано на сторінці JavaScript Garden. Хоча це ж навіть не косяки, а особливості…

Ще хочу показати виступ Дугласа Крокфорда (того що винайшов JSON і написав книжку JavaScript Good Parts). Там він цікаво розповідає про історію LiveScript/JavaScript/JScript/ECMAScript і про те яка нелегка доля цій мові випала. Зокрема, Брендана Ейха змусили взяти синтаксис Java, він хотів написати Scheme. (CoffeeScript проблему з синтаксисом усуває, і це не остання причина використовувати CoffeeScript. Він також усуває косяки, без використання “use strict”;)

The first time I saw JavaScript in 1995, I thought “This is the stupidest thing I ever seen”. And I was pretty confident that I was right. … Five years later … I discovered it has lambdas in it!

Ах, ще з цієї доповіді я дізнався що є така функція як Y комбінатор (рекомендую статтю, вона від того самого дядька який написав illustrated guide to PhD), яка вміє перетворювати рекурсивні функції на нерекурсивні аналоги, і виглядає отак:

var Y = function (F) {
 return (function (x) {
  return F(function (y) { return (x(x))(y);});
  })
        (function (x) {
  return F(function (y) { return (x(x))(y);});
  }) ;
} ;

Я поки що дивлюсь на цю функцію як баран, але думаю незабаром вникну в суть.

Це одна з багатьох речей які зі мною останнім часом відбуваються, але про все розповідати доведеться довго. Тому поки що дивіться мій сайт, коментуйте, ставте лайки, розкажіть друзям, f*&k my repo чи краще submit issue. Пост про nginx, fabric, tar, mako, або систему топологічного сортування залежностей колись буде. Ви лише скажіть що вам цікавіше.


Filed under: Кодерство, Павутина Tagged: JavaScript

Журнальне програмування, JavaScript

Я вже якось писав що без написання коментарів можна обійтись, якщо використовувати рефакторинг “extract method”. Це не означає що коментарі не варто писати, це означає що їх потрібно писати на іншому рівні абстракції і бажано в мові предметної області. Як цього навчитись – складне питання. Щоправда недавно вичитав в пості Дмитра Сіренка на Google+ ідею про те що коментарі краще робити виводом в якийсь лог.

Ця ідея для мене нова і мені дуже сподобалась. По-перше це допоможе краще думати про що ж все таки писати в коментарі. Про те що відбувається:

Якби програмки мали Твіттер...

Якби програмки мали Твіттер…

А що ще краще – такі коментарі повинні сильно допомогти в розумінні коду JavaScript, тому що в JavaScript код виконується як реакція на якусь подію, тому передбачити що за чим виконуватиметься – важко. А при таких коментарях – відкрили термінал, і читаємо коментарі в хронологічному порядку виконання програми:

dragExcercise plugin started for Object[div.exercise, div.exercise] exercises.js (рядок 8)
heißen Ordnung exercises.js (рядок 22)
content put into element exercises.js (рядок 28)
incorrect variant exercises.js (рядок 35)
heißen mir exercises.js (рядок 22)
content put into element exercises.js (рядок 28)
incorrect variant exercises.js (рядок 35)
leaves some other element exercises.js (рядок 45)
mir mir exercises.js (рядок 22)
element already occupied exercises.js (рядок 24)

Так працює код вправ для інтерактивного підручника німецької.

Коментарі записуються як параметри функції c яка описується наступним чином:

    //var c = function() {}; // for production
    var c = console.log.bind(console); // for debug

З цим є дві проблеми. Перша – навіть якщо не забути про те що треба переставити комент, на продакшні буде зайвий виклик функції. Друга – функція підсвічується в редакторі як функція, а не як коментар. Другу можна виправити відредагувавши файл з описом синтаксису мови. Це просто. Першу проблему хотілось би виправити макросами в стилі С. З директивами IFDEBUG, та двома режимами білду – debug та release.

Проблеми можна проігнорувати, а можна подумати про препроцесор. Який коментарі виду

    //-> message

перетворюватиме на

    console.log('message');

в дебаг режимі, і прибиратиме їх з реліз версії коду. Але препроцесори вже є, наприклад той же CoffeScript. Тільки от не знаю чи важко на ньому таке реалізувати… Може варто спробувати зразу осідлати ClojureScript?


Filed under: Кодерство, Павутина, Розмітка Tagged: JavaScript, розробка