Skip to content

Commit

Permalink
- some progress on manual
Browse files Browse the repository at this point in the history
  • Loading branch information
canonic-epicure committed Oct 8, 2009
1 parent 34ca21e commit 7e617a6
Show file tree
Hide file tree
Showing 21 changed files with 277 additions and 220 deletions.
2 changes: 1 addition & 1 deletion doc/html/Joose/Manual.html
Expand Up @@ -104,7 +104,7 @@ <h1 id="tableofcontents">TABLE OF CONTENTS</h1>
<li><p><a href="Manual/Reflection.html">Joose.Manual.Reflection</a></p>

<p>Joose's meta API system lets you ask classes about their parent, children, methods, attributes, etc.</p></li>
<li><p><a href="Manual/MetaRoles.html">Joose.Manual.MetaRoles</a></p>
<li><p><a href="Manual/MetaRoles.html">TODO: Joose.Manual.MetaRoles</a></p>

<p>Joose allows you to modify not only class's behavior, but also behaviour of its metaclass. Read this document to know how. </p></li>
<li><p><a href="Manual/JooseX.html">Joose.Manual.JooseX</a></p>
Expand Down
24 changes: 14 additions & 10 deletions doc/html/Joose/Manual/Contributing.html
Expand Up @@ -98,7 +98,7 @@ <h2 id="preparingatopicbranch">Preparing a topic branch</h2>

<p>However, by far the biggest benefit is that the number of commits that go into master is eventually reduced, and they are simple and coherent, making it much easier for people maintaining branches to stay up to date.</p>

<p>All large changes should be documented in <a href="Joose.Manual.Delta">Joose.Manual.Delta</a></p>
<p>All large changes should be documented in <a href="Delta.html">Joose.Manual.Delta</a></p>

<h1 id="approvalworkflow">APPROVAL WORKFLOW</h1>

Expand All @@ -114,13 +114,14 @@ <h2 id="smallbugfixesdocpatchesandadditionalpassingtests.">Small bug fixes, doc

<h2 id="largerbugfixesdocadditionsandtodoorfailingtests.">Larger bug fixes, doc additions and TODO or failing tests.</h2>

<p>Larger bug fixes should be reviewed by at least one cabal member and should be tested using the cpan-stable-smolder script in the Joose-dev-utils repository.</p>
<p>Larger bug fixes should be reviewed by at least one cabal member and should be extensively tested.</p>

<p>New documentation is always welcome, but should also be reviewed by a cabal member for accuracy.</p>

<p>TODO tests are basically feature requests, see our "NEW FEATURES" section for more information on that. If your feature needs core support, create a topic/ branch using the "STANDARD WORKFLOW" and start hacking away.</p>

<p>Failing tests are basically bug reports. You should find a core contributor and/or cabal member to see if it is a real bug, then submit the bug and your test to the RT queue. Source control is not a bug reporting tool.</p>
<p>Failing tests are basically bug reports. You should find a core contributor and/or cabal member to see if it is a real bug, then submit the bug and your test to the <a href="http://code.google.com/p/joose-js/issues/list">issues tracker</a>.
Source control is not a bug reporting tool.</p>

<h2 id="newuser-facingfeatures.">New user-facing features.</h2>

Expand Down Expand Up @@ -187,8 +188,9 @@ <h1 id="projectworkflow">PROJECT WORKFLOW</h1>
<pre><code>git checkout -b my-project--topic/foo my-project
</code></pre>

<p>(unfortunately Git will not allow my-project/foo as a branch name if my-project is a valid ref).
THE "PU" BRANCH ^</p>
<p>(unfortunately Git will not allow my-project/foo as a branch name if my-project is a valid ref).</p>

<h1 id="thepubranch">THE "PU" BRANCH</h1>

<p>To make things easier for longer lived branches (whether topics or projects), the 'pu' branch is basically what happens if you merge all of the branches and topics together with master.</p>

Expand Down Expand Up @@ -220,21 +222,23 @@ <h1 id="brancharchival">BRANCH ARCHIVAL</h1>

<h1 id="teststeststests">TESTS, TESTS, TESTS</h1>

<p>If you write any code for Joose or Class.MOP, you must add tests for that code. If you do not write tests then we cannot guarantee your change will not be removed or altered at a later date, as there is nothing to confirm this is desired behavior.</p>
<p>If you write any code for Joose, you must add tests for that code. If you do not write tests then we cannot guarantee your change will not be removed or altered at a later date, as there is nothing to confirm this is desired behavior.</p>

