Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
First stage of examples reworking in Language/ directory
  • Loading branch information
Altai-man committed Feb 2, 2017
1 parent b729c96 commit 9fc71c3
Show file tree
Hide file tree
Showing 27 changed files with 469 additions and 196 deletions.
4 changes: 2 additions & 2 deletions doc/Language/about.pod6
Expand Up @@ -93,7 +93,7 @@ example, often contain the methods the class implements.
Definitions must be in one of the following forms to be recognized as
the start of a documentable named, say, Z. First the code in the document source:
=begin code
=begin code :skip-test
=item X<C<How to use the Z infix> | infix,Z> (This a special case, which
is always considered a definition)
Expand Down Expand Up @@ -131,7 +131,7 @@ You can add emphasis with bold (B<V< B<> >>) or italicized (B<V< I<> >>),
with or without code formatting (B<V< C<> >>). Due to current parser limitations,
special steps have to be taken to use B<V< X<> >> with other formatting codes; for example:
=begin code
=begin code :skip-test
=item X<B<foo>|foo> a fancy subroutine
=end code
Expand Down
69 changes: 47 additions & 22 deletions doc/Language/classtut.pod6
Expand Up @@ -145,7 +145,8 @@ key principles of object oriented design.
The first declaration specifies instance storage for a callback – a bit of
code to invoke in order to perform the task that an object represents:
has &!callback;
=for code :skip-test
has &!callback;
X<|sigils,&>
X<|twigils>
Expand All @@ -158,7 +159,8 @@ this attribute is private to the class.
The second declaration also uses the private twigil:
has Task @!dependencies;
=for code :skip-test
has Task @!dependencies;
However, this attribute represents an array of items, so it requires the
C<@> sigil. These items each specify a task that must be completed before
Expand All @@ -168,7 +170,8 @@ class (or some subclass of it).
The third attribute represents the state of completion of a task:
has Bool $.done;
=for code :skip-test
has Bool $.done;
X<|twigils,.>
X<|twigils,accessors>
Expand Down Expand Up @@ -210,26 +213,27 @@ those with and without accessors):
The assignment is carried out at object build time. The right-hand side is
evaluated at that time, and can even reference earlier attributes:
has Task @!dependencies;
has $.ready = not @!dependencies;
=for code :skip-test
has Task @!dependencies;
has $.ready = not @!dependencies;
=head1 Static fields?
Perl 6 has no B<static> keyword. Nevertheless, any class may declare anything
that a module can, so making a scoped variable sounds like good idea.
=begin code
=begin code
class Singleton {
my Singleton $instance;
method new {!!!}
submethod instance {
$instance = Singleton.bless unless $instance;
$instance;
}
}
class Singleton {
my Singleton $instance;
method new {!!!}
submethod instance {
$instance = Singleton.bless unless $instance;
$instance;
}
}
=end code
=end code
Class attributes defined by L<my|/syntax/my> or L<our|/syntax/our> may also be initialized when
being declared, however we are implementing the Singleton pattern here and
Expand All @@ -238,9 +242,11 @@ predict the moment when attribute initialization will be executed, because
it can take place during compilation, runtime or both, especially when
importing the class using the L<use|/syntax/use> keyword.
=begin code :skip-test
class HaveStaticAttr {
my Foo $.foo = some_complicated_subroutine;
}
=end code
Class attributes may also be declared with a secondary sigil – in a similar
manner to object attributes – that will generate read-only accessors if the
Expand All @@ -256,9 +262,11 @@ ignore the C<new> method temporarily; it's a special type of method.
Consider the second method, C<add-dependency>, which adds a new task to a
task's dependency list.
=begin code :skip-test
method add-dependency(Task $dependency) {
push @!dependencies, $dependency;
}
=end code
X<|invocant>
Expand All @@ -274,13 +282,15 @@ attribute.
The C<perform> method contains the main logic of the dependency handler:
=begin code :skip-test
method perform() {
unless $!done {
.perform() for @!dependencies;
&!callback();
$!done = True;
}
}
=end code
It takes no parameters, working instead with the object's attributes. First,
it checks if the task has already completed by checking the C<$!done>
Expand Down Expand Up @@ -377,7 +387,8 @@ allowed to bind things to C<&!callback> and C<@!dependencies> directly. To
do this, we override the C<BUILD> submethod, which is called on the brand
new object by C<bless>:
submethod BUILD(:&!callback, :@!dependencies) { }
=for code :skip-test
submethod BUILD(:&!callback, :@!dependencies) { }
Since C<BUILD> runs in the context of the newly created C<Task> object, it
is allowed to manipulate those private attributes. The trick here is that
Expand All @@ -389,6 +400,7 @@ more information.
The C<BUILD> method is responsible for initializing all attributes and must also
handle default values:
=begin code :skip-test
has &!callback;
has @!dependencies;
has Bool ($.done, $.ready);
Expand All @@ -398,6 +410,7 @@ handle default values:
:$!done = False,
:$!ready = not @!dependencies
) { }
=end code
See L<Object Construction|/language/objects#Object_Construction> for more
options to influence object construction and attribute initialization.
Expand All @@ -408,7 +421,8 @@ After creating a class, you can create instances of the class. Declaring a
custom constructor provides a simple way of declaring tasks along with their
dependencies. To create a single task with no dependencies, write:
my $eat = Task.new({ say 'eating dinner. NOM!' });
=for code :skip-test
my $eat = Task.new({ say 'eating dinner. NOM!' });
An earlier section explained that declaring the class C<Task> installed a
type object in the namespace. This type object is a kind of "empty
Expand All @@ -419,6 +433,7 @@ modifying or accessing an existing object.
Unfortunately, dinner never magically happens. It has dependent tasks:
=begin code :skip-test
my $eat =
Task.new({ say 'eating dinner. NOM!' },
Task.new({ say 'making dinner' },
Expand All @@ -429,18 +444,21 @@ Unfortunately, dinner never magically happens. It has dependent tasks:
Task.new({ say 'cleaning kitchen' })
)
);
=end code
Notice how the custom constructor and sensible use of whitespace makes task dependencies clear.
Finally, the C<perform> method call recursively calls the C<perform> method
on the various other dependencies in order, giving the output:
=begin code :skip-test
making some money
going to the store
buying food
cleaning kitchen
making dinner
eating dinner. NOM!
=end code
=head1 Inheritance
Expand Down Expand Up @@ -477,7 +495,7 @@ other means, such as attribute accessors.
Now, any object of type Programmer can make use of the methods and accessors
defined in the Employee class as though they were from the Programmer class.
=begin code
=begin code :skip-test
my $programmer = Programmer.new(
salary => 100_000,
known_languages => <Perl5 Perl6 Erlang C++>,
Expand All @@ -494,7 +512,7 @@ Of course, classes can override methods and attributes defined by parent
classes by defining their own. The example below demonstrates the C<Baker>
class overriding the C<Cook>'s C<cook> method.
=begin code
=begin code :skip-test
class Cook is Employee {
has @.utensils is rw;
has @.cookbooks is rw;
Expand Down Expand Up @@ -545,7 +563,7 @@ algorithm to linearize multiple inheritance hierarchies, which is a
significant improvement over Perl 5's default approach
(depth-first search) to handling multiple inheritance.
=begin code
=begin code :skip-test
class GeekCook is Programmer is Cook {
method new( *%params ) {
push( %params<cookbooks>, "Cooking for Geeks" );
Expand Down Expand Up @@ -580,6 +598,7 @@ Classes to be inherited from can be listed in the class declaration body by
prefixing the C<is> trait with C<also>. This also works for the role
composition trait C<does>.
=begin code :skip-test
class GeekCook {
also is Programmer;
also is Cook;
Expand All @@ -589,6 +608,7 @@ composition trait C<does>.
role A {};
role B {};
class C { also does A; also does B }
=end code
=head1 Introspection
Expand All @@ -599,21 +619,25 @@ a controlling object) for some properties, such as its type.
Given an object C<$o> and the class definitions from the previous sections,
we can ask it a few questions:
=begin code :skip-test
if $o ~~ Employee { say "It's an employee" };
if $o ~~ GeekCook { say "It's a geeky cook" };
say $o.WHAT;
say $o.perl;
say $o.^methods(:local)».name.join(', ');
say $o.^name;
=end code
The output can look like this:
=begin code :skip-test
It's an employee
(Programmer)
Programmer.new(known_languages => ["Perl", "Python", "Pascal"],
favorite_editor => "gvim", salary => "too small")
code_to_solve, known_languages, favorite_editor
Programmer
=end code
The first two tests each smart-match against a class name. If the object is
of that class, or of an inheriting class, it returns true. So the object in
Expand All @@ -640,8 +664,9 @@ it is actually a method call on its I<meta class>, which is a class managing
the properties of the C<Programmer> class – or any other class you are
interested in. This meta class enables other ways of introspection too:
say $o.^attributes.join(', ');
say $o.^parents.map({ $_.^name }).join(', ');
=for code :skip-test
say $o.^attributes.join(', ');
say $o.^parents.map({ $_.^name }).join(', ');
Finally C<$o.^name> calls the C<name> method on the meta object, which
unsurprisingly returns the class name.
Expand Down
11 changes: 10 additions & 1 deletion doc/Language/concurrency.pod6
Expand Up @@ -374,11 +374,13 @@ to the C<map> is emitted:
If you need to have an action that runs when the supply finishes, you can do so
by setting the C<done> and C<quit> options in the call to C<tap>:
=begin code :skip-test
$supply.tap: { ... },
done => { say 'Job is done.' },
quit => {
when X::MyApp::Error { say "App Error: ", $_.message }
};
=end code
The C<quit> block works very similar to a C<CATCH>. If the exception is marked
as seen by a C<when> or C<default> block, the exception is caught and handled.
Expand All @@ -390,13 +392,15 @@ If you are using the C<react> or C<supply> block syntax with C<whenever>, you
can add phasers within your C<whenever> blocks to handle the C<done> and C<quit>
messages from the tapped supply:
=begin code :skip-test
react {
whenever $supply {
...; # your usual supply tap code here
LAST { say 'Job is done.' }
QUIT { when X::MyApp::Error { say "App Error: ", $_.message } }
}
}
=end code
The behavior here is the same as setting C<done> and C<quit> on C<tap>.
Expand Down Expand Up @@ -492,6 +496,7 @@ The C<.poll> method can be used in combination with C<.receive> method, as a
caching mechanism where lack of value returned by `.poll` is a signal that
more values need to be fetched and loaded into the channel:
=begin code :skip-test
sub get-value {
return $c.poll // do { start replenish-cache; $c.receive };
}
Expand All @@ -501,10 +506,12 @@ more values need to be fetched and loaded into the channel:
$c.send: $_ for slowly-fetch-a-thing();
}
}
=end code
Channels can be used in place of the L<Supply> in the C<whenever> of a
C<react> block described earlier:
=begin code :skip-test
my $channel = Channel.new;
my $p = start {
react {
Expand All @@ -523,6 +530,7 @@ C<react> block described earlier:
$channel.close;
await $p;
=end code
It is also possible to obtain a L<Channel> from a L<Supply> using the
L<Channel method|/type/Supply#method_Channel> which returns a L<Channel>
Expand Down Expand Up @@ -642,7 +650,8 @@ In both cases the completion of the code encapsulated by the L<Thread>
object can be waited on with the C<finish> method which will block until
the thread completes:
$thread.finish;
=for code :skip-test
$thread.finish;
Beyond that there are no further facilities for synchronization or resource
sharing which is largely why it should be emphasized that threads are unlikely
Expand Down
15 changes: 7 additions & 8 deletions doc/Language/exceptions.pod6
Expand Up @@ -91,7 +91,8 @@ as the enclosing block gets left immediately:
Output:
something went wrong ...
=for code :skip-test
something went wrong ...
Compare with this one:
Expand All @@ -105,11 +106,7 @@ Compare with this one:
}
say "Hi! I am at the outer block!";
Output:
Hi! I am at the outer block!
say "Hi! I am at the outer block!"; # OUTPUT: «Hi! I am at the outer block!␤»
See also "Resuming of Exceptions" to return control back to where the exception originated.
Expand Down Expand Up @@ -146,17 +143,19 @@ rethrown.
Output:
=begin code :skip-test
I'm alive!
No, I expect you to DIE Mr. Bond!
I'm immortal.
Just stop already!
in block <unit> at exception.p6 line 21
=end code
A C<try>-block is a normal block and as such treats it's last statement as the
return value of itself. We can therefore use it as a RHS.
say try { +"99999" } // "oh no"
say try { +"hello" } // "oh no"
say try { +"99999" } // "oh no";
say try { +"hello" } // "oh no";
# OUTPUT«99999␤oh no␤»
=head1 Throwing exceptions
Expand Down
4 changes: 1 addition & 3 deletions doc/Language/experimental.pod6
Expand Up @@ -10,9 +10,7 @@ these features may be made part of the Perl 6 specification. To use these
features, one uses the C<experimental> pragma in program source code, for
example, like this:
=begin code
use experimental :macros;
=end code
use experimental :macros;
Following is a list of current experimental features and a short
description of each feature's purpose or a link to more details about
Expand Down

0 comments on commit 9fc71c3

Please sign in to comment.