Что Вы подразумеваете под изяществом? Что Вы вкладываете в это понятие относительно языка программирования? Или Вы просто поддакиваете мэйн-стриму, где каждый второй скрипт-кидис считает своим долгом сказать: «после знакомства с Ruby / Python я возненавидел PHP»? Между прочим, Python был до PHP, а Ruby появился всего лишь через год после PHP — так почему Вы пришли к PHP?
Как по-Вашему, например, JavaScript — это изящный язык? Если да, насколько он изящней PHP и почему? А насколько Ruby?
.ps: мне очень нравятся JavaScript, Python, Ruby — они идеологически похожи, и, действительно, — красивые языки. Но, вместе с тем, я вполне адекватно отношусь в PHP.
Мне просто реально интересно — почему каждый второй в статье о Руби или Питон пишет — «я возненавидел PHP»? При этом, мне, почему-то, кажется, что сам Ruby эти люди знают поверхностно; ведь в 97% их прельстили Рельсы, а не Рубин.
Несколько дешевый трюк — назвать себя «элитой» (см. «Формат ВЕБОРУБА нам представляется таким»), которая идет вопреки «попсе» (например, раздел «Отношение к спонсорам») — да, на это народ обычно ведется. Это один из подходов в экономическом разделе — «очень дорого, элитарно, но только для очень избранных». При этом эта «избранность» (при такой подаче) — в 99% — самозваная. Но, массовый «гипноз» делает свое дело, и публика начинает в это верить самозванцам (на этой же схеме работает продажа куска тряпки за бешеные деньги).
ВЕБОРУБ – это звание, присваиваемое ведущим веб-разработчикам, либо людям, заслужившим признание других веб-разработчиков.
Кем присваиваемая? Кто у вас главный?
.ps: для этой «элитарной схемы» название «Веборуб» несколько деревенское. Та система, которую выбрали вы, основывается на возвышении над другими «сословиями» (не «элитарными») веб-разработчиков, а посему должна (по нынешним меркам) иметь больше аристократический вид. При этом в самом аристократическом подходе ничего плохого нет, а вот в неестественном и самозваном — может быть. Так что, такую политику нужно проводить осторожно, чтобы не переборщить.
> я бы других аналогий из других языков не искал, а то ещё сложнее станет спроецировать
да нет, я вообще не знал, что такое «штрих», поэтому интересно в любом случае — независимо от JS. А касательно JS я знаю, что терминология ES не описывает подобной сущности, поэтому (лично для меня) путаницы не будет.
> Брутальный синоним «прямо» ;) Я имел в виду…
да я понял =))) я тоже сказал, что «почему не смело? обычное расширение объекта новыми слотами — есть своего рода примесь».
и еще выдержка из другого PDF: www.iam.unibe.ch/~scg/Archive/Papers/Scha03aTraits.pdf
Traits have the following properties.
– A trait provides a set of methods that implement behaviour.
– A trait requires a set of methods that serve as parameters for the provided behaviour.
– Traits do not specify any state variables, and the methods provided by traits never access state variables directly.
– Classes and traits can be composed from other traits, but the composition order is irrelevant. Conflicting methods must be explicitly resolved.
– Trait composition does not affect the semantics of a class: the meaning of the class is the same as it would be if all of the methods obtained from the trait(s) were defined directly in the class.
– Similarly, trait composition does not affect the semantics of a trait: a composite trait is equivalent to a flattened trait containing the same methods.
Ну да, только меня смутило обязательное «parent object». Вот все-таки — это только в SELF'e или это везде так относительно traits?
В весьма скудном описании Trait_(abstract_type) из en-википедии вообще какое-то очень странное отличие дано от mixin'ов:
Traits are similar to mixins, but may include definitions for class methods.
Что знаит, «но только может включать определения для классовых методов»? А что, примесь не может что ли? — Тоже может. Или имеется в виду определения методов, которые должны быть реализованы в классе? Так и примесь под это определение подходит.
В общем, вот PDF нашел: www.iam.unibe.ch/~scg/Archive/PhD/schaerli-phd.pdf
Цитата из главы 3.1 «Traits – Composable Units of Behavior»:
Traits bear a superficial resemblance to mixins, with several important differences. Several traits can be
applied to a class in a single operation, whereas mixins must be applied one at a time. Trait composition is
unordered, thus avoiding problems due to linearization of mixins. Traits contain methods, but no state, so state
conflicts are avoided, but method conflicts may exist. A class is specified by composing a superclass with a
set of traits and some glue methods. Glue methods are defined in the class and they connect the traits together;
i.e., they implement required trait methods (possibly by accessing state), they adapt provided trait methods, and
they resolve method conflicts.
> которые по сути и есть traits, где мы определяем общее поведение
да, абстрактную параллель (особенно из определения SELF'a) можно провести, только прототип может содержать и состояние, а не только методы;
> mixin-ы же можно или считать отсутствующими, или это тупо любой объект, свойства которого можно подбросить (например, тем же копированием) к прототипу/объекту
конечно, согласно текущей спецификации нет в ES никаких mixin'ов, но а, опять же абстрактно, — почему тупо? Вполне — обычное расширение объекта копированием.
И, конечно же, любая новая теория — есть синтез уже ранее существовавших. Тут еще один важный момент — «первоисточник» тоже люди писали и (чисто гипотетически) они могли ошибиться (или же по прошествии некоторого времени осознать неэффективность той технологии, которую описали). Вот тогда, «первоисточник» переписывается и вводятся новые технологии (и терминологии).
Но это так — лишь философски и топика не касается ;)
Да, ествественно, однако, всегда убедительней звучат высказывания, основанные на первом подходе (во всяком случае — легче приводить аргументы, ссылаясь на «первоисточник», который должен являться «интерфейсом дискуссии/спора» — т. е. тем, что принимается априори, то, с чем согласны обе стороны; далее, эти рамки можно расширить (абстрагируюсь), но изначально — «первоисточник» — это удобный старт для начала разговора).
С другой стороны, второй подход, когда пытливо сам разрабатываешь «какую-то теорию», пытаясь самостоятельно (возможно, основываясь на каких-то эмпирических опытах) объяснить то или иное поведение системы, может служить хорошей тренировкой мозгов. Но! ;) Как правило, в итоге этих исследований (если все расчеты были верны и все опыты положительны), все равно приходишь к спецификации. =) (это как в старой песне: «кто-то заметил, а кто-то спросил, а третий — запишет ответ»).
Хм… Что-то я сбился. Значит трейтс (во всяком случае в SELF'е) — это обязательно родительский объект? А миксин — это тоже самое, но «без родителя» (?) (я правильно перевел — «parentless»? или «не родительский объект»?), что позволяет, так же расширить функционал сторонним поведением, но в отличии от traits избежать ненужных методов из родителя?
Да, все та же «проблема» миксовки терминологий, но, повторю, часто концов не сыщешь, кто был первым в терминологии, и не поймешь, кто на кого ссылался при создании своих сущностей.
Поэтому, главное, я считаю, — понимание общих закономерностей (на формулах, на буквах) и уже потом привязка к конкретным терминологиям (на числах). И здесь иногда удобно абстрагироваться от «конкретных чисел» (но, ясно-понятно, только лишь в терминологии для проведения параллелей, иначе, опять повторюсь, получится отсебятина). Ну а самое главное, если речь все-таки идет о конкретной технологии, чтобы этих абстрактных отхождений от терминологии спецификации было немного, иначе — снова — терминологическая каша. ;)
> В нём могут содержаться какие-то конечные функции/методы. Для них могут понадобится какие-то свои данные, которые в конечном итоге будут содержатся в thisObj.
да, создание состояния (this-свойств) в штрихе может породить конфликт состояний (программист, использующий Ваш штрих может завести в классе свое свойство «а», в то время как Вы использовали его в штрихе; в итоге работа штриха будет нарушена).
Кстати, некоторые (например, PHP) эту проблему решают специфичным именованием — так PHP оставляет за собой право на использование любых имен, с двумя ведущими подчеркиваниями (__construct, __destruct, __set, __get, и т. д.), что потенциально, если не знать об этом соглашении, может создать конфликт имен. Так и здесь — в документации к абстрактному классу (штриху) можно указать, что штрих оставляет за собой право на именование this-свойство, начинающийхся с фразы BlaBla (BlaBla_check, BlaBla_set, и т. д.). Но, это, все же, компромиссное решение, а не на уровне автоматизации.
> но буду стараться, чтобы каждый отдельный плагин получался «штрихом».
так а че там стараться? — главное, как и при описании абстрактного класса, указать какие именно методы должен реализовать класс, использующий штрих; а дальше уже штрих будет работать с этими методами.
не, ну я ж уточнил — "абстрактно отойти от спецификации", а не кардинально, иначе отсебятина получится
> после new мы пишем имя функции
все правильно, и задача этой функции — проинициализировать объект и создать неявную (это важно!) связь с прототипом. Все. На этом ее работа закончена и она может исчезнуть, освободив драгоценную память.
> после instanceof — тоже имя функции
тоже все правильно, это оператор анализирует цепь прототипов для определения значения:
function Q (){};
Q.prototype.q = 10;
var q = new Q();
alert(q.q); // 10 - посредством делегирования
alert(q instanceof Q); // true
// обnullяем прототип
Q.prototype = null;
// за счет неявной цепи все имеем связь с прототипным объектом
alert(q.q);
// но вот instanceof уже не может достучаться до
// прототипного объекта через ссылку Q.prototype
alert(q instanceof Q); // .error
> конкретно в яваскрипте — функция, предназначенная для создания объектов.
неа, если уж миксовать терминологии (т. е. абстрактно отойти от спецификации ECMAScript), то роль класса в JS будет играть прототип (и именно с ним работает instanceof), а не конструктор. Вот как раз здесь, выше параллель организации Питона и JS — конструктор (ссылка на класс) умирает, но инстанс посредством своей ссылки (__class__) имеет доступ к цепи классов (в JS — умирает конструктор (функция), но объект имеет доступ к протоипному объекту посредством __proto__).
> так как звучит основное отличие примеси от штриха
а, ну да, именно в этом:
> описывается… операция… в самом классе (т. е. данные не выходят наружу), а дальше примесь (штрих) уже на основе этой операции использует другие операции
Штрих имеет доступ к методам класса, но не к данным. Но, надо полагать, что лишь к методам, которые класс реализовывает от штриха, а не ко всем (на уровне соглашения), иначе — получится, хоть и не нарушение инкапсуляции (поскольку методы — public), но хардкод чужих методов в примеси, а не свойств.
так как звучит основное отличие примеси от штриха (подмножества примеси)? Как я понял, примеси в своих методах могут использовать данные, не описанные в самой примеси — т. е. данные из класса, который будет использовать эту примесь. Так? (хотя в определении написано, что примесь не содержит данных — или имеются в виду «свои данные»?)
Абстрактно:
Примесь использует переменную «a», которая не определена в ней:
класс МояПримесь:
функция проверить():
@a > 10 ? ложь : истина
Но «а» определена в классе, использующем примесь:
класс МойКласс:
включить: МояПримесь
инициализация:
@a = 10
В итоге объекту класса «МойКласс» будет доступен метод «проверить» относительно «а».
Это примесь. А штрих тогда кто? Тот, кто не содержит «своих данных», плюс к этому даже не оперирует «свободными данными» (которые описаны в классе, использующем штрих/примесь)? Т. е. как в примере с Comparable из Ruby — описывается одна операция <=> в самом классе (т. е. данные не выходят наружу), а дальше примесь (штрих) уже на основе этой операции использует другие операции (но тем самым мы не хардкодим свободные переменные для примеси). Да?
P.S.: а вообще, день не прошел зря, что-то новое узнал. Спасибо =)
а-а )) у меня, оказывается, эта ссылка была в закладках еще чуть ли не год назад. Но я положил ее в закладки и забыл — да и не дочитал до места со «штрихами». Спасибо =)
наличие сущности «класс» не означает присутствие «строгой» инкапсуляции (создающей концепцию «черного ящика»)
Часто инкапсуляция может быть достигнута простейшими организационными мерами: Знание того, что «вот так-то делать нельзя» иногда является самым эффективным средством инкапсуляции!
Как пример — опять же Питон — уровни доступа свойств там определены на уровне именования. Так, private-свойство (обозначается двумя ведущими подчеркиваниями) __приватноеСвойство будет недоступно извне. Однако, при определении класса, оно преобразуется к виду _ИмяКласса__приватноеСвойство и доступно как public — «Все ж открыто;».
Как по-Вашему, например, JavaScript — это изящный язык? Если да, насколько он изящней PHP и почему? А насколько Ruby?
.ps: мне очень нравятся JavaScript, Python, Ruby — они идеологически похожи, и, действительно, — красивые языки. Но, вместе с тем, я вполне адекватно отношусь в PHP.
Мне просто реально интересно — почему каждый второй в статье о Руби или Питон пишет — «я возненавидел PHP»? При этом, мне, почему-то, кажется, что сам Ruby эти люди знают поверхностно; ведь в 97% их прельстили Рельсы, а не Рубин.
Кем присваиваемая? Кто у вас главный?
.ps: для этой «элитарной схемы» название «Веборуб» несколько деревенское. Та система, которую выбрали вы, основывается на возвышении над другими «сословиями» (не «элитарными») веб-разработчиков, а посему должна (по нынешним меркам) иметь больше аристократический вид. При этом в самом аристократическом подходе ничего плохого нет, а вот в неестественном и самозваном — может быть. Так что, такую политику нужно проводить осторожно, чтобы не переборщить.
Подобную идеологию имеют <ahref=«ru.wikipedia.org/wiki/Яппи»>Яппи.
> старт для начала
> эмпирических опытах
масло масляное в масле с маслом =))))
да нет, я вообще не знал, что такое «штрих», поэтому интересно в любом случае — независимо от JS. А касательно JS я знаю, что терминология ES не описывает подобной сущности, поэтому (лично для меня) путаницы не будет.
> Брутальный синоним «прямо» ;) Я имел в виду…
да я понял =))) я тоже сказал, что «почему не смело? обычное расширение объекта новыми слотами — есть своего рода примесь».
Anyway, спасибо =)
В весьма скудном описании Trait_(abstract_type) из en-википедии вообще какое-то очень странное отличие дано от mixin'ов:
Что знаит, «но только может включать определения для классовых методов»? А что, примесь не может что ли? — Тоже может. Или имеется в виду определения методов, которые должны быть реализованы в классе? Так и примесь под это определение подходит.
В общем, вот PDF нашел: www.iam.unibe.ch/~scg/Archive/PhD/schaerli-phd.pdf
Цитата из главы 3.1 «Traits – Composable Units of Behavior»:
> которые по сути и есть traits, где мы определяем общее поведение
да, абстрактную параллель (особенно из определения SELF'a) можно провести, только прототип может содержать и состояние, а не только методы;
> mixin-ы же можно или считать отсутствующими, или это тупо любой объект, свойства которого можно подбросить (например, тем же копированием) к прототипу/объекту
конечно, согласно текущей спецификации нет в ES никаких mixin'ов, но а, опять же абстрактно, — почему тупо? Вполне — обычное расширение объекта копированием.
Но это так — лишь философски и топика не касается ;)
С другой стороны, второй подход, когда пытливо сам разрабатываешь «какую-то теорию», пытаясь самостоятельно (возможно, основываясь на каких-то эмпирических опытах) объяснить то или иное поведение системы, может служить хорошей тренировкой мозгов. Но! ;) Как правило, в итоге этих исследований (если все расчеты были верны и все опыты положительны), все равно приходишь к спецификации. =) (это как в старой песне: «кто-то заметил, а кто-то спросил, а третий — запишет ответ»).
Поэтому, главное, я считаю, — понимание общих закономерностей (на формулах, на буквах) и уже потом привязка к конкретным терминологиям (на числах). И здесь иногда удобно абстрагироваться от «конкретных чисел» (но, ясно-понятно, только лишь в терминологии для проведения параллелей, иначе, опять повторюсь, получится отсебятина). Ну а самое главное, если речь все-таки идет о конкретной технологии, чтобы этих абстрактных отхождений от терминологии спецификации было немного, иначе — снова — терминологическая каша. ;)
да, создание состояния (this-свойств) в штрихе может породить конфликт состояний (программист, использующий Ваш штрих может завести в классе свое свойство «а», в то время как Вы использовали его в штрихе; в итоге работа штриха будет нарушена).
Кстати, некоторые (например, PHP) эту проблему решают специфичным именованием — так PHP оставляет за собой право на использование любых имен, с двумя ведущими подчеркиваниями (__construct, __destruct, __set, __get, и т. д.), что потенциально, если не знать об этом соглашении, может создать конфликт имен. Так и здесь — в документации к абстрактному классу (штриху) можно указать, что штрих оставляет за собой право на именование this-свойство, начинающийхся с фразы BlaBla (BlaBla_check, BlaBla_set, и т. д.). Но, это, все же, компромиссное решение, а не на уровне автоматизации.
так а че там стараться? — главное, как и при описании абстрактного класса, указать какие именно методы должен реализовать класс, использующий штрих; а дальше уже штрих будет работать с этими методами.
не, ну я ж уточнил — "абстрактно отойти от спецификации", а не кардинально, иначе отсебятина получится
> после new мы пишем имя функции
все правильно, и задача этой функции — проинициализировать объект и создать неявную (это важно!) связь с прототипом. Все. На этом ее работа закончена и она может исчезнуть, освободив драгоценную память.
> после instanceof — тоже имя функции
тоже все правильно, это оператор анализирует цепь прототипов для определения значения:
неа, если уж миксовать терминологии (т. е. абстрактно отойти от спецификации ECMAScript), то роль класса в JS будет играть прототип (и именно с ним работает instanceof), а не конструктор. Вот как раз здесь, выше параллель организации Питона и JS — конструктор (ссылка на класс) умирает, но инстанс посредством своей ссылки (__class__) имеет доступ к цепи классов (в JS — умирает конструктор (функция), но объект имеет доступ к протоипному объекту посредством __proto__).
а, ну да, именно в этом:
> описывается… операция… в самом классе (т. е. данные не выходят наружу), а дальше примесь (штрих) уже на основе этой операции использует другие операции
Штрих имеет доступ к методам класса, но не к данным. Но, надо полагать, что лишь к методам, которые класс реализовывает от штриха, а не ко всем (на уровне соглашения), иначе — получится, хоть и не нарушение инкапсуляции (поскольку методы — public), но хардкод чужих методов в примеси, а не свойств.
Абстрактно:
Примесь использует переменную «a», которая не определена в ней:
Но «а» определена в классе, использующем примесь:
В итоге объекту класса «МойКласс» будет доступен метод «проверить» относительно «а».
Это примесь. А штрих тогда кто? Тот, кто не содержит «своих данных», плюс к этому даже не оперирует «свободными данными» (которые описаны в классе, использующем штрих/примесь)? Т. е. как в примере с Comparable из Ruby — описывается одна операция <=> в самом классе (т. е. данные не выходят наружу), а дальше примесь (штрих) уже на основе этой операции использует другие операции (но тем самым мы не хардкодим свободные переменные для примеси). Да?
P.S.: а вообще, день не прошел зря, что-то новое узнал. Спасибо =)
а-а )) у меня, оказывается, эта ссылка была в закладках еще чуть ли не год назад. Но я положил ее в закладки и забыл — да и не дочитал до места со «штрихами». Спасибо =)
наличие сущности «класс» не означает присутствие «строгой» инкапсуляции (создающей концепцию «черного ящика»)
Как пример — опять же Питон — уровни доступа свойств там определены на уровне именования. Так, private-свойство (обозначается двумя ведущими подчеркиваниями) __приватноеСвойство будет недоступно извне. Однако, при определении класса, оно преобразуется к виду _ИмяКласса__приватноеСвойство и доступно как public — «Все ж открыто;».
кстати, а по поводу ES4 (JS 2), представители от Microsoft были в числе первых, кто отрицал этот проект в пользу JS (максимум) 1.6-1.7.