<p>If your code change/addition is deep within the bowels of Joose/Class.MOP and your test exercises this feature in a non-obvious way, please add some comments either near the code in question or in the test so that others know.</p>
<p>If your code change/addition is deep within the bowels of Joose and your test exercises this feature in a non-obvious way, please add some comments either near the code in question or in the test so that others know.</p>

<p>We also greatly appreciate documentation to go with your changes, and an entry in the Changes file. Make sure to give yourself credit!</p>

<h1 id="backwardscompatibility">BACKWARDS COMPATIBILITY</h1>

<p>Change is inevitable, and Joose is not immune to this. We do our best to maintain backwards compatibility, but we do not want the code base to become overburdened by this. This is not to say that we will be frivolous with our changes, quite the opposite, just that we are not afraid of change and will do our best to keep it as painless as possible for the end user.</p>
<p>Change is inevitable, and Joose is not immune to this. We do our best to maintain backwards compatibility, but we do not want the code base to become overburdened by this.
This is not to say that we will be frivolous with our changes, quite the opposite, just that we are not afraid of change and will do our best to keep it as painless as possible for the end user.</p>

<p>The rule is that if you do something that is not backwards compatible, you must do at least one deprecation cycle (more if it is larger change). For really larger or radical changes dev releases may be needed as well (the Cabal will decide on this on a case-per-case basis).</p>
<p>The rule is that if you do something that is not backwards compatible, you must do at least one deprecation cycle (more if it is larger change).
For really larger or radical changes dev releases may be needed as well (the Cabal will decide on this on a case-per-case basis).</p>

<p>The preference with regard to deprecation is to warn loudly and often so that users will have time to fix their usages.</p>

<p>All backwards incompatible changes must be documented in Joose.Manual.Delta. Make sure to document any useful tips or workarounds for the change in that document.</p>
<p>All backwards incompatible changes must be documented in <a href="Delta.html">Joose.Manual.Delta</a>. Make sure to document any useful tips or workarounds for the change in that document.</p>

<h1 id="author">AUTHOR</h1>

Expand Down
10 changes: 5 additions & 5 deletions doc/html/Joose/Manual/JooseX.html
Expand Up @@ -6,7 +6,7 @@ <h1 id="joosex">JooseX?</h1>

<p>It's easy to extend and change Joose, and this is part of what makes Joose so powerful. You can use the meta API to do things your own way, add new features, and generally customize your Joose.</p>

<p>Writing your own extensions does require a good understanding of the meta-model. You can start learning about this with the <a href="Joose.Proto.Class">Joose.Proto.Class</a> docs. There are also several extension recipes in the <a href="Joose.Cookbook">Joose.Cookbook</a>.</p>
<p>Writing your own extensions does require a good understanding of the meta-model. You can start learning about this with the <a href="http://openjsan.org/go?l=Joose.Proto.Class">Joose.Proto.Class</a> docs. There are also several extension recipes in the <a href="../Cookbook.html">Joose.Cookbook</a>.</p>

<p>Explaining how to write extensions is beyond the scope of this manual. Fortunately, lots of people have already written extensions and put them on JSAN for you.</p>

Expand Down Expand Up @@ -46,7 +46,7 @@ <h1 id="joosex.attribute">JooseX.Attribute</h1>
})
</code></pre>

<p>For further reading please refer to <a href="JooseX.Attribute">JooseX.Attribute</a></p>
<p>For further reading please refer to <a href="http://openjsan.org/go?l=JooseX.Attribute">JooseX.Attribute</a></p>

<h1 id="joosex.namespace.depended">JooseX.Namespace.Depended</h1>

Expand Down Expand Up @@ -75,9 +75,9 @@ <h1 id="joosex.namespace.depended">JooseX.Namespace.Depended</h1>
<p>The most interesting feature of <code>JooseX.Namespace.Depended</code> is a special "grouped" loading mode, in which it can load a class with any number of recursive dependencies (in-depth) with only 2 http requests
(requires a server-side component). </p>

