mirror of
https://github.com/wren-lang/wren.git
synced 2026-01-12 14:48:40 +01:00
649 lines
42 KiB
HTML
649 lines
42 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='//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="./">wren</a></h1>
|
|
<h2>a classy little scripting language</h2>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
<div class="page">
|
|
<nav class="big">
|
|
<a href="./"><img src="./wren.svg" class="logo"></a>
|
|
<ul>
|
|
<li><a href="getting-started.html">Getting Started</a></li>
|
|
<li><a href="contributing.html">Contributing</a></li>
|
|
<li><a href="blog">Blog</a></li>
|
|
</ul>
|
|
<section>
|
|
<h2>guides</h2>
|
|
<ul>
|
|
<li><a href="syntax.html">Syntax</a></li>
|
|
<li><a href="values.html">Values</a></li>
|
|
<li><a href="lists.html">Lists</a></li>
|
|
<li><a href="maps.html">Maps</a></li>
|
|
<li><a href="method-calls.html">Method Calls</a></li>
|
|
<li><a href="control-flow.html">Control Flow</a></li>
|
|
<li><a href="variables.html">Variables</a></li>
|
|
<li><a href="functions.html">Functions</a></li>
|
|
<li><a href="classes.html">Classes</a></li>
|
|
<li><a href="concurrency.html">Concurrency</a></li>
|
|
<li><a href="error-handling.html">Error Handling</a></li>
|
|
<li><a href="modularity.html">Modularity</a></li>
|
|
</ul>
|
|
</section>
|
|
<section>
|
|
<h2>reference</h2>
|
|
<ul>
|
|
<li><a href="modules">Modules</a></li>
|
|
<li><a href="embedding">Embedding</a></li>
|
|
<li><a href="performance.html">Performance</a></li>
|
|
<li><a href="qa.html">Q & A</a></li>
|
|
</ul>
|
|
</section>
|
|
</nav>
|
|
<nav class="small">
|
|
<table>
|
|
<tr>
|
|
<div><a href="getting-started.html">Getting Started</a></div>
|
|
<div><a href="contributing.html">Contributing</a></div>
|
|
<div><a href="blog">Blog</a></div>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="2"><h2>guides</h2></td>
|
|
<td><h2>reference</h2></td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
<ul>
|
|
<li><a href="syntax.html">Syntax</a></li>
|
|
<li><a href="values.html">Values</a></li>
|
|
<li><a href="lists.html">Lists</a></li>
|
|
<li><a href="maps.html">Maps</a></li>
|
|
<li><a href="method-calls.html">Method Calls</a></li>
|
|
<li><a href="control-flow.html">Control Flow</a></li>
|
|
</ul>
|
|
</td>
|
|
<td>
|
|
<ul>
|
|
<li><a href="variables.html">Variables</a></li>
|
|
<li><a href="functions.html">Functions</a></li>
|
|
<li><a href="classes.html">Classes</a></li>
|
|
<li><a href="concurrency.html">Concurrency</a></li>
|
|
<li><a href="error-handling.html">Error Handling</a></li>
|
|
<li><a href="modularity.html">Modularity</a></li>
|
|
</ul>
|
|
</td>
|
|
<td>
|
|
<ul>
|
|
<li><a href="modules">Modules</a></li>
|
|
<li><a href="embedding">Embedding</a></li>
|
|
<li><a href="performance.html">Performance</a></li>
|
|
<li><a href="qa.html">Q & A</a></li>
|
|
</ul>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</nav>
|
|
<main>
|
|
<h2>Classes</h2>
|
|
<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
|
|
<a href="modules/core/bool.html">Bool</a> class. </p>
|
|
<p>Classes define an objects <em>behavior</em> and <em>state</em>. Behavior is defined by
|
|
<a href="method-calls.html"><em>methods</em></a> which live in the class. Every object of the same
|
|
class supports the same methods. 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="k">class</span> <span class="vg">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="k">class</span> <span class="vg">Unicorn</span> <span class="p">{</span>
|
|
<span class="n">prance</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="vg">System</span><span class="o">.</span><span class="n">print</span><span class="p">(</span><span class="s">"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 add parameters, put
|
|
their names inside the parentheses: </p>
|
|
<div class="codehilite"><pre><span class="k">class</span> <span class="vg">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="vg">System</span><span class="o">.</span><span class="n">print</span><span class="p">(</span><span class="s">"The unicorn prances in </span><span class="si">%(</span><span class="n">where</span><span class="si">)</span><span class="s"> at </span><span class="si">%(</span><span class="n">when</span><span class="si">)</span><span class="s">."</span><span class="p">)</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
</pre></div>
|
|
|
|
|
|
<p>Since the number of parameters is part of a method’s <a href="method-calls.html#signature">signature</a> a class can
|
|
define multiple methods with the same name: </p>
|
|
<div class="codehilite"><pre><span class="k">class</span> <span class="vg">Unicorn</span> <span class="p">{</span>
|
|
<span class="n">prance</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="vg">System</span><span class="o">.</span><span class="n">print</span><span class="p">(</span><span class="s">"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="vg">System</span><span class="o">.</span><span class="n">print</span><span class="p">(</span><span class="s">"The unicorn prances in </span><span class="si">%(</span><span class="n">where</span><span class="si">)</span><span class="s">."</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="vg">System</span><span class="o">.</span><span class="n">print</span><span class="p">(</span><span class="s">"The unicorn prances in </span><span class="si">%(</span><span class="n">where</span><span class="si">)</span><span class="s"> at </span><span class="si">%(</span><span class="n">when</span><span class="si">)</span><span class="s">."</span><span class="p">)</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
</pre></div>
|
|
|
|
|
|
<p>It’s often natural to have the same conceptual operation work with different
|
|
sets of arguments. In other languages, you’d define a single method for the
|
|
operation and have to check for missing optional arguments. In Wren, they are
|
|
different methods that you implement separately. </p>
|
|
<p>In addition to named methods with parameter lists, Wren has a bunch of other
|
|
different syntaxes for methods. Your classes can define all of them. </p>
|
|
<h3>Getters <a href="#getters" name="getters" class="header-anchor">#</a></h3>
|
|
<p>A getter leaves off the parameter list and the parentheses: </p>
|
|
<div class="codehilite"><pre><span class="k">class</span> <span class="vg">Unicorn</span> <span class="p">{</span>
|
|
<span class="c1">// Unicorns are always fancy.</span>
|
|
<span class="n">isFancy</span> <span class="p">{</span> <span class="kc">true</span> <span class="p">}</span>
|
|
<span class="p">}</span>
|
|
</pre></div>
|
|
|
|
|
|
<h3>Setters <a href="#setters" name="setters" class="header-anchor">#</a></h3>
|
|
<p>A setter has <code>=</code> after the name, followed by a single parenthesized parameter: </p>
|
|
<div class="codehilite"><pre><span class="k">class</span> <span class="vg">Unicorn</span> <span class="p">{</span>
|
|
<span class="n">rider</span><span class="o">=</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="vg">System</span><span class="o">.</span><span class="n">print</span><span class="p">(</span><span class="s">"I am being ridden by </span><span class="si">%(</span><span class="n">value</span><span class="si">)</span><span class="s">."</span><span class="p">)</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
</pre></div>
|
|
|
|
|
|
<p>By convention, the parameter is usually named <code>value</code> but you can call it
|
|
whatever makes your heart flutter. </p>
|
|
<h3>Operators <a href="#operators" name="operators" class="header-anchor">#</a></h3>
|
|
<p>Prefix operators, like getters, have no parameter list: </p>
|
|
<div class="codehilite"><pre><span class="k">class</span> <span class="vg">Unicorn</span> <span class="p">{</span>
|
|
<span class="o">-</span> <span class="p">{</span>
|
|
<span class="vg">System</span><span class="o">.</span><span class="n">print</span><span class="p">(</span><span class="s">"Negating a unicorn is weird."</span><span class="p">)</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
</pre></div>
|
|
|
|
|
|
<p>Infix operators, like setters, have a single parenthesized parameter for the
|
|
right-hand operand: </p>
|
|
<div class="codehilite"><pre><span class="k">class</span> <span class="vg">Unicorn</span> <span class="p">{</span>
|
|
<span class="o">-</span><span class="p">(</span><span class="n">other</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="vg">System</span><span class="o">.</span><span class="n">print</span><span class="p">(</span><span class="s">"Subtracting </span><span class="si">%(</span><span class="n">other</span><span class="si">)</span><span class="s"> from a unicorn is weird."</span><span class="p">)</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
</pre></div>
|
|
|
|
|
|
<p>A subscript operator puts the parameters inside square brackets and can have
|
|
more than one: </p>
|
|
<div class="codehilite"><pre><span class="k">class</span> <span class="vg">Unicorn</span> <span class="p">{</span>
|
|
<span class="p">[</span><span class="n">index</span><span class="p">]</span> <span class="p">{</span>
|
|
<span class="vg">System</span><span class="o">.</span><span class="n">print</span><span class="p">(</span><span class="s">"Unicorns are not lists!"</span><span class="p">)</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="p">[</span><span class="err">x</span><span class="p">,</span> <span class="err">y</span><span class="p">]</span> <span class="p">{</span>
|
|
<span class="vg">System</span><span class="o">.</span><span class="n">print</span><span class="p">(</span><span class="s">"Unicorns are not matrices either!"</span><span class="p">)</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
</pre></div>
|
|
|
|
|
|
<p>Unlike with named methods, you can’t define a subscript operator with an empty
|
|
parameter list. </p>
|
|
<p>As the name implies, a subscript setter looks like a combination of a subscript
|
|
operator and a setter: </p>
|
|
<div class="codehilite"><pre><span class="k">class</span> <span class="vg">Unicorn</span> <span class="p">{</span>
|
|
<span class="p">[</span><span class="n">index</span><span class="p">]</span><span class="o">=</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="vg">System</span><span class="o">.</span><span class="n">print</span><span class="p">(</span><span class="s">"You can't stuff </span><span class="si">%(</span><span class="n">value</span><span class="si">)</span><span class="s"> into me at </span><span class="si">%(</span><span class="n">index</span><span class="si">)</span><span class="s">!"</span><span class="p">)</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
</pre></div>
|
|
|
|
|
|
<h2>Method Scope <a href="#method-scope" name="method-scope" class="header-anchor">#</a></h2>
|
|
<p>Up to this point, “<a href="variables.html#scope">scope</a>” has been used to talk exclusively about
|
|
<a href="variables.html">variables</a>. In a procedural language like C, or a functional one like Scheme,
|
|
that’s the only kind of scope there is. But object-oriented languages like Wren
|
|
introduce another kind of scope: <em>object scope</em>. It contains the methods that
|
|
are available on an object. When you write: </p>
|
|
<div class="codehilite"><pre><span class="n">unicorn</span><span class="o">.</span><span class="n">isFancy</span>
|
|
</pre></div>
|
|
|
|
|
|
<p>You’re saying “look up the method <code>isFancy</code> in the scope of the object
|
|
<code>unicorn</code>”. In this case, the fact that you want to look up a <em>method</em>
|
|
<code>isFancy</code> and not a <em>variable</em> <code>isFancy</code> is explicit. That’s what <code>.</code> does and
|
|
the object to the left of the period is the object you want to look up the
|
|
method on. </p>
|
|
<h3><code>this</code> <a href="#this" name="this" class="header-anchor">#</a></h3>
|
|
<p>Things get more interesting when you’re inside the body of a method. When the
|
|
method is called on some object and the body is being executed, you often need
|
|
to access that object itself. You can do that using <code>this</code>. </p>
|
|
<div class="codehilite"><pre><span class="k">class</span> <span class="vg">Unicorn</span> <span class="p">{</span>
|
|
<span class="n">name</span> <span class="p">{</span> <span class="s">"Francis"</span> <span class="p">}</span>
|
|
|
|
<span class="n">printName</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="vg">System</span><span class="o">.</span><span class="n">print</span><span class="p">(</span><span class="nb">this</span><span class="o">.</span><span class="n">name</span><span class="p">)</span> <span class="output">Francis</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
</pre></div>
|
|
|
|
|
|
<p>The <code>this</code> keyword works sort of like a variable, but has special behavior. It
|
|
always refers to the instance whose method is currently being executed. This
|
|
lets you invoke methods on “yourself”. </p>
|
|
<p>It’s an error to refer to <code>this</code> outside of a method. However, it’s perfectly
|
|
fine to use it inside a <a href="functions.html">function</a> declared <em>inside</em> a method. When you do,
|
|
<code>this</code> still refers to the instance whose <em>method</em> is being called: </p>
|
|
<div class="codehilite"><pre><span class="k">class</span> <span class="vg">Unicorn</span> <span class="p">{</span>
|
|
<span class="n">name</span> <span class="p">{</span> <span class="s">"Francis"</span> <span class="p">}</span>
|
|
|
|
<span class="n">printNameThrice</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="p">(</span><span class="mi">1</span><span class="o">..</span><span class="mi">3</span><span class="p">)</span><span class="o">.</span><span class="n">each</span> <span class="p">{</span>
|
|
<span class="c1">// Use "this" inside the function passed to each().</span>
|
|
<span class="vg">System</span><span class="o">.</span><span class="n">print</span><span class="p">(</span><span class="nb">this</span><span class="o">.</span><span class="n">name</span><span class="p">)</span> <span class="output">Francis</span>
|
|
<span class="p">}</span> <span class="output">Francis</span>
|
|
<span class="p">}</span> <span class="output">Francis</span>
|
|
<span class="p">}</span>
|
|
</pre></div>
|
|
|
|
|
|
<p>This is unlike Lua and JavaScript which can “forget” <code>this</code> when you create a
|
|
callback inside a method. Wren does what you want here and retains the
|
|
reference to the original object. </p>
|
|
<p>(In technical terms, a function’s closure includes <code>this</code>. Wren can do this
|
|
because it makes a distinction between methods and functions.) </p>
|
|
<h3>Implicit <code>this</code> <a href="#implicit-this" name="implicit-this" class="header-anchor">#</a></h3>
|
|
<p>Using <code>this.</code> every time you want to call a method on yourself works, but it’s
|
|
tedious and verbose, which is why some languages don’t require it. You can do a
|
|
“self send” by calling a method (or getter or setter) without any explicit
|
|
receiver: </p>
|
|
<div class="codehilite"><pre><span class="k">class</span> <span class="vg">Unicorn</span> <span class="p">{</span>
|
|
<span class="n">name</span> <span class="p">{</span> <span class="s">"Francis"</span> <span class="p">}</span>
|
|
|
|
<span class="n">printName</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="vg">System</span><span class="o">.</span><span class="n">print</span><span class="p">(</span><span class="n">name</span><span class="p">)</span> <span class="output">Francis</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
</pre></div>
|
|
|
|
|
|
<p>Code like this gets tricky when there is also a variable outside of the class
|
|
with the same name. Consider: </p>
|
|
<div class="codehilite"><pre><span class="k">var</span> <span class="n">name</span> <span class="o">=</span> <span class="s">"variable"</span>
|
|
|
|
<span class="k">class</span> <span class="vg">Unicorn</span> <span class="p">{</span>
|
|
<span class="n">name</span> <span class="p">{</span> <span class="s">"Francis"</span> <span class="p">}</span>
|
|
|
|
<span class="n">printName</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="vg">System</span><span class="o">.</span><span class="n">print</span><span class="p">(</span><span class="n">name</span><span class="p">)</span> <span class="c1">// ???</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
</pre></div>
|
|
|
|
|
|
<p>Should <code>printName()</code> print “variable” or “Francis”? A method body has a foot in
|
|
each of two worlds. It is surrounded by the lexical scope where it’s defined in
|
|
the program, but it also has the object scope of the methods on <code>this</code>. </p>
|
|
<p>Which scope wins? Every language has to decide how to handle this and there
|
|
is a surprising plethora of approaches. Wren’s approach to resolving a name
|
|
inside a method works like this: </p>
|
|
<ol>
|
|
<li>If there is a local variable inside the method with that name, that wins. </li>
|
|
<li>Else, if the name starts with a lowercase letter, treat it like a method on
|
|
<code>this</code>. </li>
|
|
<li>Otherwise, look for a variable with that name in the surrounding scope. </li>
|
|
</ol>
|
|
<p>So, in the above example, we hit case #2 and it prints “Francis”. Distinguishing
|
|
self sends from outer variables based on the <em>case</em> of the first letter in the
|
|
name probably seems crazy but it works surprisingly well. Method names are
|
|
lowercase in Wren. Class names are capitalized. </p>
|
|
<p>Most of the time, when you’re in a method and want to access a name from outside
|
|
of the class, it’s usually the name of some other class. This rule makes that
|
|
work. </p>
|
|
<p>Here’s an example that shows all three cases: </p>
|
|
<div class="codehilite"><pre><span class="k">var</span> <span class="n">shadowed</span> <span class="o">=</span> <span class="s">"surrounding"</span>
|
|
<span class="k">var</span> <span class="n">lowercase</span> <span class="o">=</span> <span class="s">"surrounding"</span>
|
|
<span class="k">var</span> <span class="vg">Capitalized</span> <span class="o">=</span> <span class="s">"surrounding"</span>
|
|
|
|
<span class="k">class</span> <span class="vg">Scope</span> <span class="p">{</span>
|
|
<span class="n">shadowed</span> <span class="p">{</span> <span class="s">"object"</span> <span class="p">}</span>
|
|
<span class="n">lowercase</span> <span class="p">{</span> <span class="s">"object"</span> <span class="p">}</span>
|
|
<span class="vg">Capitalized</span> <span class="p">{</span> <span class="s">"object"</span> <span class="p">}</span>
|
|
|
|
<span class="n">test</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="k">var</span> <span class="n">shadowed</span> <span class="o">=</span> <span class="s">"local"</span>
|
|
|
|
<span class="vg">System</span><span class="o">.</span><span class="n">print</span><span class="p">(</span><span class="n">shadowed</span><span class="p">)</span> <span class="output">local</span>
|
|
<span class="vg">System</span><span class="o">.</span><span class="n">print</span><span class="p">(</span><span class="n">lowercase</span><span class="p">)</span> <span class="output">object</span>
|
|
<span class="vg">System</span><span class="o">.</span><span class="n">print</span><span class="p">(</span><span class="vg">Capitalized</span><span class="p">)</span> <span class="output">surrounding</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
</pre></div>
|
|
|
|
|
|
<p>It’s a bit of a strange rule, but Ruby works more or less the same way. </p>
|
|
<h2>Constructors <a href="#constructors" name="constructors" class="header-anchor">#</a></h2>
|
|
<p>We’ve seen how to define kinds of objects and how to declare methods on them.
|
|
Our unicorns can prance around, but we don’t actually <em>have</em> any unicorns to do
|
|
it. To create <em>instances</em> of a class, we need a <em>constructor</em>. You define one
|
|
like so: </p>
|
|
<div class="codehilite"><pre><span class="k">class</span> <span class="vg">Unicorn</span> <span class="p">{</span>
|
|
<span class="k">construct</span> <span class="n">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="vg">System</span><span class="o">.</span><span class="n">print</span><span class="p">(</span><span class="s">"My name is "</span> <span class="o">+</span> <span class="n">name</span> <span class="o">+</span> <span class="s">" and I am "</span> <span class="o">+</span> <span class="n">color</span> <span class="o">+</span> <span class="s">"."</span><span class="p">)</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
</pre></div>
|
|
|
|
|
|
<p>The <code>construct</code> keyword says we’re defining a constructor, and <code>new</code> is its
|
|
name. In Wren, all constructors have names. The word “new” isn’t special to
|
|
Wren, it’s just a common constructor name. </p>
|
|
<p>To make a unicorn now, we call the constructor method on the class itself: </p>
|
|
<div class="codehilite"><pre><span class="k">var</span> <span class="n">fred</span> <span class="o">=</span> <span class="vg">Unicorn</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s">"Fred"</span><span class="p">,</span> <span class="s">"palomino"</span><span class="p">)</span>
|
|
</pre></div>
|
|
|
|
|
|
<p>Giving constructors names is handy because it means you can have more than one,
|
|
and each can clarify how it creates the instance: </p>
|
|
<div class="codehilite"><pre><span class="k">class</span> <span class="vg">Unicorn</span> <span class="p">{</span>
|
|
<span class="k">construct</span> <span class="n">brown</span><span class="p">(</span><span class="n">name</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="vg">System</span><span class="o">.</span><span class="n">print</span><span class="p">(</span><span class="s">"My name is "</span> <span class="o">+</span> <span class="n">name</span> <span class="o">+</span> <span class="s">" and I am brown."</span><span class="p">)</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="k">var</span> <span class="n">dave</span> <span class="o">=</span> <span class="vg">Unicorn</span><span class="o">.</span><span class="n">brown</span><span class="p">(</span><span class="s">"Dave"</span><span class="p">)</span>
|
|
</pre></div>
|
|
|
|
|
|
<p>Note that we have to declare a constructor because, unlike some other
|
|
languages, Wren doesn’t give you a default one. This is useful because some
|
|
classes aren’t designed to be constructed. If you have an abstract base class
|
|
that just contains methods to be inherited by other classes, it doesn’t need
|
|
and won’t have a constructor. </p>
|
|
<p>Like other methods, constructors can obviously have arguments, and can be
|
|
overloaded by <a href="#signature">arity</a>. A constructor <em>must</em> be a named method with
|
|
a (possibly empty) argument list. Operators, getters, and setters cannot be
|
|
constructors. </p>
|
|
<p>A constructor is actually a pair of methods. You get a method on the class: </p>
|
|
<div class="codehilite"><pre><span class="vg">Unicorn</span><span class="o">.</span><span class="n">brown</span><span class="p">(</span><span class="s">"Dave"</span><span class="p">)</span>
|
|
</pre></div>
|
|
|
|
|
|
<p>That creates the new instance, then it invokes the <em>initializer</em> on that
|
|
instance. This is where the constructor body you defined gets run. </p>
|
|
<p>This distinction is important because it means inside the body of the
|
|
constructor, you can access <code>this</code>, assign <a href="#fields">fields</a>, call superclass
|
|
constructors, etc. </p>
|
|
<h2>Fields <a href="#fields" name="fields" class="header-anchor">#</a></h2>
|
|
<p>All state stored in instances is stored in <em>fields</em>. Each field has a name
|
|
that starts with an underscore. </p>
|
|
<div class="codehilite"><pre><span class="k">class</span> <span class="vg">Rectangle</span> <span class="p">{</span>
|
|
<span class="n">area</span> <span class="p">{</span> <span class="vi">_width</span> <span class="o">*</span> <span class="vi">_height</span> <span class="p">}</span>
|
|
|
|
<span class="c1">// Other stuff...</span>
|
|
<span class="p">}</span>
|
|
</pre></div>
|
|
|
|
|
|
<p>Here, <code>_width</code> and <code>_height</code> in the <code>area</code> <a href="classes.html#methods">getter</a> refer
|
|
to fields on the rectangle instance. You can think of them like <code>this.width</code>
|
|
and <code>this.height</code> in other languages. </p>
|
|
<p>When a field name appears, Wren looks for the nearest enclosing class and looks
|
|
up the field on the instance of that class. Field names cannot be used outside
|
|
of an instance method. They <em>can</em> be used inside a <a href="functions.html">function</a>
|
|
in a method. Wren will look outside any nested functions until it finds an
|
|
enclosing method. </p>
|
|
<p>Unlike <a href="variables.html">variables</a>, fields are implicitly declared by simply
|
|
assigning to them. If you access a field before it has been initialized, its
|
|
value is <code>null</code>. </p>
|
|
<h3>Encapsulation <a href="#encapsulation" name="encapsulation" class="header-anchor">#</a></h3>
|
|
<p>All fields are <em>private</em> in Wren—an object’s fields can only be directly
|
|
accessed from within methods defined on the object’s class. </p>
|
|
<p>In short, if you want to make a property of an object visible,
|
|
<strong>you need to define a getter to expose it</strong>: </p>
|
|
<div class="codehilite"><pre><span class="k">class</span> <span class="vg">Rectangle</span> <span class="p">{</span>
|
|
<span class="n">width</span> <span class="p">{</span> <span class="vi">_width</span> <span class="p">}</span>
|
|
<span class="n">height</span> <span class="p">{</span> <span class="vi">_height</span> <span class="p">}</span>
|
|
|
|
<span class="c1">// ...</span>
|
|
<span class="p">}</span>
|
|
</pre></div>
|
|
|
|
|
|
<p>To allow outside code to modify the field,
|
|
<strong>you need to provide setters to provide access</strong>: </p>
|
|
<div class="codehilite"><pre><span class="k">class</span> <span class="vg">Rectangle</span> <span class="p">{</span>
|
|
<span class="n">width</span><span class="o">=</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> <span class="p">{</span> <span class="vi">_width</span> <span class="o">=</span> <span class="n">value</span> <span class="p">}</span>
|
|
<span class="n">height</span><span class="o">=</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> <span class="p">{</span> <span class="vi">_height</span> <span class="o">=</span> <span class="n">value</span> <span class="p">}</span>
|
|
<span class="p">}</span>
|
|
</pre></div>
|
|
|
|
|
|
<p>This might be different from what you’re used to, so here are two important facts: </p>
|
|
<ul>
|
|
<li>You can’t access fields from a base class. </li>
|
|
<li>You can’t access fields on another instance of your own class. </li>
|
|
</ul>
|
|
<p>Here is an example in code: </p>
|
|
<div class="codehilite"><pre><span class="k">class</span> <span class="vg">Shape</span> <span class="p">{</span>
|
|
<span class="k">construct</span> <span class="n">new</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="vi">_shape</span> <span class="o">=</span> <span class="s">"none"</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="k">class</span> <span class="vg">Rectangle</span> <span class="k">is</span> <span class="vg">Shape</span> <span class="p">{</span>
|
|
<span class="k">construct</span> <span class="n">new</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="c1">//This will print null!</span>
|
|
<span class="c1">//_shape from the parent class is private,</span>
|
|
<span class="c1">//we are reading `_shape` from `this`,</span>
|
|
<span class="c1">//which has not been set, so returns null.</span>
|
|
<span class="vg">System</span><span class="o">.</span><span class="n">print</span><span class="p">(</span><span class="s">"I am a </span><span class="si">%(</span><span class="vi">_shape</span><span class="si">)</span><span class="s">"</span><span class="p">)</span>
|
|
|
|
<span class="c1">//a local variable, all variables are private</span>
|
|
<span class="vi">_width</span> <span class="o">=</span> <span class="mi">10</span>
|
|
<span class="k">var</span> <span class="n">other</span> <span class="o">=</span> <span class="vg">Rectangle</span><span class="o">.</span><span class="n">new</span><span class="p">()</span>
|
|
|
|
<span class="c1">//other._width is not accessible from here,</span>
|
|
<span class="c1">//even though we are also a rectangle. The field</span>
|
|
<span class="c1">//is private, and other._width is invalid syntax!</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
<span class="o">...</span>
|
|
</pre></div>
|
|
|
|
|
|
<p>One thing we’ve learned in the past forty years of software engineering is that
|
|
encapsulating state tends to make code easier to maintain, so Wren defaults to
|
|
keeping your object’s state pretty tightly bundled up. Don’t feel that you have
|
|
to or even should define getters or setters for most of your object’s fields. </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>
|
|
<h3>Static fields <a href="#static-fields" name="static-fields" class="header-anchor">#</a></h3>
|
|
<p>A name that starts with <em>two</em> underscores is a <em>static</em> field. They work
|
|
similar to <a href="#fields">fields</a> except the data is stored on the class itself, and
|
|
not the instance. They can be used in <em>both</em> instance and static methods. </p>
|
|
<div class="codehilite"><pre><span class="k">class</span> <span class="vg">Foo</span> <span class="p">{</span>
|
|
<span class="k">construct</span> <span class="n">new</span><span class="p">()</span> <span class="p">{}</span>
|
|
|
|
<span class="k">static</span> <span class="n">setFromStatic</span><span class="p">(</span><span class="err">a</span><span class="p">)</span> <span class="p">{</span> <span class="vc">__a</span> <span class="o">=</span> <span class="err">a</span> <span class="p">}</span>
|
|
<span class="n">setFromInstance</span><span class="p">(</span><span class="err">a</span><span class="p">)</span> <span class="p">{</span> <span class="vc">__a</span> <span class="o">=</span> <span class="err">a</span> <span class="p">}</span>
|
|
|
|
<span class="k">static</span> <span class="n">printFromStatic</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="vg">System</span><span class="o">.</span><span class="n">print</span><span class="p">(</span><span class="vc">__a</span><span class="p">)</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="n">printFromInstance</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="vg">System</span><span class="o">.</span><span class="n">print</span><span class="p">(</span><span class="vc">__a</span><span class="p">)</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
</pre></div>
|
|
|
|
|
|
<p>Just like instance fields, static fields are initially <code>null</code>: </p>
|
|
<div class="codehilite"><pre><span class="vg">Foo</span><span class="o">.</span><span class="n">printFromStatic</span><span class="p">()</span> <span class="output">null</span>
|
|
</pre></div>
|
|
|
|
|
|
<p>They can be used from static methods: </p>
|
|
<div class="codehilite"><pre><span class="vg">Foo</span><span class="o">.</span><span class="n">setFromStatic</span><span class="p">(</span><span class="s">"first"</span><span class="p">)</span>
|
|
<span class="vg">Foo</span><span class="o">.</span><span class="n">printFromStatic</span><span class="p">()</span> <span class="output">first</span>
|
|
</pre></div>
|
|
|
|
|
|
<p>And also instance methods. When you do so, there is still only one static field
|
|
shared among all instances of the class: </p>
|
|
<div class="codehilite"><pre><span class="k">var</span> <span class="n">foo1</span> <span class="o">=</span> <span class="vg">Foo</span><span class="o">.</span><span class="n">new</span><span class="p">()</span>
|
|
<span class="k">var</span> <span class="n">foo2</span> <span class="o">=</span> <span class="vg">Foo</span><span class="o">.</span><span class="n">new</span><span class="p">()</span>
|
|
|
|
<span class="n">foo1</span><span class="o">.</span><span class="n">setFromInstance</span><span class="p">(</span><span class="s">"second"</span><span class="p">)</span>
|
|
<span class="n">foo2</span><span class="o">.</span><span class="n">printFromInstance</span><span class="p">()</span> <span class="output">second</span>
|
|
</pre></div>
|
|
|
|
|
|
<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 Object, 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="k">class</span> <span class="vg">Pegasus</span> <span class="k">is</span> <span class="vg">Unicorn</span> <span class="p">{}</span>
|
|
</pre></div>
|
|
|
|
|
|
<p>This declares a new class Pegasus that inherits from Unicorn. </p>
|
|
<p>Note that you should not create classes that inherit from the built-in types
|
|
(Bool, Num, String, Range, List). The built-in types expect their internal bit
|
|
representation to be very specific and get horribly confused when you invoke one
|
|
of the inherited built-in methods on the derived type. </p>
|
|
<p>The metaclass hierarchy does <em>not</em> parallel the regular class hierarchy. So, if
|
|
Pegasus inherits from Unicorn, Pegasus’s metaclass does not inherit from
|
|
Unicorn’s metaclass. In more prosaic terms, this means that static methods are
|
|
not inherited. </p>
|
|
<div class="codehilite"><pre><span class="k">class</span> <span class="vg">Unicorn</span> <span class="p">{</span>
|
|
<span class="c1">// Unicorns cannot fly. :(</span>
|
|
<span class="k">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="k">class</span> <span class="vg">Pegasus</span> <span class="k">is</span> <span class="vg">Unicorn</span> <span class="p">{}</span>
|
|
|
|
<span class="vg">Pegasus</span><span class="o">.</span><span class="n">canFly</span> <span class="error">Static methods are not inherited.</span>
|
|
</pre></div>
|
|
|
|
|
|
<p>This also means constructors are not inherited: </p>
|
|
<div class="codehilite"><pre><span class="k">class</span> <span class="vg">Unicorn</span> <span class="p">{</span>
|
|
<span class="k">construct</span> <span class="n">new</span><span class="p">(</span><span class="n">name</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="vg">System</span><span class="o">.</span><span class="n">print</span><span class="p">(</span><span class="s">"My name is "</span> <span class="o">+</span> <span class="n">name</span> <span class="o">+</span> <span class="s">"."</span><span class="p">)</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="k">class</span> <span class="vg">Pegasus</span> <span class="k">is</span> <span class="vg">Unicorn</span> <span class="p">{}</span>
|
|
|
|
<span class="vg">Pegasus</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s">"Fred"</span><span class="p">)</span> <span class="error">Pegasus does not define new().</span>
|
|
</pre></div>
|
|
|
|
|
|
<p>Each class gets to control how it may be constructed independently of its base
|
|
classes. However, constructor <em>initializers</em> are inherited since those are
|
|
instance methods on the new object. </p>
|
|
<p>This means you can do <code>super</code> calls inside a constructor: </p>
|
|
<div class="codehilite"><pre><span class="k">class</span> <span class="vg">Unicorn</span> <span class="p">{</span>
|
|
<span class="k">construct</span> <span class="n">new</span><span class="p">(</span><span class="n">name</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="vg">System</span><span class="o">.</span><span class="n">print</span><span class="p">(</span><span class="s">"My name is "</span> <span class="o">+</span> <span class="n">name</span> <span class="o">+</span> <span class="s">"."</span><span class="p">)</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="k">class</span> <span class="vg">Pegasus</span> <span class="k">is</span> <span class="vg">Unicorn</span> <span class="p">{</span>
|
|
<span class="k">construct</span> <span class="n">new</span><span class="p">(</span><span class="n">name</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">super</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="vg">Pegasus</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s">"Fred"</span><span class="p">)</span> <span class="output">My name is Fred</span>
|
|
</pre></div>
|
|
|
|
|
|
<h2>Super <a href="#super" name="super" class="header-anchor">#</a></h2>
|
|
<p><strong>TODO: Integrate better into page. Should explain this before mentioning
|
|
super above.</strong> </p>
|
|
<p>Sometimes you want to invoke a method on yourself, but using methods defined in
|
|
one of your <a href="classes.html#inheritance">superclasses</a>. You typically do this in
|
|
an overridden method when you want to access the original method being
|
|
overridden. </p>
|
|
<p>To do that, you can use the special <code>super</code> keyword as the receiver in a method
|
|
call: </p>
|
|
<div class="codehilite"><pre><span class="k">class</span> <span class="vg">Base</span> <span class="p">{</span>
|
|
<span class="n">method</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="vg">System</span><span class="o">.</span><span class="n">print</span><span class="p">(</span><span class="s">"base method"</span><span class="p">)</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="k">class</span> <span class="vg">Derived</span> <span class="k">is</span> <span class="vg">Base</span> <span class="p">{</span>
|
|
<span class="n">method</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="k">super</span><span class="o">.</span><span class="n">method</span><span class="p">()</span> <span class="output">base method</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
</pre></div>
|
|
|
|
|
|
<p>You can also use <code>super</code> without a method name inside a constructor to invoke a
|
|
base class constructor: </p>
|
|
<div class="codehilite"><pre><span class="k">class</span> <span class="vg">Base</span> <span class="p">{</span>
|
|
<span class="k">construct</span> <span class="n">new</span><span class="p">(</span><span class="n">arg</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="vg">System</span><span class="o">.</span><span class="n">print</span><span class="p">(</span><span class="s">"base got "</span> <span class="o">+</span> <span class="n">arg</span><span class="p">)</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="k">class</span> <span class="vg">Derived</span> <span class="k">is</span> <span class="vg">Base</span> <span class="p">{</span>
|
|
<span class="k">construct</span> <span class="n">new</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="k">super</span><span class="p">(</span><span class="s">"value"</span><span class="p">)</span> <span class="output">base got value</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
</pre></div>
|
|
|
|
|
|
<p><br><hr>
|
|
<a class="right" href="concurrency.html">Concurrency →</a>
|
|
<a href="functions.html">← Functions</a> </p>
|
|
</main>
|
|
</div>
|
|
<footer>
|
|
<div class="page">
|
|
<div class="main-column">
|
|
<p>Wren lives
|
|
<a href="https://github.com/wren-lang/wren">on GitHub</a>
|
|
— Made with ❤ by
|
|
<a href="http://journal.stuffwithstuff.com/">Bob Nystrom</a> and
|
|
<a href="https://github.com/wren-lang/wren/blob/master/AUTHORS">friends</a>.
|
|
</p>
|
|
<div class="main-column">
|
|
</div>
|
|
</footer>
|
|
</body>
|
|
</html>
|