Статья о простом, но не очевидном способе как сделать код чище и избавиться от копипасты.
Условно проблема выглядит вот так:
У нас есть кусок кода (тот, что с проверкой), который во-первых похоже потребуется повторить в новом методе, да и вообще отвлекает от основного действа в методе.
Для избавления от копипасты мы слегка схитрим и изменим код модуля, введя одну внеклассовую функцию, и результат станет выглядеть так:
Этот же принцип можно использовать для отладочного логирования:
И всего, чего вам только вздумается.
Ложка дегтя (куда уж без нее) — сами декораторы таки придется копипастить из модуля в модуль, простого и очевидного способа расшарить их я пока не нашел.
Бочка меда (спасибо Infernal) — для использования декораторов в проекте — просто собираем их в модуле(-ях) и импортируем требуемые в нужном месте, что еще больше сокращет объем писанины и повышает читабельность.
Этот трюк был честно куплен с книжкой CoffeeScript Ristretto, по мне — самой толковой для понимания CoffeeScript.
PS. Это правоверный способ использования декораторов, без
PPS. Скобки вокруг содержимого декорированного метода в классе использовать не обязательно, но они помогают подсветке TM2, поэтому я их включаю в свой код.
Условно проблема выглядит вот так:
### My awesome class ### class Awesome doFoo : (arg, cb) -> unless arg is 42 return cb Error """ only The Answer may be an argument, but got: |arg| = |#{arg}| """ cb null, "#{arg} is The Answer" doBar : (arg, cb) -> # hm... arg must be The Answer too
У нас есть кусок кода (тот, что с проверкой), который во-первых похоже потребуется повторить в новом методе, да и вообще отвлекает от основного действа в методе.
Для избавления от копипасты мы слегка схитрим и изменим код модуля, введя одну внеклассовую функцию, и результат станет выглядеть так:
### My awesome class ### ensureArgIsTheAnswer = (methodBody) -> (arg, cb) -> unless arg is 42 return cb Error """ only The Answer may be an argument, but got: |arg| = |#{arg}| """ methodBody.call @, arg, cb class Awesome doFoo : ( ensureArgIsTheAnswer (arg, cb) -> cb null, "#{arg} is The Answer" ) doBar : ( ensureArgIsTheAnswer (arg, cb) -> cb null, "#{arg*2} is The Double Answer" )
Этот же принцип можно использовать для отладочного логирования:
### Logging method decorator ### logOnDemand = (methodBody) -> (args...)-> __rval__ = methodBody.apply this, args if @_do_logging_ console.log "#{args[0]} -> #{__rval__}" __rval__
И всего, чего вам только вздумается.
Бочка меда (спасибо Infernal) — для использования декораторов в проекте — просто собираем их в модуле(-ях) и импортируем требуемые в нужном месте, что еще больше сокращет объем писанины и повышает читабельность.
Этот трюк был честно куплен с книжкой CoffeeScript Ristretto, по мне — самой толковой для понимания CoffeeScript.
PS. Это правоверный способ использования декораторов, без
callee и прочей бесовщины, он не портит кармы.PPS. Скобки вокруг содержимого декорированного метода в классе использовать не обязательно, но они помогают подсветке TM2, поэтому я их включаю в свой код.