<p>JooseX.Namespace.Depended supports several transport layers (&lt;script&gt; tag, sync/async ajax, ServerJS), resource types (JavaScript, CSS, etc) and its very easy to add your own.</p>
<p><code>JooseX.Namespace.Depended</code> supports several transport layers (&lt;script&gt; tag, sync/async xhr, ServerJS), resource types (JavaScript, CSS, etc) and its very easy to add your own.</p>

<p>For further reading please refer to <a href="JooseX.Namespace.Depended">JooseX.Namespace.Depended</a></p>
<p>For further reading please refer to <a href="http://openjsan.org/go?l=JooseX.Namespace.Depended">JooseX.Namespace.Depended</a></p>

<h1 id="joosex.bridge.ext">JooseX.Bridge.Ext</h1>

Expand Down Expand Up @@ -119,7 +119,7 @@ <h1 id="joosex.bridge.ext">JooseX.Bridge.Ext</h1>
})
</code></pre>

<p>For further reading please refer to <a href="JooseX.Bridge.Ext">JooseX.Bridge.Ext</a></p>
<p>For further reading please refer to <a href="http://openjsan.org/go?l=JooseX.Bridge.Ext">JooseX.Bridge.Ext</a></p>

<h1 id="joosex.types">JooseX.Types</h1>

Expand Down
41 changes: 22 additions & 19 deletions doc/html/Joose/Manual/MethodModifiers.html
Expand Up @@ -19,7 +19,7 @@ <h1 id="whatisamethodmodifier">WHAT IS A METHOD MODIFIER?</h1>
}
})

