а чуть более в другом местеSomeBoilerplate(1); MoreBoilerplate("Some parameter"); TheCodeThatYouActuallyNeed(); YetAnotherPieceOfBoilerplate(Foo.Bar);
?SomeBoilerplate(0); MoreBoilerplate("Other parameter"); YouNeedThatCodeToo(); YetAnotherPieceOfBoilerplate(Foo.Baz);
Сразу видно, что можно бы завернуть все это дело в функцию, принимающую параметры для бойлерплейтного кода... вот только действительно нужный код везде разный и в лучшем случае нам удастся свести три строки бойлерплейта к двум. Это, конечно кажется выходом, когда лишних строк больше десяти, но все равно, надо о них помнить и надо их писать (или копипастить).
Так вот, пока овцеебы из Вильяриба наворачивают на это слои
Применяется он так:(defmacro with-boilerplate (number string enum &rest body) `(progn (some-boilerplate ,number) (more-boilerplate ,string) ,@body (yet-another-piece-of-boilerplate ,enum)))
Правда, охуенно?(with-boilerplate 1 "Some parameter" 'foo-bar (the-code-you-actually-need)) (with-boilerplate 0 "Other parameter" 'foo-baz (you-need-that-code-too))
В F# это делается примерно так же:
Правда, это уже не будет раскрываться во время компиляции и мы понесем все тяготы и лишения -- пролог и эпилог на байтоебском спике -- которые связаны с вызовом функции. Впрочем, это уже проблема компилятора и байтоебов.let WithBoilerplate aNumber aString aEnum aBody = SomeBoilerplate aNumber MoreBoilerplate aString aBody () YetAnotherPieceOfBoilerplate aEnum WithBoilerplate 1 "Some parameter" Foo.Bar (fun () -> TheCodeThatYouActuallyNeed()) WithBolierplate 0 "Other parameter" Foo.Baz (fun () -> YouNeedThatCodeToo())
К сожалению, в C# мы похожие макросы получим разве что через пару лет (а в Java -- сразу после никогда) когда то, что сейчас стыдливо прозывается Roslyn будет более-менее широко применяться, но и сейчас в нем можно сделать кое-что похожее:
using System; public class WithBoilerplate { public static void Do(int Number, string Str, Foo BarOrBaz, Action UsefulCode) { SomeBoilerplate(Number); MoreBoilerplate(Str); UsefulCode(); YetAnotherPieceOfBoilerplate(BarOrBaz); } } WithBoilerplate.Do(1,"Some parameter",Foo.Bar,() => TheCodeThatYouActuallyNeed()); WithBoilerplate.Do(1,"Other parameter,Foo.Baz,() => YouNeedThatCodeToo());
Комментариев нет:
Отправить комментарий