mirror of
https://github.com/wren-lang/wren.git
synced 2026-01-12 22:58:40 +01:00
217 lines
14 KiB
HTML
217 lines
14 KiB
HTML
<!DOCTYPE html>
|
||
<html>
|
||
<head>
|
||
<meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
|
||
<title>Classes – Wren</title>
|
||
<link rel="stylesheet" type="text/css" href="style.css" />
|
||
<link href='http://fonts.googleapis.com/css?family=Source+Sans+Pro:400,700,400italic,700italic|Source+Code+Pro:400|Lato:400|Sanchez:400italic,400' rel='stylesheet' type='text/css'>
|
||
<!-- Tell mobile browsers we're optimized for them and they don't need to crop
|
||
the viewport. -->
|
||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
|
||
</head>
|
||
<body id="top">
|
||
<header>
|
||
<div class="page">
|
||
<div class="main-column">
|
||
<h1><a href="index.html">wren</a></h1>
|
||
<h2>a classy little scripting language</h2>
|
||
</div>
|
||
</div>
|
||
</header>
|
||
<div class="page">
|
||
<nav>
|
||
<ul>
|
||
<li><a href="getting-started.html">Getting Started</a></li>
|
||
</ul>
|
||
<section>
|
||
<h2>language</h2>
|
||
<ul>
|
||
<li><a href="syntax.html">Syntax</a></li>
|
||
<li><a href="method-calls.html">Method Calls</a></li>
|
||
<li><a href="variables.html">Variables</a></li>
|
||
<li><a href="branching.html">Branching</a></li>
|
||
<li><a href="looping.html">Looping</a></li>
|
||
<li><a href="error-handling.html">Error Handling</a></li>
|
||
</ul>
|
||
</section>
|
||
<section>
|
||
<h2>types</h2>
|
||
<ul>
|
||
<li><a href="values.html">Values</a></li>
|
||
<li><a href="classes.html">Classes</a></li>
|
||
<li><a href="fibers.html">Fibers</a></li>
|
||
<li><a href="functions.html">Functions</a></li>
|
||
<li><a href="lists.html">Lists</a></li>
|
||
<li><a href="maps.html">Maps</a></li>
|
||
</ul>
|
||
</section>
|
||
<section>
|
||
<h2>reference</h2>
|
||
<ul>
|
||
<li><a href="core-library.html">Core Library</a></li>
|
||
<li><a href="embedding-api.html">Embedding API</a></li>
|
||
<li><a href="performance.html">Performance</a></li>
|
||
<li><a href="contributing.html">Contributing</a></li>
|
||
<li><a href="qa.html">Q & A</a></li>
|
||
</ul>
|
||
</section>
|
||
</nav>
|
||
<main>
|
||
<h1>Classes</h1>
|
||
<p>Every value in Wren is an object, and every object is an instance of a class.
|
||
Even <code>true</code> and <code>false</code> are full-featured objects—instances of the <code>Bool</code> class.</p>
|
||
<p>Classes contain both <em>behavior</em> and <em>state</em>. Behavior is defined in <em>methods</em> which are stored in the class. State is defined in <em>fields</em>, whose values are stored in each instance.</p>
|
||
<h2>Defining a class <a href="#defining-a-class" name="defining-a-class" class="header-anchor">#</a></h2>
|
||
<p>Classes are created using the <code>class</code> keyword, unsurprisingly:</p>
|
||
<div class="codehilite"><pre><span class="kd">class</span> <span class="nc">Unicorn</span> <span class="p">{}</span>
|
||
</pre></div>
|
||
|
||
|
||
<p>This creates a class named <code>Unicorn</code> with no methods or fields.</p>
|
||
<h2>Methods <a href="#methods" name="methods" class="header-anchor">#</a></h2>
|
||
<p>To let our unicorn do stuff, we need to give it methods.</p>
|
||
<div class="codehilite"><pre><span class="kd">class</span> <span class="nc">Unicorn</span> <span class="p">{</span>
|
||
<span class="n">prance</span> <span class="p">{</span>
|
||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"The unicorn prances in a fancy manner!"</span><span class="p">)</span>
|
||
<span class="p">}</span>
|
||
<span class="p">}</span>
|
||
</pre></div>
|
||
|
||
|
||
<p>This defines a <code>prance</code> method that takes no arguments. To support parameters, add a parenthesized parameter list after the method's name:</p>
|
||
<div class="codehilite"><pre><span class="kd">class</span> <span class="nc">Unicorn</span> <span class="p">{</span>
|
||
<span class="n">prance</span><span class="p">(</span><span class="n">where</span><span class="p">,</span> <span class="n">when</span><span class="p">)</span> <span class="p">{</span>
|
||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"The unicorn prances in "</span> <span class="o">+</span> <span class="n">where</span> <span class="o">+</span> <span class="s2">" at "</span> <span class="o">+</span> <span class="n">when</span><span class="p">)</span>
|
||
<span class="p">}</span>
|
||
<span class="p">}</span>
|
||
</pre></div>
|
||
|
||
|
||
<p>Unlike most other dynamically-typed languages, in Wren you can have multiple methods in a class with the same name, as long as they take a different number of parameters. In technical terms, you can <em>overload by arity</em>. So this class is fine:</p>
|
||
<div class="codehilite"><pre><span class="kd">class</span> <span class="nc">Unicorn</span> <span class="p">{</span>
|
||
<span class="n">prance</span> <span class="p">{</span>
|
||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"The unicorn prances in a fancy manner!"</span><span class="p">)</span>
|
||
<span class="p">}</span>
|
||
|
||
<span class="n">prance</span><span class="p">(</span><span class="n">where</span><span class="p">)</span> <span class="p">{</span>
|
||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"The unicorn prances in "</span> <span class="o">+</span> <span class="n">where</span><span class="p">)</span>
|
||
<span class="p">}</span>
|
||
|
||
<span class="n">prance</span><span class="p">(</span><span class="n">where</span><span class="p">,</span> <span class="n">when</span><span class="p">)</span> <span class="p">{</span>
|
||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"The unicorn prances in "</span> <span class="o">+</span> <span class="n">where</span> <span class="o">+</span> <span class="s2">" at "</span> <span class="o">+</span> <span class="n">when</span><span class="p">)</span>
|
||
<span class="p">}</span>
|
||
<span class="p">}</span>
|
||
</pre></div>
|
||
|
||
|
||
<p>When you <a href="method-calls.html">call</a> the <code>prance</code> method, it selects the right one based on how many arguments you pass it.</p>
|
||
<h2>Constructors <a href="#constructors" name="constructors" class="header-anchor">#</a></h2>
|
||
<p>To create a new instance of a class, you use the <code>new</code> keyword. We can make a unicorn like so:</p>
|
||
<div class="codehilite"><pre><span class="k">new</span> <span class="n">Unicorn</span>
|
||
</pre></div>
|
||
|
||
|
||
<p>You almost always want to define some state or do some other initialization on a new object. For that, you'll want to define a constructor, like so:</p>
|
||
<div class="codehilite"><pre><span class="kd">class</span> <span class="nc">Unicorn</span> <span class="p">{</span>
|
||
<span class="k">new</span> <span class="p">{</span>
|
||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"I am a constructor!"</span><span class="p">)</span>
|
||
<span class="p">}</span>
|
||
<span class="p">}</span>
|
||
</pre></div>
|
||
|
||
|
||
<p>When you create an instance with <code>new</code>, its constructor will be invoked. It's just a method with a special name. Like methods, you can pass arguments to the constructor by adding a parenthesized parameter list after <code>new</code>:</p>
|
||
<div class="codehilite"><pre><span class="kd">class</span> <span class="nc">Unicorn</span> <span class="p">{</span>
|
||
<span class="k">new</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">color</span><span class="p">)</span> <span class="p">{</span>
|
||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"My name is "</span> <span class="o">+</span> <span class="n">name</span> <span class="o">+</span> <span class="s2">" and I am "</span> <span class="o">+</span> <span class="n">color</span> <span class="o">+</span> <span class="s2">"."</span><span class="p">)</span>
|
||
<span class="p">}</span>
|
||
<span class="p">}</span>
|
||
</pre></div>
|
||
|
||
|
||
<p>Values are passed to the constructor like so:</p>
|
||
<div class="codehilite"><pre><span class="k">new</span> <span class="n">Unicorn</span><span class="p">(</span><span class="s2">"Flicker"</span><span class="p">,</span> <span class="s2">"purple"</span><span class="p">)</span>
|
||
</pre></div>
|
||
|
||
|
||
<p>Like other methods, you can overload constructors by arity.</p>
|
||
<h2>Operators <a href="#operators" name="operators" class="header-anchor">#</a></h2>
|
||
<p>Operators are just special syntax for regular <a href="method-calls.html">method calls</a> on the left hand operand (or only operand in the case of unary operators like <code>!</code> and <code>~</code>). You can define them like so:</p>
|
||
<div class="codehilite"><pre><span class="kd">class</span> <span class="nc">Unicorn</span> <span class="p">{</span>
|
||
<span class="c1">// Infix:</span>
|
||
<span class="o">+</span><span class="p">(</span><span class="n">other</span><span class="p">)</span> <span class="p">{</span>
|
||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"Adding to a unicorn?"</span><span class="p">)</span>
|
||
<span class="p">}</span>
|
||
|
||
<span class="c1">// Prefix:</span>
|
||
<span class="o">!</span> <span class="p">{</span>
|
||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"Negating a unicorn?!"</span><span class="p">)</span>
|
||
<span class="p">}</span>
|
||
<span class="p">}</span>
|
||
</pre></div>
|
||
|
||
|
||
<p>This can be used to define any of these operators:</p>
|
||
<div class="codehilite"><pre><span class="c1">// Infix:</span>
|
||
<span class="o">+</span> <span class="o">-</span> <span class="o">*</span> <span class="o">/</span> <span class="o">%</span> <span class="o"><</span> <span class="o">></span> <span class="o"><=</span> <span class="o">>=</span> <span class="o">==</span> <span class="o">!=</span> <span class="o">&</span> <span class="o">|</span>
|
||
|
||
<span class="c1">// Prefix:</span>
|
||
<span class="o">!</span> <span class="o">~</span> <span class="o">-</span>
|
||
</pre></div>
|
||
|
||
|
||
<p>Note that <code>-</code> can be both a prefix and infix operator. If there's a parameter list, it's the infix one, otherwise, it's prefix. Since Wren supports overloading by arity, it's no problem for a class to define both.</p>
|
||
<p>Operator overloading is really useful for types like vectors and complex numbers where the reader knows what the operators will do, but can make code deeply confusing if overused. When in doubt, use a real name.</p>
|
||
<h2>Setters <a href="#setters" name="setters" class="header-anchor">#</a></h2>
|
||
<p><strong>TODO: ...</strong></p>
|
||
<h2>Fields <a href="#fields" name="fields" class="header-anchor">#</a></h2>
|
||
<p><strong>TODO</strong></p>
|
||
<h2>Metaclasses and static members <a href="#metaclasses-and-static-members" name="metaclasses-and-static-members" class="header-anchor">#</a></h2>
|
||
<p><strong>TODO</strong></p>
|
||
<h2>Inheritance <a href="#inheritance" name="inheritance" class="header-anchor">#</a></h2>
|
||
<p>A class can inherit from a "parent" or <em>superclass</em>. When you invoke a method on an object of some class, if it can't be found, it walks up the chain of superclasses looking for it there.</p>
|
||
<p>By default, any new class inherits from <code>Object</code>, which is the superclass from which all other classes ultimately descend. You can specify a different parent class using <code>is</code> when you declare the class:</p>
|
||
<div class="codehilite"><pre><span class="kd">class</span> <span class="nc">Pegasus</span> <span class="k">is</span> <span class="n">Unicorn</span> <span class="p">{}</span>
|
||
</pre></div>
|
||
|
||
|
||
<p>This declares a new class <code>Pegasus</code> that inherits from <code>Unicorn</code>.</p>
|
||
<p>The metaclass hierarchy does <em>not</em> parallel the regular class hierarchy. So, if <code>Pegasus</code> inherits from <code>Unicorn</code>, <code>Pegasus</code>'s metaclass will not inherit from <code>Unicorn</code>'s metaclass. In more prosaic terms, this means that static methods are not inherited.</p>
|
||
<div class="codehilite"><pre><span class="kd">class</span> <span class="nc">Unicorn</span> <span class="p">{</span>
|
||
<span class="c1">// Unicorns cannot fly. :(</span>
|
||
<span class="kd">static</span> <span class="n">canFly</span> <span class="p">{</span> <span class="kc">false</span> <span class="p">}</span>
|
||
<span class="p">}</span>
|
||
|
||
<span class="kd">class</span> <span class="nc">Pegasus</span> <span class="k">is</span> <span class="n">Unicorn</span> <span class="p">{}</span>
|
||
|
||
<span class="n">Pegasus</span><span class="p">.</span><span class="n">canFly</span> <span class="c1">// ERROR: Static methods are not inherited.</span>
|
||
</pre></div>
|
||
|
||
|
||
<p>Constructors, however, initialize the instance <em>after</em> it has been created. They are defined as instance methods on the class and not on the metaclass. That means that constructors <em>are</em> inherited.</p>
|
||
<div class="codehilite"><pre><span class="kd">class</span> <span class="nc">Unicorn</span> <span class="p">{</span>
|
||
<span class="k">new</span><span class="p">(</span><span class="n">name</span><span class="p">)</span> <span class="p">{</span>
|
||
<span class="n">IO</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"My name is "</span> <span class="o">+</span> <span class="n">name</span> <span class="o">+</span> <span class="s2">"."</span><span class="p">)</span>
|
||
<span class="p">}</span>
|
||
<span class="p">}</span>
|
||
|
||
<span class="kd">class</span> <span class="nc">Pegasus</span> <span class="k">is</span> <span class="n">Unicorn</span> <span class="p">{}</span>
|
||
|
||
<span class="k">new</span> <span class="n">Pegasus</span><span class="p">(</span><span class="s2">"Fred"</span><span class="p">)</span> <span class="c1">// Prints "My name is Fred.".</span>
|
||
</pre></div>
|
||
|
||
|
||
<h2>Superclass method calls <a href="#superclass-method-calls" name="superclass-method-calls" class="header-anchor">#</a></h2>
|
||
<p><strong>TODO</strong></p>
|
||
<p><strong>TODO: this</strong></p>
|
||
</main>
|
||
</div>
|
||
<footer>
|
||
<div class="page">
|
||
<div class="main-column">
|
||
<p>Wren lives <a href="https://github.com/munificent/wren">on GitHub</a> — Made with ❤ by <a href="http://journal.stuffwithstuff.com/">Bob Nystrom</a>.</p>
|
||
<div class="main-column">
|
||
</div>
|
||
</footer>
|
||
</body>
|
||
</html> |