Class('TidyPerson', {
Class('Person.Tidy', {
isa : Person,

before : {
Expand All @@ -46,7 +46,7 @@ <h1 id="whatisamethodmodifier">WHAT IS A METHOD MODIFIER?</h1>
})
</code></pre>

<p>Now if I call new TidyPerson().eat('apple') I'll get the following output:</p>
<p>Now if I call <code>new Person.Tidy().eat('apple')</code> I'll get the following output:</p>

<pre><code> washing hands
yummy
Expand All @@ -62,7 +62,9 @@ <h1 id="whatisamethodmodifier">WHAT IS A METHOD MODIFIER?</h1>

<h1 id="whyusethem">WHY USE THEM?</h1>

<p>Method modifiers have many uses. One very common use is in roles. This lets roles alter the behavior of methods in the classes that use them. See [Joose.Manual.Roles][1] for more information about roles.</p>
<p>Method modifiers have many uses. Generally, they simplify class logic, making it more "natural" and descriptable in natural words.</p>

<p>Another very common use of method modifiers is in roles. This lets roles alter the behavior of methods in the classes that use them. See <a href="Roles.html">Joose.Manual.Roles</a> for more information about roles.</p>

<p>Since modifiers are mostly useful in roles, some of the examples below are a bit artificial. They're intended to give you an idea of how modifiers work, but may not be the most natural usage.</p>

Expand All @@ -76,10 +78,10 @@ <h1 id="beforeandafter">BEFORE and AFTER</h1>
<pre><code> var tidyPerson = new TidyPerson()
var res = tidyPerson.eat('apple')

console.log(res == 'yummy') # returns 'yummy'
console.log(res == 'yummy') # returns 'yummy' from the inherited method
</code></pre>

<p>Another use for the before modifier would be to do some sort of prechecking on a method call or setter. For example:</p>
<p>Another use for the 'before' modifier would be to do some sort of prechecking on a method call or setter. For example:</p>

<pre><code> Class('Bus', {
isa : Vehicle,
Expand All @@ -94,17 +96,17 @@ <h1 id="beforeandafter">BEFORE and AFTER</h1>

<p>This lets us implement logical checks that don't make sense as type constraints. In particular, they're useful for defining logical rules about an object's state changes.</p>

<p>Similarly, an after modifier could be used for logging an action that was taken, and so on.</p>
<p>Similarly, an 'after' modifier could be used for logging an action that was taken, and so on.</p>

<h1 id="overrideandaround">OVERRIDE and AROUND</h1>

<p>An 'override' and 'around' modifiers are a bit more powerful than either a 'before' or 'after' modifier. It can modify the arguments being passed to the original method,
and you can even decide to simply not call the original method at all. You can also modify the return value of the original method.</p>

<pre><code> Class('Person', {
have : {
firstName : null,
lastName : null
has : {
firstName : { is : 'rw' },
lastName : { is : 'rw' }
},

methods : {
Expand All @@ -115,7 +117,7 @@ <h1 id="overrideandaround">OVERRIDE and AROUND</h1>
},

chatOnIRC : function (partner, message) {
return this.type(partner + ': ' + message
return this.type(partner + ': ' + message)
}
}
})
Expand All @@ -142,16 +144,17 @@ <h1 id="overrideandaround">OVERRIDE and AROUND</h1>
})
</code></pre>

<p>An 'override' modifier allows you to use the <strong>this.SUPER(arg1, arg2, ...)</strong> call in the modifier. As expected this call will execute the original method with provided arguments.
Its possible also to specify the arguments in the "packed" form, as array, with <strong>this.SUPERARG(argumentsArray)</strong>. This variant is usually used as <strong>this.SUPERARG(arguments)</strong></p>
<p>An 'override' modifier allows you to use the <code>this.SUPER(arg1, arg2, ...)</code> call in the modifier. As expected this call will execute the original method with provided arguments.
Its possible also to specify the arguments in the "packed" form, as array, with <code>this.SUPERARG(argumentsArray)</code>. This variant is usually used as <code>this.SUPERARG(arguments)</code> and is an
equivalent for <code>this.SUPER.apply(this, arguments)</code>.</p>

<p>An 'around' modifier receives the original method as its first argument, then any arguments passed to the original method.</p>

<h1 id="augment">AUGMENT</h1>

<p>The augment modifier provides a sort of inverted subclassing. You provide part of the implementation in a superclass, and then document that subclasses are expected to provide the rest.</p>

<p>The superclass calls <strong>this.INNER()</strong>, which then calls the augment modifier in the subclass:</p>
<p>The superclass calls <code>this.INNER()</code>, which then calls the 'augment' modifier in the subclass:</p>

<pre><code> Class('Document', {

Expand All @@ -167,7 +170,7 @@ <h1 id="augment">AUGMENT</h1>
})
</code></pre>

<p>Using <strong>this.INNER()</strong> in this method makes it possible for one or more subclasses to then augment this method with their own specific implementation:</p>
<p>Using <code>this.INNER()</code> in this method makes it possible for one or more subclasses to then augment this method with their own specific implementation:</p>

<pre><code> Class('Report', {
isa : Document,
Expand All @@ -184,15 +187,15 @@ <h1 id="augment">AUGMENT</h1>
})
</code></pre>

<p>When we call 'as_xml' on a Report object, we get something like this:</p>
<p>When we call <code>as_xml</code> on a <code>Report</code> object, we get something like this:</p>

<pre><code> &lt;document&gt;
&lt;report&gt;
&lt;/report&gt;
&lt;/document&gt;
</code></pre>

<p>But we also called <strong>this.INNER()</strong> in Report, so we can continue subclassing and adding more content inside the document:</p>
<p>But we also called <code>this.INNER()</code> in <code>Report</code>, so we can continue subclassing and adding more content inside the document:</p>

<pre><code> Class('Report.IncomeAndExpenses', {
isa : Report,
Expand Down Expand Up @@ -221,10 +224,10 @@ <h1 id="augment">AUGMENT</h1>
&lt;/document&gt;
</code></pre>

<p>What makes this combination of 'augment' and <strong>this.INNER()</strong> special is that it allows us to have methods which are called from parent (least specific) to child (most specific). This inverts the normal inheritance pattern.</p>
<p>What makes this combination of <code>augment</code> and <code>this.INNER()</code> special is that it allows us to have methods which are called from parent (least specific) to child (most specific). This inverts the normal inheritance pattern.</p>

<p>Note that in Report.IncomeAndExpenses we call <strong>this.INNER()</strong> again. If the object is an instance of Report.IncomeAndExpenses then this call is a no-op, and just returns false.
However, if later we will decide to further subclass the Report.IncomeAndExpenses, than its 'as_xml' will still include the content, provided by subclass.</p>
<p>Note that in <code>Report.IncomeAndExpenses</code> we call <code>this.INNER()</code> again. If the object is an instance of <code>Report.IncomeAndExpenses</code> then this call is a no-op, and just returns <code>undefined</code>.
However, if later we will decide to further subclass the <code>Report.IncomeAndExpenses</code>, than its <code>as_xml</code> will still include the content, provided by subclass.</p>

<h1 id="author">AUTHOR</h1>

Expand Down

0 comments on commit 7e617a6

Please sign in to comment.