CINXE.COM
Raku Guide
<!DOCTYPE html> <html lang="en"> <head> <!-- Google tag (gtag.js) --> <script async src="https://www.googletagmanager.com/gtag/js?id=G-BKRLVLW1G0"></script> <script> window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'G-BKRLVLW1G0'); </script> <!-- Matomo --> <script> var _paq = window._paq = window._paq || []; /* tracker methods like "setCustomDimension" should be called before "trackPageView" */ _paq.push(["setDocumentTitle", document.domain + "/" + document.title]); _paq.push(["setCookieDomain", "*.raku.guide"]); _paq.push(["setDomains", ["*.raku.guide"]]); _paq.push(["setDoNotTrack", true]); _paq.push(['trackPageView']); _paq.push(['enableLinkTracking']); (function() { var u="https://hankache.com/matomo/"; _paq.push(['setTrackerUrl', u+'matomo.php']); _paq.push(['setSiteId', '2']); var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s); })(); </script> <!-- End Matomo Code --> <link rel="shortcut icon" type="image/x-icon" href="favicon.ico"> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="generator" content="Asciidoctor 2.0.23"> <meta name="description" content="A general introduction to Raku"> <meta name="keywords" content="perl6, perl 6, introduction, perl6intro, perl 6 introduction, perl 6 tutorial, perl 6 intro, raku, raku introduction, raku guide, raku tutorial"> <meta name="author" content="Naoum Hankache"> <title>Raku Guide</title> <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700"> <style> /*! Asciidoctor default stylesheet | MIT License | https://asciidoctor.org */ /* Uncomment the following line when using as a custom stylesheet */ /* @import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700"; */ html{font-family:sans-serif;-webkit-text-size-adjust:100%} a{background:none} a:focus{outline:thin dotted} a:active,a:hover{outline:0} h1{font-size:2em;margin:.67em 0} b,strong{font-weight:bold} abbr{font-size:.9em} abbr[title]{cursor:help;border-bottom:1px dotted #dddddf;text-decoration:none} dfn{font-style:italic} hr{height:0} mark{background:#ff0;color:#000} code,kbd,pre,samp{font-family:monospace;font-size:1em} pre{white-space:pre-wrap} q{quotes:"\201C" "\201D" "\2018" "\2019"} small{font-size:80%} sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline} sup{top:-.5em} sub{bottom:-.25em} img{border:0} svg:not(:root){overflow:hidden} figure{margin:0} audio,video{display:inline-block} audio:not([controls]){display:none;height:0} fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em} legend{border:0;padding:0} button,input,select,textarea{font-family:inherit;font-size:100%;margin:0} button,input{line-height:normal} button,select{text-transform:none} button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer} button[disabled],html input[disabled]{cursor:default} input[type=checkbox],input[type=radio]{padding:0} button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0} textarea{overflow:auto;vertical-align:top} table{border-collapse:collapse;border-spacing:0} *,::before,::after{box-sizing:border-box} html,body{font-size:100%} body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;line-height:1;position:relative;cursor:auto;-moz-tab-size:4;-o-tab-size:4;tab-size:4;word-wrap:anywhere;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased} a:hover{cursor:pointer} img,object,embed{max-width:100%;height:auto} object,embed{height:100%} img{-ms-interpolation-mode:bicubic} .left{float:left!important} .right{float:right!important} .text-left{text-align:left!important} .text-right{text-align:right!important} .text-center{text-align:center!important} .text-justify{text-align:justify!important} .hide{display:none} img,object,svg{display:inline-block;vertical-align:middle} textarea{height:auto;min-height:50px} select{width:100%} .subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em} div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0} a{color:#2156a5;text-decoration:underline;line-height:inherit} a:hover,a:focus{color:#1d4b8f} a img{border:0} p{line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility} p aside{font-size:.875em;line-height:1.35;font-style:italic} h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em} h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0} h1{font-size:2.125em} h2{font-size:1.6875em} h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em} h4,h5{font-size:1.125em} h6{font-size:1em} hr{border:solid #dddddf;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em} em,i{font-style:italic;line-height:inherit} strong,b{font-weight:bold;line-height:inherit} small{font-size:60%;line-height:inherit} code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9)} ul,ol,dl{line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit} ul,ol{margin-left:1.5em} ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0} ul.circle{list-style-type:circle} ul.disc{list-style-type:disc} ul.square{list-style-type:square} ul.circle ul:not([class]),ul.disc ul:not([class]),ul.square ul:not([class]){list-style:inherit} ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0} dl dt{margin-bottom:.3125em;font-weight:bold} dl dd{margin-bottom:1.25em} blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd} blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)} @media screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2} h1{font-size:2.75em} h2{font-size:2.3125em} h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em} h4{font-size:1.4375em}} table{background:#fff;margin-bottom:1.25em;border:1px solid #dedede;word-wrap:normal} table thead,table tfoot{background:#f7f8f7} table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left} table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)} table tr.even,table tr.alt{background:#f8f8f7} table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{line-height:1.6} h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em} h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400} .center{margin-left:auto;margin-right:auto} .stretch{width:100%} .clearfix::before,.clearfix::after,.float-group::before,.float-group::after{content:" ";display:table} .clearfix::after,.float-group::after{clear:both} :not(pre).nobreak{word-wrap:normal} :not(pre).nowrap{white-space:nowrap} :not(pre).pre-wrap{white-space:pre-wrap} :not(pre):not([class^=L])>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background:#f7f7f8;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed} pre{color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;line-height:1.45;text-rendering:optimizeSpeed} pre code,pre pre{color:inherit;font-size:inherit;line-height:inherit} pre>code{display:block} pre.nowrap,pre.nowrap pre{white-space:pre;word-wrap:normal} em em{font-style:normal} strong strong{font-weight:400} .keyseq{color:rgba(51,51,51,.8)} kbd{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background:#f7f7f7;border:1px solid #ccc;border-radius:3px;box-shadow:0 1px 0 rgba(0,0,0,.2),inset 0 0 0 .1em #fff;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap} .keyseq kbd:first-child{margin-left:0} .keyseq kbd:last-child{margin-right:0} .menuseq,.menuref{color:#000} .menuseq b:not(.caret),.menuref{font-weight:inherit} .menuseq{word-spacing:-.02em} .menuseq b.caret{font-size:1.25em;line-height:.8} .menuseq i.caret{font-weight:bold;text-align:center;width:.45em} b.button::before,b.button::after{position:relative;top:-1px;font-weight:400} b.button::before{content:"[";padding:0 3px 0 2px} b.button::after{content:"]";padding:0 2px 0 3px} p a>code:hover{color:rgba(0,0,0,.9)} #header,#content,#footnotes,#footer{width:100%;margin:0 auto;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em} #header::before,#header::after,#content::before,#content::after,#footnotes::before,#footnotes::after,#footer::before,#footer::after{content:" ";display:table} #header::after,#content::after,#footnotes::after,#footer::after{clear:both} #content{margin-top:1.25em} #content::before{content:none} #header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0} #header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #dddddf} #header>h1:only-child{border-bottom:1px solid #dddddf;padding-bottom:8px} #header .details{border-bottom:1px solid #dddddf;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:flex;flex-flow:row wrap} #header .details span:first-child{margin-left:-.125em} #header .details span.email a{color:rgba(0,0,0,.85)} #header .details br{display:none} #header .details br+span::before{content:"\00a0\2013\00a0"} #header .details br+span.author::before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)} #header .details br+span#revremark::before{content:"\00a0|\00a0"} #header #revnumber{text-transform:capitalize} #header #revnumber::after{content:"\00a0"} #content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #dddddf;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem} #toc{border-bottom:1px solid #e7e7e9;padding-bottom:.5em} #toc>ul{margin-left:.125em} #toc ul.sectlevel0>li>a{font-style:italic} #toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0} #toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none} #toc li{line-height:1.3334;margin-top:.3334em} #toc a{text-decoration:none} #toc a:active{text-decoration:underline} #toctitle{color:#7a2518;font-size:1.2em} @media screen and (min-width:768px){#toctitle{font-size:1.375em} body.toc2{padding-left:15em;padding-right:0} body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #dddddf;padding-bottom:8px} #toc.toc2{margin-top:0!important;background:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #e7e7e9;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto} #toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em} #toc.toc2>ul{font-size:.9em;margin-bottom:0} #toc.toc2 ul ul{margin-left:0;padding-left:1em} #toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em} body.toc2.toc-right{padding-left:0;padding-right:15em} body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #e7e7e9;left:auto;right:0}} @media screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0} #toc.toc2{width:20em} #toc.toc2 #toctitle{font-size:1.375em} #toc.toc2>ul{font-size:.95em} #toc.toc2 ul ul{padding-left:1.25em} body.toc2.toc-right{padding-left:0;padding-right:20em}} #content #toc{border:1px solid #e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;border-radius:4px} #content #toc>:first-child{margin-top:0} #content #toc>:last-child{margin-bottom:0} #footer{max-width:none;background:rgba(0,0,0,.8);padding:1.25em} #footer-text{color:hsla(0,0%,100%,.8);line-height:1.44} #content{margin-bottom:.625em} .sect1{padding-bottom:.625em} @media screen and (min-width:768px){#content{margin-bottom:1.25em} .sect1{padding-bottom:1.25em}} .sect1:last-child{padding-bottom:0} .sect1+.sect1{border-top:1px solid #e7e7e9} #content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400} #content h1>a.anchor::before,h2>a.anchor::before,h3>a.anchor::before,#toctitle>a.anchor::before,.sidebarblock>.content>.title>a.anchor::before,h4>a.anchor::before,h5>a.anchor::before,h6>a.anchor::before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em} #content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible} #content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none} #content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221} details,.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em} details{margin-left:1.25rem} details>summary{cursor:pointer;display:block;position:relative;line-height:1.6;margin-bottom:.625rem;outline:none;-webkit-tap-highlight-color:transparent} details>summary::-webkit-details-marker{display:none} details>summary::before{content:"";border:solid transparent;border-left:solid;border-width:.3em 0 .3em .5em;position:absolute;top:.5em;left:-1.25rem;transform:translateX(15%)} details[open]>summary::before{border:solid transparent;border-top:solid;border-width:.5em .3em 0;transform:translateY(15%)} details>summary::after{content:"";width:1.25rem;height:1em;position:absolute;top:.3em;left:-1.25rem} .admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:"Noto Serif","DejaVu Serif",serif;font-size:1rem;font-style:italic} table.tableblock.fit-content>caption.title{white-space:nowrap;width:0} .paragraph.lead>p,#preamble>.sectionbody>[class=paragraph]:first-of-type p{font-size:1.21875em;line-height:1.6;color:rgba(0,0,0,.85)} .admonitionblock>table{border-collapse:separate;border:0;background:none;width:100%} .admonitionblock>table td.icon{text-align:center;width:80px} .admonitionblock>table td.icon img{max-width:none} .admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase} .admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #dddddf;color:rgba(0,0,0,.6);word-wrap:anywhere} .admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0} .exampleblock>.content{border:1px solid #e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;border-radius:4px} .sidebarblock{border:1px solid #dbdbd6;margin-bottom:1.25em;padding:1.25em;background:#f3f3f2;border-radius:4px} .sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center} .exampleblock>.content>:first-child,.sidebarblock>.content>:first-child{margin-top:0} .exampleblock>.content>:last-child,.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0} .literalblock pre,.listingblock>.content>pre{border-radius:4px;overflow-x:auto;padding:1em;font-size:.8125em} @media screen and (min-width:768px){.literalblock pre,.listingblock>.content>pre{font-size:.90625em}} @media screen and (min-width:1280px){.literalblock pre,.listingblock>.content>pre{font-size:1em}} .literalblock pre,.listingblock>.content>pre:not(.highlight),.listingblock>.content>pre[class=highlight],.listingblock>.content>pre[class^="highlight "]{background:#f7f7f8} .literalblock.output pre{color:#f7f7f8;background:rgba(0,0,0,.9)} .listingblock>.content{position:relative} .listingblock code[data-lang]::before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:inherit;opacity:.5} .listingblock:hover code[data-lang]::before{display:block} .listingblock.terminal pre .command::before{content:attr(data-prompt);padding-right:.5em;color:inherit;opacity:.5} .listingblock.terminal pre .command:not([data-prompt])::before{content:"$"} .listingblock pre.highlightjs{padding:0} .listingblock pre.highlightjs>code{padding:1em;border-radius:4px} .listingblock pre.prettyprint{border-width:0} .prettyprint{background:#f7f7f8} pre.prettyprint .linenums{line-height:1.45;margin-left:2em} pre.prettyprint li{background:none;list-style-type:inherit;padding-left:0} pre.prettyprint li code[data-lang]::before{opacity:1} pre.prettyprint li:not(:first-child) code[data-lang]::before{display:none} table.linenotable{border-collapse:separate;border:0;margin-bottom:0;background:none} table.linenotable td[class]{color:inherit;vertical-align:top;padding:0;line-height:inherit;white-space:normal} table.linenotable td.code{padding-left:.75em} table.linenotable td.linenos,pre.pygments .linenos{border-right:1px solid;opacity:.35;padding-right:.5em;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none} pre.pygments span.linenos{display:inline-block;margin-right:.75em} .quoteblock{margin:0 1em 1.25em 1.5em;display:table} .quoteblock:not(.excerpt)>.title{margin-left:-1.5em;margin-bottom:.75em} .quoteblock blockquote,.quoteblock p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify} .quoteblock blockquote{margin:0;padding:0;border:0} .quoteblock blockquote::before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)} .quoteblock blockquote>.paragraph:last-child p{margin-bottom:0} .quoteblock .attribution{margin-top:.75em;margin-right:.5ex;text-align:right} .verseblock{margin:0 1em 1.25em} .verseblock pre{font-family:"Open Sans","DejaVu Sans",sans-serif;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility} .verseblock pre strong{font-weight:400} .verseblock .attribution{margin-top:1.25rem;margin-left:.5ex} .quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic} .quoteblock .attribution br,.verseblock .attribution br{display:none} .quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)} .quoteblock.abstract blockquote::before,.quoteblock.excerpt blockquote::before,.quoteblock .quoteblock blockquote::before{display:none} .quoteblock.abstract blockquote,.quoteblock.abstract p,.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{line-height:1.6;word-spacing:0} .quoteblock.abstract{margin:0 1em 1.25em;display:block} .quoteblock.abstract>.title{margin:0 0 .375em;font-size:1.15em;text-align:center} .quoteblock.excerpt>blockquote,.quoteblock .quoteblock{padding:0 0 .25em 1em;border-left:.25em solid #dddddf} .quoteblock.excerpt,.quoteblock .quoteblock{margin-left:0} .quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{color:inherit;font-size:1.0625rem} .quoteblock.excerpt .attribution,.quoteblock .quoteblock .attribution{color:inherit;font-size:.85rem;text-align:left;margin-right:0} p.tableblock:last-child{margin-bottom:0} td.tableblock>.content{margin-bottom:1.25em;word-wrap:anywhere} td.tableblock>.content>:last-child{margin-bottom:-1.25em} table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede} table.grid-all>*>tr>*{border-width:1px} table.grid-cols>*>tr>*{border-width:0 1px} table.grid-rows>*>tr>*{border-width:1px 0} table.frame-all{border-width:1px} table.frame-ends{border-width:1px 0} table.frame-sides{border-width:0 1px} table.frame-none>colgroup+*>:first-child>*,table.frame-sides>colgroup+*>:first-child>*{border-top-width:0} table.frame-none>:last-child>:last-child>*,table.frame-sides>:last-child>:last-child>*{border-bottom-width:0} table.frame-none>*>tr>:first-child,table.frame-ends>*>tr>:first-child{border-left-width:0} table.frame-none>*>tr>:last-child,table.frame-ends>*>tr>:last-child{border-right-width:0} table.stripes-all>*>tr,table.stripes-odd>*>tr:nth-of-type(odd),table.stripes-even>*>tr:nth-of-type(even),table.stripes-hover>*>tr:hover{background:#f8f8f7} th.halign-left,td.halign-left{text-align:left} th.halign-right,td.halign-right{text-align:right} th.halign-center,td.halign-center{text-align:center} th.valign-top,td.valign-top{vertical-align:top} th.valign-bottom,td.valign-bottom{vertical-align:bottom} th.valign-middle,td.valign-middle{vertical-align:middle} table thead th,table tfoot th{font-weight:bold} tbody tr th{background:#f7f8f7} tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold} p.tableblock>code:only-child{background:none;padding:0} p.tableblock{font-size:1em} ol{margin-left:1.75em} ul li ol{margin-left:1.5em} dl dd{margin-left:1.125em} dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0} li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em} ul.checklist,ul.none,ol.none,ul.no-bullet,ol.no-bullet,ol.unnumbered,ul.unstyled,ol.unstyled{list-style-type:none} ul.no-bullet,ol.no-bullet,ol.unnumbered{margin-left:.625em} ul.unstyled,ol.unstyled{margin-left:0} li>p:empty:only-child::before{content:"";display:inline-block} ul.checklist>li>p:first-child{margin-left:-1em} ul.checklist>li>p:first-child>.fa-square-o:first-child,ul.checklist>li>p:first-child>.fa-check-square-o:first-child{width:1.25em;font-size:.8em;position:relative;bottom:.125em} ul.checklist>li>p:first-child>input[type=checkbox]:first-child{margin-right:.25em} ul.inline{display:flex;flex-flow:row wrap;list-style:none;margin:0 0 .625em -1.25em} ul.inline>li{margin-left:1.25em} .unstyled dl dt{font-weight:400;font-style:normal} ol.arabic{list-style-type:decimal} ol.decimal{list-style-type:decimal-leading-zero} ol.loweralpha{list-style-type:lower-alpha} ol.upperalpha{list-style-type:upper-alpha} ol.lowerroman{list-style-type:lower-roman} ol.upperroman{list-style-type:upper-roman} ol.lowergreek{list-style-type:lower-greek} .hdlist>table,.colist>table{border:0;background:none} .hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none} td.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em} td.hdlist1{font-weight:bold;padding-bottom:1.25em} td.hdlist2{word-wrap:anywhere} .literalblock+.colist,.listingblock+.colist{margin-top:-.5em} .colist td:not([class]):first-child{padding:.4em .75em 0;line-height:1;vertical-align:top} .colist td:not([class]):first-child img{max-width:none} .colist td:not([class]):last-child{padding:.25em 0} .thumb,.th{line-height:0;display:inline-block;border:4px solid #fff;box-shadow:0 0 0 1px #ddd} .imageblock.left{margin:.25em .625em 1.25em 0} .imageblock.right{margin:.25em 0 1.25em .625em} .imageblock>.title{margin-bottom:0} .imageblock.thumb,.imageblock.th{border-width:6px} .imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em} .image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0} .image.left{margin-right:.625em} .image.right{margin-left:.625em} a.image{text-decoration:none;display:inline-block} a.image object{pointer-events:none} sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super} sup.footnote a,sup.footnoteref a{text-decoration:none} sup.footnote a:active,sup.footnoteref a:active,#footnotes .footnote a:first-of-type:active{text-decoration:underline} #footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em} #footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em;border-width:1px 0 0} #footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;margin-bottom:.2em} #footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none;margin-left:-1.05em} #footnotes .footnote:last-of-type{margin-bottom:0} #content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0} div.unbreakable{page-break-inside:avoid} .big{font-size:larger} .small{font-size:smaller} .underline{text-decoration:underline} .overline{text-decoration:overline} .line-through{text-decoration:line-through} .aqua{color:#00bfbf} .aqua-background{background:#00fafa} .black{color:#000} .black-background{background:#000} .blue{color:#0000bf} .blue-background{background:#0000fa} .fuchsia{color:#bf00bf} .fuchsia-background{background:#fa00fa} .gray{color:#606060} .gray-background{background:#7d7d7d} .green{color:#006000} .green-background{background:#007d00} .lime{color:#00bf00} .lime-background{background:#00fa00} .maroon{color:#600000} .maroon-background{background:#7d0000} .navy{color:#000060} .navy-background{background:#00007d} .olive{color:#606000} .olive-background{background:#7d7d00} .purple{color:#600060} .purple-background{background:#7d007d} .red{color:#bf0000} .red-background{background:#fa0000} .silver{color:#909090} .silver-background{background:#bcbcbc} .teal{color:#006060} .teal-background{background:#007d7d} .white{color:#bfbfbf} .white-background{background:#fafafa} .yellow{color:#bfbf00} .yellow-background{background:#fafa00} span.icon>.fa{cursor:default} a span.icon>.fa{cursor:inherit} .admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default} .admonitionblock td.icon .icon-note::before{content:"\f05a";color:#19407c} .admonitionblock td.icon .icon-tip::before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111} .admonitionblock td.icon .icon-warning::before{content:"\f071";color:#bf6900} .admonitionblock td.icon .icon-caution::before{content:"\f06d";color:#bf3400} .admonitionblock td.icon .icon-important::before{content:"\f06a";color:#bf0000} .conum[data-value]{display:inline-block;color:#fff!important;background:rgba(0,0,0,.8);border-radius:50%;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold} .conum[data-value] *{color:#fff!important} .conum[data-value]+b{display:none} .conum[data-value]::after{content:attr(data-value)} pre .conum[data-value]{position:relative;top:-.125em} b.conum *{color:inherit!important} .conum:not([data-value]):empty{display:none} dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility} h1,h2,p,td.content,span.alt,summary{letter-spacing:-.01em} p strong,td.content strong,div.footnote strong{letter-spacing:-.005em} p,blockquote,dt,td.content,td.hdlist1,span.alt,summary{font-size:1.0625rem} p{margin-bottom:1.25rem} .sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em} .exampleblock>.content{background:#fffef7;border-color:#e0e0dc;box-shadow:0 1px 4px #e0e0dc} .print-only{display:none!important} @page{margin:1.25cm .75cm} @media print{*{box-shadow:none!important;text-shadow:none!important} html{font-size:80%} a{color:inherit!important;text-decoration:underline!important} a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important} a[href^="http:"]:not(.bare)::after,a[href^="https:"]:not(.bare)::after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em} abbr[title]{border-bottom:1px dotted} abbr[title]::after{content:" (" attr(title) ")"} pre,blockquote,tr,img,object,svg{page-break-inside:avoid} thead{display:table-header-group} svg{max-width:100%} p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3} h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid} #header,#content,#footnotes,#footer{max-width:none} #toc,.sidebarblock,.exampleblock>.content{background:none!important} #toc{border-bottom:1px solid #dddddf!important;padding-bottom:0!important} body.book #header{text-align:center} body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em} body.book #header .details{border:0!important;display:block;padding:0!important} body.book #header .details span:first-child{margin-left:0!important} body.book #header .details br{display:block} body.book #header .details br+span::before{content:none!important} body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important} body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always} .listingblock code[data-lang]::before{display:block} #footer{padding:0 .9375em} .hide-on-print{display:none!important} .print-only{display:block!important} .hide-for-print{display:none!important} .show-for-print{display:inherit!important}} @media amzn-kf8,print{#header>h1:first-child{margin-top:1.25rem} .sect1{padding:0!important} .sect1+.sect1{border:0} #footer{background:none} #footer-text{color:rgba(0,0,0,.6);font-size:.9em}} @media amzn-kf8{#header,#content,#footnotes,#footer{padding:0}} </style> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"> <style> pre.pygments .hll { background-color: #ffffcc } pre.pygments { background: #f8f8f8; } pre.pygments .tok-c { color: #3D7B7B; font-style: italic } /* Comment */ pre.pygments .tok-err { border: 1px solid #FF0000 } /* Error */ pre.pygments .tok-k { color: #008000; font-weight: bold } /* Keyword */ pre.pygments .tok-o { color: #666666 } /* Operator */ pre.pygments .tok-ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */ pre.pygments .tok-cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */ pre.pygments .tok-cp { color: #9C6500 } /* Comment.Preproc */ pre.pygments .tok-cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */ pre.pygments .tok-c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */ pre.pygments .tok-cs { color: #3D7B7B; font-style: italic } /* Comment.Special */ pre.pygments .tok-gd { color: #A00000 } /* Generic.Deleted */ pre.pygments .tok-ge { font-style: italic } /* Generic.Emph */ pre.pygments .tok-ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */ pre.pygments .tok-gr { color: #E40000 } /* Generic.Error */ pre.pygments .tok-gh { color: #000080; font-weight: bold } /* Generic.Heading */ pre.pygments .tok-gi { color: #008400 } /* Generic.Inserted */ pre.pygments .tok-go { color: #717171 } /* Generic.Output */ pre.pygments .tok-gp { color: #000080; font-weight: bold } /* Generic.Prompt */ pre.pygments .tok-gs { font-weight: bold } /* Generic.Strong */ pre.pygments .tok-gu { color: #800080; font-weight: bold } /* Generic.Subheading */ pre.pygments .tok-gt { color: #0044DD } /* Generic.Traceback */ pre.pygments .tok-kc { color: #008000; font-weight: bold } /* Keyword.Constant */ pre.pygments .tok-kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ pre.pygments .tok-kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ pre.pygments .tok-kp { color: #008000 } /* Keyword.Pseudo */ pre.pygments .tok-kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ pre.pygments .tok-kt { color: #B00040 } /* Keyword.Type */ pre.pygments .tok-m { color: #666666 } /* Literal.Number */ pre.pygments .tok-s { color: #BA2121 } /* Literal.String */ pre.pygments .tok-na { color: #687822 } /* Name.Attribute */ pre.pygments .tok-nb { color: #008000 } /* Name.Builtin */ pre.pygments .tok-nc { color: #0000FF; font-weight: bold } /* Name.Class */ pre.pygments .tok-no { color: #880000 } /* Name.Constant */ pre.pygments .tok-nd { color: #AA22FF } /* Name.Decorator */ pre.pygments .tok-ni { color: #717171; font-weight: bold } /* Name.Entity */ pre.pygments .tok-ne { color: #CB3F38; font-weight: bold } /* Name.Exception */ pre.pygments .tok-nf { color: #0000FF } /* Name.Function */ pre.pygments .tok-nl { color: #767600 } /* Name.Label */ pre.pygments .tok-nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ pre.pygments .tok-nt { color: #008000; font-weight: bold } /* Name.Tag */ pre.pygments .tok-nv { color: #19177C } /* Name.Variable */ pre.pygments .tok-ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ pre.pygments .tok-w { color: #bbbbbb } /* Text.Whitespace */ pre.pygments .tok-mb { color: #666666 } /* Literal.Number.Bin */ pre.pygments .tok-mf { color: #666666 } /* Literal.Number.Float */ pre.pygments .tok-mh { color: #666666 } /* Literal.Number.Hex */ pre.pygments .tok-mi { color: #666666 } /* Literal.Number.Integer */ pre.pygments .tok-mo { color: #666666 } /* Literal.Number.Oct */ pre.pygments .tok-sa { color: #BA2121 } /* Literal.String.Affix */ pre.pygments .tok-sb { color: #BA2121 } /* Literal.String.Backtick */ pre.pygments .tok-sc { color: #BA2121 } /* Literal.String.Char */ pre.pygments .tok-dl { color: #BA2121 } /* Literal.String.Delimiter */ pre.pygments .tok-sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ pre.pygments .tok-s2 { color: #BA2121 } /* Literal.String.Double */ pre.pygments .tok-se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */ pre.pygments .tok-sh { color: #BA2121 } /* Literal.String.Heredoc */ pre.pygments .tok-si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */ pre.pygments .tok-sx { color: #008000 } /* Literal.String.Other */ pre.pygments .tok-sr { color: #A45A77 } /* Literal.String.Regex */ pre.pygments .tok-s1 { color: #BA2121 } /* Literal.String.Single */ pre.pygments .tok-ss { color: #19177C } /* Literal.String.Symbol */ pre.pygments .tok-bp { color: #008000 } /* Name.Builtin.Pseudo */ pre.pygments .tok-fm { color: #0000FF } /* Name.Function.Magic */ pre.pygments .tok-vc { color: #19177C } /* Name.Variable.Class */ pre.pygments .tok-vg { color: #19177C } /* Name.Variable.Global */ pre.pygments .tok-vi { color: #19177C } /* Name.Variable.Instance */ pre.pygments .tok-vm { color: #19177C } /* Name.Variable.Magic */ pre.pygments .tok-il { color: #666666 } /* Literal.Number.Integer.Long */ </style> </head> <body class="book toc2 toc-left"> <div id="header"> <h1>Raku Guide</h1> <div class="details"> <span id="author" class="author">Naoum Hankache</span><br> <span id="email" class="email"><a href="mailto:naoum@hankache.com">naoum@hankache.com</a></span><br> </div> <div id="toc" class="toc2"> <div id="toctitle">Table of Contents</div> <ul class="sectlevel1"> <li><a href="#_introduction">1. Introduction</a> <ul class="sectlevel2"> <li><a href="#_what_is_raku">1.1. What is Raku</a></li> <li><a href="#_jargon">1.2. Jargon</a></li> <li><a href="#_installing_raku">1.3. Installing Raku</a></li> <li><a href="#_running_raku_code">1.4. Running Raku code</a></li> <li><a href="#_editors">1.5. Editors</a></li> <li><a href="#_hello_world">1.6. Hello World!</a></li> <li><a href="#_syntax_overview">1.7. Syntax overview</a></li> </ul> </li> <li><a href="#_operators">2. Operators</a> <ul class="sectlevel2"> <li><a href="#_common_operators">2.1. Common Operators</a></li> <li><a href="#_reversed_operators">2.2. Reversed Operators</a></li> <li><a href="#_reduction_operators">2.3. Reduction Operators</a></li> </ul> </li> <li><a href="#_variables">3. Variables</a> <ul class="sectlevel2"> <li><a href="#_scalars">3.1. Scalars</a></li> <li><a href="#_arrays">3.2. Arrays</a></li> <li><a href="#_hashes">3.3. Hashes</a></li> <li><a href="#_types">3.4. Types</a></li> <li><a href="#_introspection">3.5. Introspection</a></li> <li><a href="#_scoping">3.6. Scoping</a></li> <li><a href="#_assignment_vs_binding">3.7. Assignment vs. Binding</a></li> </ul> </li> <li><a href="#_functions_and_mutators">4. Functions and mutators</a></li> <li><a href="#_loops_and_conditions">5. Loops and conditions</a> <ul class="sectlevel2"> <li><a href="#_if">5.1. if</a></li> <li><a href="#_unless">5.2. unless</a></li> <li><a href="#_with">5.3. with</a></li> <li><a href="#_for">5.4. for</a></li> <li><a href="#_given">5.5. given</a></li> <li><a href="#_loop">5.6. loop</a></li> </ul> </li> <li><a href="#_io">6. I/O</a> <ul class="sectlevel2"> <li><a href="#_basic_io_using_the_terminal">6.1. Basic I/O using the Terminal</a></li> <li><a href="#_running_shell_commands">6.2. Running Shell Commands</a></li> <li><a href="#_file_io">6.3. File I/O</a></li> <li><a href="#_working_with_files_and_directories">6.4. Working with files and directories</a></li> </ul> </li> <li><a href="#_subroutines">7. Subroutines</a> <ul class="sectlevel2"> <li><a href="#_definition">7.1. Definition</a></li> <li><a href="#_signature">7.2. Signature</a></li> <li><a href="#_multiple_dispatch">7.3. Multiple dispatch</a></li> <li><a href="#_default_and_optional_parameters">7.4. Default and Optional Parameters</a></li> <li><a href="#_returning_values">7.5. Returning values</a></li> </ul> </li> <li><a href="#_functional_programming">8. Functional Programming</a> <ul class="sectlevel2"> <li><a href="#_functions_are_first_class_citizens">8.1. Functions are first-class citizens</a></li> <li><a href="#_anonymous_functions">8.2. Anonymous functions</a></li> <li><a href="#_chaining">8.3. Chaining</a></li> <li><a href="#_feed_operator">8.4. Feed Operator</a></li> <li><a href="#_hyper_operator">8.5. Hyper operator</a></li> <li><a href="#_junctions">8.6. Junctions</a></li> <li><a href="#_lazy_lists">8.7. Lazy Lists</a></li> <li><a href="#_closures">8.8. Closures</a></li> </ul> </li> <li><a href="#_classes_objects">9. Classes & Objects</a> <ul class="sectlevel2"> <li><a href="#_introduction_2">9.1. Introduction</a></li> <li><a href="#_encapsulation">9.2. Encapsulation</a></li> <li><a href="#_named_vs_positional_parameters">9.3. Named vs. Positional Parameters</a></li> <li><a href="#_methods">9.4. Methods</a></li> <li><a href="#_class_attributes">9.5. Class Attributes</a></li> <li><a href="#_access_type">9.6. Access Type</a></li> <li><a href="#_inheritance">9.7. Inheritance</a></li> <li><a href="#_multiple_inheritance">9.8. Multiple Inheritance</a></li> <li><a href="#_roles">9.9. Roles</a></li> <li><a href="#_introspection_2">9.10. Introspection</a></li> </ul> </li> <li><a href="#_exception_handling">10. Exception Handling</a> <ul class="sectlevel2"> <li><a href="#_catching_exceptions">10.1. Catching Exceptions</a></li> <li><a href="#_throwing_exceptions">10.2. Throwing Exceptions</a></li> </ul> </li> <li><a href="#_regular_expressions">11. Regular Expressions</a> <ul class="sectlevel2"> <li><a href="#_regex_definition">11.1. Regex definition</a></li> <li><a href="#_matching_characters">11.2. Matching characters</a></li> <li><a href="#_matching_categories_of_characters">11.3. Matching categories of characters</a></li> <li><a href="#_unicode_properties">11.4. Unicode properties</a></li> <li><a href="#_wildcards">11.5. Wildcards</a></li> <li><a href="#_quantifiers">11.6. Quantifiers</a></li> <li><a href="#_match_results">11.7. Match Results</a></li> <li><a href="#_example">11.8. Example</a></li> </ul> </li> <li><a href="#_raku_modules">12. Raku Modules</a> <ul class="sectlevel2"> <li><a href="#_using_modules">12.1. Using Modules</a></li> </ul> </li> <li><a href="#_unicode">13. Unicode</a> <ul class="sectlevel2"> <li><a href="#_using_unicode">13.1. Using Unicode</a></li> <li><a href="#_unicode_aware_operations">13.2. Unicode-aware Operations</a></li> </ul> </li> <li><a href="#_parallelism_concurrency_and_asynchrony">14. Parallelism, Concurrency and Asynchrony</a> <ul class="sectlevel2"> <li><a href="#_parallelism">14.1. Parallelism</a></li> <li><a href="#_concurrency_and_asynchrony">14.2. Concurrency and Asynchrony</a></li> </ul> </li> <li><a href="#_native_calling_interface">15. Native Calling Interface</a> <ul class="sectlevel2"> <li><a href="#_calling_a_function">15.1. Calling a function</a></li> <li><a href="#_renaming_a_function">15.2. Renaming a function</a></li> <li><a href="#_passing_arguments">15.3. Passing Arguments</a></li> <li><a href="#_returning_values_2">15.4. Returning values</a></li> <li><a href="#_types_2">15.5. Types</a></li> </ul> </li> <li><a href="#_the_community">16. The Community</a></li> </ul> </div> </div> <div id="content"> <div id="preamble"> <div class="sectionbody"> <div class="paragraph"> <p>This document is intended to give you a quick overview of the Raku programming language.<br> For those new to Raku, it should get you up and running.</p> </div> <div class="paragraph"> <p>Some sections of this document refer to other (more complete and accurate) parts of the <a href="https://docs.raku.org">Raku documentation</a>. You should read them if you need more information on a specific subject.</p> </div> <div class="paragraph"> <p>Throughout this document, you will find examples for most discussed topics. To better understand them, take the time to reproduce all examples.</p> </div> <div class="paragraph"> <div class="title">License</div> <p>This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. To view a copy of this license, visit</p> </div> <div class="ulist"> <ul> <li> <p><a href="https://creativecommons.org/licenses/by-sa/4.0/" class="bare">https://creativecommons.org/licenses/by-sa/4.0/</a>.</p> </li> </ul> </div> <div class="paragraph"> <div class="title">Contribution</div> <p>If you would like to contribute to this document, head over to:</p> </div> <div class="ulist"> <ul> <li> <p><a href="https://github.com/hankache/rakuguide" class="bare">https://github.com/hankache/rakuguide</a></p> </li> </ul> </div> <div class="paragraph"> <div class="title">Feedback</div> <p>All feedback is welcomed: <a href="mailto:naoum@hankache.com">naoum@hankache.com</a></p> </div> <div class="paragraph"> <p>If you liked this work, <em>Star</em> the repository on <a href="https://github.com/hankache/rakuguide">Github</a>.</p> </div> <div class="ulist"> <div class="title">Translations</div> <ul> <li> <p>Bulgarian: <a href="https://raku.guide/bg" class="bare">https://raku.guide/bg</a></p> </li> <li> <p>Chinese: <a href="https://raku.guide/zh" class="bare">https://raku.guide/zh</a></p> </li> <li> <p>Dutch: <a href="https://raku.guide/nl" class="bare">https://raku.guide/nl</a></p> </li> <li> <p>French: <a href="https://raku.guide/fr" class="bare">https://raku.guide/fr</a></p> </li> <li> <p>German: <a href="https://raku.guide/de" class="bare">https://raku.guide/de</a></p> </li> <li> <p>Indonesian: <a href="https://raku.guide/id" class="bare">https://raku.guide/id</a></p> </li> <li> <p>Italian <a href="https://raku.guide/it" class="bare">https://raku.guide/it</a></p> </li> <li> <p>Japanese: <a href="https://raku.guide/ja" class="bare">https://raku.guide/ja</a></p> </li> <li> <p>Portuguese: <a href="https://raku.guide/pt" class="bare">https://raku.guide/pt</a></p> </li> <li> <p>Spanish: <a href="https://raku.guide/es" class="bare">https://raku.guide/es</a></p> </li> <li> <p>Turkish: <a href="https://raku.guide/tr" class="bare">https://raku.guide/tr</a></p> </li> <li> <p>Russian: <a href="https://raku.guide/ru" class="bare">https://raku.guide/ru</a></p> </li> <li> <p>Ukrainian: <a href="https://raku.guide/uk" class="bare">https://raku.guide/uk</a></p> </li> </ul> </div> </div> </div> <div class="sect1"> <h2 id="_introduction">1. Introduction</h2> <div class="sectionbody"> <div class="sect2"> <h3 id="_what_is_raku">1.1. What is Raku</h3> <div class="paragraph"> <p>Raku is a high-level, general-purpose, gradually typed language. Raku is multi-paradigmatic. It supports Procedural, Object Oriented, and Functional programming.</p> </div> <div class="ulist"> <div class="title">Raku motto:</div> <ul> <li> <p>TMTOWTDI (Pronounced Tim Toady): There is more than one way to do it.</p> </li> </ul> </div> </div> <div class="sect2"> <h3 id="_jargon">1.2. Jargon</h3> <div class="ulist"> <ul> <li> <p><strong>Raku</strong>: Is a language specification with a test suite. Implementations that pass the specification test suite are considered Raku.</p> </li> <li> <p><strong>Rakudo</strong>: Is a compiler for Raku.</p> </li> <li> <p><strong>Zef</strong>: Is a Raku module installer.</p> </li> <li> <p><strong>Rakudo Star</strong>: Is a bundle that includes Rakudo, Zef, a collection of Raku modules, and documentation.</p> </li> </ul> </div> </div> <div class="sect2"> <h3 id="_installing_raku">1.3. Installing Raku</h3> <div class="paragraph"> <p><a href="https://rakubrew.org" class="bare">https://rakubrew.org</a> is a platform independent environment manager (think pyenv for Raku)</p> </div> <div class="paragraph"> <div class="title">Linux</div> <p>To install Rakudo Star, run the following commands from your terminal:</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="shell"><span></span>mkdir<span class="tok-w"> </span>~/rakudo<span class="tok-w"> </span><span class="tok-o">&&</span><span class="tok-w"> </span><span class="tok-nb">cd</span><span class="tok-w"> </span><span class="tok-nv">$_</span> curl<span class="tok-w"> </span>-LJO<span class="tok-w"> </span>https://rakudo.org/latest/star/src tar<span class="tok-w"> </span>-xzf<span class="tok-w"> </span>rakudo-star-*.tar.gz mv<span class="tok-w"> </span>rakudo-star-*/*<span class="tok-w"> </span>. rm<span class="tok-w"> </span>-fr<span class="tok-w"> </span>rakudo-star-* ./bin/rstar<span class="tok-w"> </span>install <span class="tok-nb">echo</span><span class="tok-w"> </span><span class="tok-s2">"export PATH=</span><span class="tok-k">$(</span><span class="tok-nb">pwd</span><span class="tok-k">)</span><span class="tok-s2">/bin/:</span><span class="tok-k">$(</span><span class="tok-nb">pwd</span><span class="tok-k">)</span><span class="tok-s2">/share/perl6/site/bin:</span><span class="tok-k">$(</span><span class="tok-nb">pwd</span><span class="tok-k">)</span><span class="tok-s2">/share/perl6/vendor/bin:</span><span class="tok-k">$(</span><span class="tok-nb">pwd</span><span class="tok-k">)</span><span class="tok-s2">/share/perl6/core/bin:\$PATH"</span><span class="tok-w"> </span>>><span class="tok-w"> </span>~/.bashrc <span class="tok-nb">source</span><span class="tok-w"> </span>~/.bashrc</code></pre> </div> </div> <div class="paragraph"> <p>For other Unix options, go to <a href="https://rakudo.org/star/source" class="bare">https://rakudo.org/star/source</a></p> </div> <div class="paragraph"> <div class="title">macOS</div> <p>Four options are available:</p> </div> <div class="ulist"> <ul> <li> <p>Follow the same steps listed for installing on Linux</p> </li> <li> <p>Install with homebrew: <code>brew install rakudo-star</code></p> </li> <li> <p>Install with MacPorts: <code>sudo port install rakudo</code></p> </li> <li> <p>Get the latest installer (file with .dmg extension) from <a href="https://rakudo.org/latest/star/macos" class="bare">https://rakudo.org/latest/star/macos</a></p> </li> </ul> </div> <div class="olist arabic"> <div class="title">Windows</div> <ol class="arabic"> <li> <p>For 64-bit architectures: Get the latest installer (file with .msi extension) from <a href="https://rakudo.org/latest/star/win" class="bare">https://rakudo.org/latest/star/win</a></p> </li> <li> <p>After installation, make sure <code>C:\rakudo\bin</code> is in the PATH</p> </li> </ol> </div> <div class="olist arabic"> <div class="title">Docker</div> <ol class="arabic"> <li> <p>Get the official Docker image <code>docker pull rakudo-star</code></p> </li> <li> <p>Then run a container with the image <code>docker run -it rakudo-star</code></p> </li> </ol> </div> </div> <div class="sect2"> <h3 id="_running_raku_code">1.4. Running Raku code</h3> <div class="paragraph"> <p>Running Raku code can be done using the REPL (Read-Eval-Print Loop). To do this, open a terminal, type <code>raku</code> into the terminal window, and hit [Enter]. This will cause a prompt of <code>></code> to appear. Next, type a line of code and hit [Enter]. The REPL will print out the value of the line. You may then type another line, or type <code>exit</code> and hit [Enter] to leave the REPL.</p> </div> <div class="paragraph"> <p>Alternatively, write your code in a file, save it and run it. It is recommended that Raku scripts have a <code>.raku</code> file name extension. Run the file by typing <code>raku filename.raku</code> into the terminal window and hitting [Enter]. Unlike the REPL, this will not automatically print the result of each line: the code must contain a statement like <code>say</code> to print output.</p> </div> <div class="paragraph"> <p>The REPL is mostly used for trying a specific piece of code, typically a single line. For programs with more than a single line it is recommended to store them in a file and then run them.</p> </div> <div class="paragraph"> <p>Single lines may also be tried non-interactively on the command-line by typing <code>raku -e 'your code here'</code> and hitting [Enter].</p> </div> <div class="admonitionblock tip"> <table> <tr> <td class="icon"> <i class="fa icon-tip" title="Tip"></i> </td> <td class="content"> <div class="paragraph"> <p>Rakudo Star bundles a line editor that helps you get the most out of the REPL.</p> </div> <div class="paragraph"> <p>If you installed plain Rakudo instead of Rakudo Star then you probably don’t have line editing features enabled (using the up and down arrows for history, left and right to edit input, TAB completion). Consider running the following command and you shall be all set:</p> </div> <div class="ulist"> <ul> <li> <p><code>zef install Linenoise</code> would work on Windows, Linux and macOS</p> </li> <li> <p><code>zef install Readline</code> if you are on Linux and prefer the <em>Readline</em> library</p> </li> </ul> </div> </td> </tr> </table> </div> </div> <div class="sect2"> <h3 id="_editors">1.5. Editors</h3> <div class="paragraph"> <p>Since most of the time we will be writing and storing our Raku programs in files, we should have a decent text editor that recognizes Raku syntax.</p> </div> <div class="paragraph"> <p>The community uses frequently the following editors:</p> </div> <div class="ulist"> <ul> <li> <p><a href="https://code.visualstudio.com/">Visual Studio Code</a>: syntax highlighting and error checking enabled using <a href="https://marketplace.visualstudio.com/items?itemName=bscan.raku-navigator">raku-navigator</a></p> </li> <li> <p><a href="https://www.vim.org/">Vim</a>: better syntax highlighting enabled using <a href="https://github.com/Raku/vim-raku">vim-raku</a></p> </li> <li> <p><a href="https://www.gnu.org/software/emacs/">Emacs</a>: syntax highlighting enabled using <a href="https://github.com/Raku/raku-mode">raku-mode</a></p> </li> <li> <p><a href="https://www.nano-editor.org/">Nano</a>: syntax highlighting enabled using <a href="https://github.com/hankache/raku.nanorc">raku.nanorc</a></p> </li> <li> <p><a href="https://notepad-plus-plus.org/">Notepad++</a>: syntax highlighting available out of the box</p> </li> <li> <p><a href="https://kate-editor.org//">Kate</a>: syntax highlighting available out of the box</p> </li> </ul> </div> </div> <div class="sect2"> <h3 id="_hello_world">1.6. Hello World!</h3> <div class="paragraph"> <p>We shall begin with The <code>hello world</code> ritual.</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-nb">say</span> <span class="tok-s">'hello world'</span>;</code></pre> </div> </div> <div class="paragraph"> <p>that can also be written as:</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-s">'hello world'</span>.<span class="tok-nb">say</span>;</code></pre> </div> </div> </div> <div class="sect2"> <h3 id="_syntax_overview">1.7. Syntax overview</h3> <div class="paragraph"> <p>Raku is <strong>free form</strong>: Most of the time you are free to use any amount of whitespace, although in certain cases whitespace carries meaning.</p> </div> <div class="paragraph"> <p><strong>Statements</strong> are typically a single line of code separated with semicolons:</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-nb">say</span> <span class="tok-s">"Hello"</span> <span class="tok-k">if</span> <span class="tok-nb">True</span>; <span class="tok-nb">say</span> <span class="tok-s">"World"</span> <span class="tok-k">if</span> <span class="tok-nb">False</span>;</code></pre> </div> </div> <div class="paragraph"> <p>Semicolons are not required after the last statement in a file or block of code, but it’s good practice to include them anyway.</p> </div> <div class="paragraph"> <p><strong>Blocks</strong> can contain a collection of statements. Surround statements with curly braces to create a block:</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span>{ <span class="tok-nb">say</span> <span class="tok-s">"First statement in the block."</span>; <span class="tok-nb">say</span> <span class="tok-s">"Second statement in the block."</span>; }</code></pre> </div> </div> <div class="paragraph"> <p><strong>Expressions</strong> are a special type of statement that returns a value: <code>1+2</code> will return <code>3</code></p> </div> <div class="paragraph"> <p>Expressions are made of <strong>Terms</strong> and <strong>Operators</strong>.</p> </div> <div class="paragraph"> <p><strong>Terms</strong> are:</p> </div> <div class="ulist"> <ul> <li> <p><strong>Variables</strong>: A value that can be manipulated and changed.</p> </li> <li> <p><strong>Literals</strong>: A constant value like a number or a string.</p> </li> </ul> </div> <div class="paragraph"> <p><strong>Operators</strong> are classified into types:</p> </div> <table class="tableblock frame-all grid-all stretch"> <colgroup> <col style="width: 33.3333%;"> <col style="width: 33.3333%;"> <col style="width: 33.3334%;"> </colgroup> <tbody> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>Type</strong></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>Explanation</strong></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>Example</strong></p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Prefix</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Before the term.</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>++1</code></p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Infix</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Between terms</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>1+2</code></p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Postfix</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">After the term</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>1++</code></p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Circumfix</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Around the term</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>(1)</code></p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Postcircumfix</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">After one term, around another</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>Array[1]</code></p></td> </tr> </tbody> </table> <div class="sect3"> <h4 id="_identifiers">1.7.1. Identifiers</h4> <div class="paragraph"> <p>Identifiers are the names given to terms when you define them.</p> </div> <div class="ulist"> <div class="title">Rules:</div> <ul> <li> <p>They must start with an alphabetic character or an underscore.</p> </li> <li> <p>They can contain digits (except the first character).</p> </li> <li> <p>They can contain dashes or apostrophes (except the first and last character), provided there’s an alphabetic character to the right side of each dash or apostrophe.</p> </li> </ul> </div> <table class="tableblock frame-all grid-all stretch"> <colgroup> <col style="width: 50%;"> <col style="width: 50%;"> </colgroup> <tbody> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>Valid</strong></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>Invalid</strong></p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>var1</code></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>1var</code></p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>var-one</code></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>var-1</code></p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>var’one</code></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>var'1</code></p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>var1_</code></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>var1'</code></p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>_var</code></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>-var</code></p></td> </tr> </tbody> </table> <div class="ulist"> <div class="title">Naming conventions:</div> <ul> <li> <p>Camel case: <code>variableNo1</code></p> </li> <li> <p>Kebab case: <code>variable-no1</code></p> </li> <li> <p>Snake case: <code>variable_no1</code></p> </li> </ul> </div> <div class="paragraph"> <p>You are free to name your identifiers as you like, but it is good practice to adopt one naming convention consistently.</p> </div> <div class="paragraph"> <p>Using meaningful names will ease your (and other’s) programming life.</p> </div> <div class="ulist"> <ul> <li> <p><code>var1 = var2 * var3</code> is syntactically correct but its purpose is not evident.</p> </li> <li> <p><code>monthly-salary = daily-rate * working-days</code> would be a better way to name your variables.</p> </li> </ul> </div> </div> <div class="sect3"> <h4 id="_comments">1.7.2. Comments</h4> <div class="paragraph"> <p>A comment is text ignored by the compiler and used as a note.</p> </div> <div class="paragraph"> <p>Comments are divided into 3 types:</p> </div> <div class="ulist"> <ul> <li> <p>Single line:</p> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-c1"># This is a single line comment</span></code></pre> </div> </div> </li> <li> <p>Embedded:</p> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-nb">say</span> <span class="tok-cm">#`(This is an embedded comment)</span> <span class="tok-s">"Hello World."</span></code></pre> </div> </div> </li> <li> <p>Multi line:</p> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-cm">=begin comment</span> <span class="tok-cm">This is a multi line comment.</span> <span class="tok-cm">Comment 1</span> <span class="tok-cm">Comment 2</span> <span class="tok-cm">=end comment</span></code></pre> </div> </div> </li> </ul> </div> </div> <div class="sect3"> <h4 id="_quotes">1.7.3. Quotes</h4> <div class="paragraph"> <p>Strings need to be delimited by either double quotes or single quotes.</p> </div> <div class="paragraph"> <p>Always use double quotes:</p> </div> <div class="ulist"> <ul> <li> <p>if your string contains an apostrophe.</p> </li> <li> <p>if your string contains a variable that needs to be interpolated.</p> </li> </ul> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-nb">say</span> <span class="tok-s">'Hello World'</span>; <span class="tok-c1"># Hello World</span> <span class="tok-nb">say</span> <span class="tok-s">"Hello World"</span>; <span class="tok-c1"># Hello World</span> <span class="tok-nb">say</span> <span class="tok-s">"Don't"</span>; <span class="tok-c1"># Don't</span> <span class="tok-k">my</span> <span class="tok-nv">$name</span> = <span class="tok-s">'John Doe'</span>; <span class="tok-nb">say</span> <span class="tok-s">'Hello $name'</span>; <span class="tok-c1"># Hello $name</span> <span class="tok-nb">say</span> <span class="tok-s">"Hello $name"</span>; <span class="tok-c1"># Hello John Doe</span></code></pre> </div> </div> </div> </div> </div> </div> <div class="sect1"> <h2 id="_operators">2. Operators</h2> <div class="sectionbody"> <div class="sect2"> <h3 id="_common_operators">2.1. Common Operators</h3> <div class="paragraph"> <p>The below table lists the most commonly used operators.</p> </div> <table class="tableblock frame-all grid-all stretch"> <colgroup> <col style="width: 7.1428%;"> <col style="width: 7.1428%;"> <col style="width: 28.5714%;"> <col style="width: 28.5714%;"> <col style="width: 28.5716%;"> </colgroup> <thead> <tr> <th class="tableblock halign-center valign-middle">Operator</th> <th class="tableblock halign-center valign-middle">Type</th> <th class="tableblock halign-left valign-middle">Description</th> <th class="tableblock halign-left valign-middle">Example</th> <th class="tableblock halign-left valign-middle">Result</th> </tr> </thead> <tbody> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>+</code></p></td> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>Infix</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock">Addition</p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>1 + 2</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>3</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>-</code></p></td> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>Infix</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock">Subtraction</p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>3 - 1</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>2</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>*</code></p></td> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>Infix</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock">Multiplication</p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>3 * 2</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>6</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>**</code></p></td> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>Infix</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock">Power</p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>3 ** 2</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>9</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>/</code></p></td> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>Infix</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock">Division</p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>3 / 2</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>1.5</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>div</code></p></td> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>Infix</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock">Integer Division (rounds down)</p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>3 div 2</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>1</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>%</code></p></td> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>Infix</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock">Modulo</p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>7 % 4</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>3</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle" rowspan="2"><p class="tableblock"><code>%%</code></p></td> <td class="tableblock halign-center valign-middle" rowspan="2"><p class="tableblock"><code>Infix</code></p></td> <td class="tableblock halign-left valign-middle" rowspan="2"><p class="tableblock">Divisibility</p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>6 %% 4</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>False</code></p></td> </tr> <tr> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>6 %% 3</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>True</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>gcd</code></p></td> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>Infix</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock">Greatest common divisor</p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>6 gcd 9</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>3</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>lcm</code></p></td> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>Infix</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock">Least common multiple</p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>6 lcm 9</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>18</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>==</code></p></td> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>Infix</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock">Numeric equal</p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>9 == 7</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>False</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>!=</code></p></td> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>Infix</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock">Numeric not equal</p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>9 != 7</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>True</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code><</code></p></td> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>Infix</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock">Numeric less than</p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>9 < 7</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>False</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>></code></p></td> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>Infix</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock">Numeric greater than</p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>9 > 7</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>True</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code><=</code></p></td> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>Infix</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock">Numeric less than or equal</p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>7 <= 7</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>True</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>>=</code></p></td> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>Infix</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock">Numeric greater than or equal</p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>9 >= 7</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>True</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle" rowspan="3"><p class="tableblock"><code><=></code></p></td> <td class="tableblock halign-center valign-middle" rowspan="3"><p class="tableblock"><code>Infix</code></p></td> <td class="tableblock halign-left valign-middle" rowspan="3"><p class="tableblock">Numeric three-way comparator</p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>1 <=> 1.0</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>Same</code></p></td> </tr> <tr> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>1 <=> 2</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>Less</code></p></td> </tr> <tr> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>3 <=> 2</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>More</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>eq</code></p></td> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>Infix</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock">String equal</p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>"John" eq "John"</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>True</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>ne</code></p></td> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>Infix</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock">String not equal</p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>"John" ne "Jane"</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>True</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>lt</code></p></td> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>Infix</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock">String less than</p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>"a" lt "b"</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>True</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>gt</code></p></td> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>Infix</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock">String greater than</p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>"a" gt "b"</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>False</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>le</code></p></td> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>Infix</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock">String less than or equal</p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>"a" le "a"</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>True</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>ge</code></p></td> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>Infix</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock">String greater than or equal</p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>"a" ge "b"</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>False</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle" rowspan="3"><p class="tableblock"><code>leg</code></p></td> <td class="tableblock halign-center valign-middle" rowspan="3"><p class="tableblock"><code>Infix</code></p></td> <td class="tableblock halign-left valign-middle" rowspan="3"><p class="tableblock">String three-way comparator</p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>"a" leg "a"</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>Same</code></p></td> </tr> <tr> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>"a" leg "b"</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>Less</code></p></td> </tr> <tr> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>"c" leg "b"</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>More</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle" rowspan="2"><p class="tableblock"><code>cmp</code></p></td> <td class="tableblock halign-center valign-middle" rowspan="2"><p class="tableblock"><code>Infix</code></p></td> <td class="tableblock halign-left valign-middle" rowspan="2"><p class="tableblock">Smart three-way comparator</p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>"a" cmp "b"</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>Less</code></p></td> </tr> <tr> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>3.5 cmp 2.6</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>More</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>=</code></p></td> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>Infix</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock">Assignment</p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>my $var = 7</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>Assigns the value of <code>7</code> to the variable <code>$var</code></code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle" rowspan="2"><p class="tableblock"><code>~</code></p></td> <td class="tableblock halign-center valign-middle" rowspan="2"><p class="tableblock"><code>Infix</code></p></td> <td class="tableblock halign-left valign-middle" rowspan="2"><p class="tableblock">String concatenation</p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>9 ~ 7</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>97</code></p></td> </tr> <tr> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>"Hi " ~ "there"</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>Hi there</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle" rowspan="2"><p class="tableblock"><code>x</code></p></td> <td class="tableblock halign-center valign-middle" rowspan="2"><p class="tableblock"><code>Infix</code></p></td> <td class="tableblock halign-left valign-middle" rowspan="2"><p class="tableblock">String replication</p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>13 x 3</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>131313</code></p></td> </tr> <tr> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>"Hello " x 3</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>Hello Hello Hello</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle" rowspan="5"><p class="tableblock"><code>~~</code></p></td> <td class="tableblock halign-center valign-middle" rowspan="5"><p class="tableblock"><code>Infix</code></p></td> <td class="tableblock halign-left valign-middle" rowspan="5"><p class="tableblock">Smart match</p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>2 ~~ 2</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>True</code></p></td> </tr> <tr> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>2 ~~ Int</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>True</code></p></td> </tr> <tr> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>"Raku" ~~ "Raku"</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>True</code></p></td> </tr> <tr> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>"Raku" ~~ Str</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>True</code></p></td> </tr> <tr> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>"enlightenment" ~~ /light/</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>「light」</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle" rowspan="2"><p class="tableblock"><code>++</code></p></td> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>Prefix</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock">Increment</p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>my $var = 2; ++$var;</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>Increment the variable by 1 and return the result <code>3</code></code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>Postfix</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock">Increment</p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>my $var = 2; $var++;</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>Return the variable <code>2</code> and then increment it</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle" rowspan="2"><p class="tableblock"><code>--</code></p></td> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>Prefix</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock">Decrement</p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>my $var = 2; --$var;</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>Decrement the variable by 1 and return the result <code>1</code></code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>Postfix</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock">Decrement</p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>my $var = 2; $var--;</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>Return the variable <code>2</code> and then decrement it</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle" rowspan="3"><p class="tableblock"><code>+</code></p></td> <td class="tableblock halign-center valign-middle" rowspan="3"><p class="tableblock"><code>Prefix</code></p></td> <td class="tableblock halign-left valign-middle" rowspan="3"><p class="tableblock">Coerce the operand to a numeric value</p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>+"3"</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>3</code></p></td> </tr> <tr> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>+True</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>1</code></p></td> </tr> <tr> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>+False</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>0</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle" rowspan="3"><p class="tableblock"><code>-</code></p></td> <td class="tableblock halign-center valign-middle" rowspan="3"><p class="tableblock"><code>Prefix</code></p></td> <td class="tableblock halign-left valign-middle" rowspan="3"><p class="tableblock">Coerce the operand to a numeric value and return the negation</p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>-"3"</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>-3</code></p></td> </tr> <tr> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>-True</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>-1</code></p></td> </tr> <tr> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>-False</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>0</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle" rowspan="6"><p class="tableblock"><code>?</code></p></td> <td class="tableblock halign-center valign-middle" rowspan="6"><p class="tableblock"><code>Prefix</code></p></td> <td class="tableblock halign-left valign-middle" rowspan="6"><p class="tableblock">Coerce the operand to a boolean value</p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>?0</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>False</code></p></td> </tr> <tr> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>?9.8</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>True</code></p></td> </tr> <tr> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>?"Hello"</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>True</code></p></td> </tr> <tr> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>?""</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>False</code></p></td> </tr> <tr> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>my $var; ?$var;</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>False</code></p></td> </tr> <tr> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>my $var = 7; ?$var;</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>True</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>!</code></p></td> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>Prefix</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock">Coerce the operand to a boolean value and return the negation</p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>!4</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>False</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>..</code></p></td> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>Infix</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock">Range Constructor</p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>0..5</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>Creates a range of the interval [0, 5] <sup class="footnote" id="_footnote_intervals">[<a id="_footnoteref_1" class="footnote" href="#_footnotedef_1" title="View footnote.">1</a>]</sup></code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>..^</code></p></td> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>Infix</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock">Range Constructor</p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>0..^5</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>Creates a range of the interval [0, 5) <sup class="footnoteref">[<a class="footnote" href="#_footnotedef_1" title="View footnote.">1</a>]</sup></code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>^..</code></p></td> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>Infix</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock">Range Constructor</p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>0^..5</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>Creates a range of the interval (0, 5] <sup class="footnoteref">[<a class="footnote" href="#_footnotedef_1" title="View footnote.">1</a>]</sup></code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>^..^</code></p></td> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>Infix</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock">Range Constructor</p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>0^..^5</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>Creates a range of the interval (0, 5) <sup class="footnoteref">[<a class="footnote" href="#_footnotedef_1" title="View footnote.">1</a>]</sup></code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>^</code></p></td> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>Prefix</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock">Range Constructor</p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>^5</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>Same as 0..^5 Creates a range of the interval [0, 5) <sup class="footnoteref">[<a class="footnote" href="#_footnotedef_1" title="View footnote.">1</a>]</sup></code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>…​</code></p></td> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>Infix</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock">Lazy List Constructor</p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>0…​9999</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>return the elements only if requested</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle" rowspan="2"><p class="tableblock"><code>|</code></p></td> <td class="tableblock halign-center valign-middle" rowspan="2"><p class="tableblock"><code>Prefix</code></p></td> <td class="tableblock halign-left valign-middle" rowspan="2"><p class="tableblock">Flattening</p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>|(0..5)</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>(0 1 2 3 4 5)</code></p></td> </tr> <tr> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>|(0^..^5)</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>(1 2 3 4)</code></p></td> </tr> </tbody> </table> </div> <div class="sect2"> <h3 id="_reversed_operators">2.2. Reversed Operators</h3> <div class="paragraph"> <p>Adding <code>R</code> before any operator will have the effect of reversing its operands.</p> </div> <table class="tableblock frame-all grid-all stretch"> <colgroup> <col style="width: 25%;"> <col style="width: 25%;"> <col style="width: 25%;"> <col style="width: 25%;"> </colgroup> <thead> <tr> <th class="tableblock halign-left valign-middle">Normal Operation</th> <th class="tableblock halign-left valign-middle">Result</th> <th class="tableblock halign-left valign-middle">Reversed Operator</th> <th class="tableblock halign-left valign-middle">Result</th> </tr> </thead> <tbody> <tr> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>2 / 3</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>0.666667</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>2 R/ 3</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>1.5</code></p></td> </tr> <tr> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>2 - 1</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>1</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>2 R- 1</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>-1</code></p></td> </tr> </tbody> </table> </div> <div class="sect2"> <h3 id="_reduction_operators">2.3. Reduction Operators</h3> <div class="paragraph"> <p>Reduction operators work on lists of values. They are formed by surrounding the operator with brackets <code>[]</code></p> </div> <table class="tableblock frame-all grid-all stretch"> <colgroup> <col style="width: 25%;"> <col style="width: 25%;"> <col style="width: 25%;"> <col style="width: 25%;"> </colgroup> <thead> <tr> <th class="tableblock halign-left valign-middle">Normal Operation</th> <th class="tableblock halign-left valign-middle">Result</th> <th class="tableblock halign-left valign-middle">Reduction Operator</th> <th class="tableblock halign-left valign-middle">Result</th> </tr> </thead> <tbody> <tr> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>1 + 2 + 3 + 4 + 5</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>15</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>[+] 1,2,3,4,5</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>15</code></p></td> </tr> <tr> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>1 * 2 * 3 * 4 * 5</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>120</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>[*] 1,2,3,4,5</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>120</code></p></td> </tr> </tbody> </table> <div class="admonitionblock note"> <table> <tr> <td class="icon"> <i class="fa icon-note" title="Note"></i> </td> <td class="content"> For the complete list of operators, including their precedence, go to <a href="https://docs.raku.org/language/operators" class="bare">https://docs.raku.org/language/operators</a> </td> </tr> </table> </div> </div> </div> </div> <div class="sect1"> <h2 id="_variables">3. Variables</h2> <div class="sectionbody"> <div class="paragraph"> <p>Raku variables are classified into 3 categories: Scalars, Arrays and Hashes.</p> </div> <div class="paragraph"> <p>A <strong>sigil</strong> (Sign in Latin) is a character that is used as a prefix to categorize variables.</p> </div> <div class="ulist"> <ul> <li> <p><code>$</code> is used for scalars</p> </li> <li> <p><code>@</code> is used for arrays</p> </li> <li> <p><code>%</code> is used for hashes</p> </li> </ul> </div> <div class="admonitionblock note"> <table> <tr> <td class="icon"> <i class="fa icon-note" title="Note"></i> </td> <td class="content"> This guide offers a simplified model of variables suitable for learning the basics of Raku. For a deeper understanding of variables, see <a href="https://docs.raku.org/language/containers" class="bare">https://docs.raku.org/language/containers</a> </td> </tr> </table> </div> <div class="sect2"> <h3 id="_scalars">3.1. Scalars</h3> <div class="paragraph"> <p>A scalar holds one value or reference.</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-c1"># String</span> <span class="tok-k">my</span> <span class="tok-nv">$name</span> = <span class="tok-s">'John Doe'</span>; <span class="tok-nb">say</span> <span class="tok-nv">$name</span>; <span class="tok-c1"># Integer</span> <span class="tok-k">my</span> <span class="tok-nv">$age</span> = <span class="tok-mi">99</span>; <span class="tok-nb">say</span> <span class="tok-nv">$age</span>;</code></pre> </div> </div> <div class="paragraph"> <p>A specific set of operations can be performed on a scalar, depending on the value it holds.</p> </div> <div class="listingblock"> <div class="title">String</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">$name</span> = <span class="tok-s">'John Doe'</span>; <span class="tok-nb">say</span> <span class="tok-nv">$name</span>.<span class="tok-nb">uc</span>; <span class="tok-nb">say</span> <span class="tok-nv">$name</span>.<span class="tok-nb">chars</span>; <span class="tok-nb">say</span> <span class="tok-nv">$name</span>.<span class="tok-nb">flip</span>;</code></pre> </div> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-n">JOHN</span> <span class="tok-n">DOE</span> <span class="tok-mi">8</span> <span class="tok-n">eoD</span> <span class="tok-n">nhoJ</span></code></pre> </div> </div> <div class="admonitionblock note"> <table> <tr> <td class="icon"> <i class="fa icon-note" title="Note"></i> </td> <td class="content"> For the complete list of methods applicable to Strings, see <a href="https://docs.raku.org/type/Str" class="bare">https://docs.raku.org/type/Str</a> </td> </tr> </table> </div> <div class="listingblock"> <div class="title">Integer</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">$age</span> = <span class="tok-mi">17</span>; <span class="tok-nb">say</span> <span class="tok-nv">$age</span>.<span class="tok-nb">is-prime</span>;</code></pre> </div> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-nb">True</span></code></pre> </div> </div> <div class="admonitionblock note"> <table> <tr> <td class="icon"> <i class="fa icon-note" title="Note"></i> </td> <td class="content"> For the complete list of methods applicable to Integers, see <a href="https://docs.raku.org/type/Int" class="bare">https://docs.raku.org/type/Int</a> </td> </tr> </table> </div> <div class="listingblock"> <div class="title">Rational Number</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">$age</span> = <span class="tok-mf">2.3</span>; <span class="tok-nb">say</span> <span class="tok-nv">$age</span>.<span class="tok-nb">numerator</span>; <span class="tok-nb">say</span> <span class="tok-nv">$age</span>.<span class="tok-nb">denominator</span>; <span class="tok-nb">say</span> <span class="tok-nv">$age</span>.<span class="tok-nb">nude</span>;</code></pre> </div> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-mi">23</span> <span class="tok-mi">10</span> (<span class="tok-mi">23</span> <span class="tok-mi">10</span>)</code></pre> </div> </div> <div class="admonitionblock note"> <table> <tr> <td class="icon"> <i class="fa icon-note" title="Note"></i> </td> <td class="content"> For the complete list of methods applicable to Rational Numbers, see <a href="https://docs.raku.org/type/Rat" class="bare">https://docs.raku.org/type/Rat</a> </td> </tr> </table> </div> </div> <div class="sect2"> <h3 id="_arrays">3.2. Arrays</h3> <div class="paragraph"> <p>Arrays are lists containing multiple values.</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">@animals</span> = <span class="tok-s">'camel'</span>,<span class="tok-s">'llama'</span>,<span class="tok-s">'owl'</span>; <span class="tok-nb">say</span> <span class="tok-nv">@animals</span>;</code></pre> </div> </div> <div class="paragraph"> <p>Many operations can be performed on arrays as shown in the below example:</p> </div> <div class="admonitionblock tip"> <table> <tr> <td class="icon"> <i class="fa icon-tip" title="Tip"></i> </td> <td class="content"> The tilde <code>~</code> is used for string concatenation. </td> </tr> </table> </div> <div class="listingblock"> <div class="title"><code>Script</code></div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">@animals</span> = <span class="tok-s">'camel'</span>,<span class="tok-s">'vicuña'</span>,<span class="tok-s">'llama'</span>; <span class="tok-nb">say</span> <span class="tok-s">"The zoo contains "</span> ~ <span class="tok-nv">@animals</span>.<span class="tok-nb">elems</span> ~ <span class="tok-s">" animals"</span>; <span class="tok-nb">say</span> <span class="tok-s">"The animals are: "</span> ~ <span class="tok-nv">@animals</span>; <span class="tok-nb">say</span> <span class="tok-s">"I will adopt an owl for the zoo"</span>; <span class="tok-nv">@animals</span>.<span class="tok-nb">push</span>(<span class="tok-s">"owl"</span>); <span class="tok-nb">say</span> <span class="tok-s">"Now my zoo has: "</span> ~ <span class="tok-nv">@animals</span>; <span class="tok-nb">say</span> <span class="tok-s">"The first animal we adopted was the "</span> ~ <span class="tok-nv">@animals</span>[<span class="tok-mi">0</span>]; <span class="tok-nv">@animals</span>.<span class="tok-nb">pop</span>; <span class="tok-nb">say</span> <span class="tok-s">"Unfortunately the owl got away and we're left with: "</span> ~ <span class="tok-nv">@animals</span>; <span class="tok-nb">say</span> <span class="tok-s">"We're closing the zoo and keeping one animal only"</span>; <span class="tok-nb">say</span> <span class="tok-s">"We're going to let go: "</span> ~ <span class="tok-nv">@animals</span>.<span class="tok-nb">splice</span>(<span class="tok-mi">1</span>,<span class="tok-mi">2</span>) ~ <span class="tok-s">" and keep the "</span> ~ <span class="tok-nv">@animals</span>;</code></pre> </div> </div> <div class="listingblock"> <div class="title"><code>Output</code></div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-n">The</span> <span class="tok-n">zoo</span> <span class="tok-nb">contains</span> <span class="tok-mi">3</span> <span class="tok-n">animals</span> <span class="tok-n">The</span> <span class="tok-n">animals</span> <span class="tok-n">are:</span> <span class="tok-n">camel</span> <span class="tok-n">vicuña</span> <span class="tok-n">llama</span> <span class="tok-n">I</span> <span class="tok-n">will</span> <span class="tok-n">adopt</span> <span class="tok-n">an</span> <span class="tok-n">owl</span> <span class="tok-k">for</span> <span class="tok-n">the</span> <span class="tok-n">zoo</span> <span class="tok-n">Now</span> <span class="tok-k">my</span> <span class="tok-n">zoo</span> <span class="tok-n">has:</span> <span class="tok-n">camel</span> <span class="tok-n">vicuña</span> <span class="tok-n">llama</span> <span class="tok-n">owl</span> <span class="tok-n">The</span> <span class="tok-nb">first</span> <span class="tok-n">animal</span> <span class="tok-n">we</span> <span class="tok-n">adopted</span> <span class="tok-n">was</span> <span class="tok-n">the</span> <span class="tok-n">camel</span> <span class="tok-n">Unfortunately</span> <span class="tok-n">the</span> <span class="tok-n">owl</span> <span class="tok-nb">got</span> <span class="tok-n">away</span> <span class="tok-o">and</span> <span class="tok-n">we're</span> <span class="tok-n">left</span> <span class="tok-n">with:</span> <span class="tok-n">camel</span> <span class="tok-n">vicuña</span> <span class="tok-n">llama</span> <span class="tok-n">We're</span> <span class="tok-n">closing</span> <span class="tok-n">the</span> <span class="tok-n">zoo</span> <span class="tok-o">and</span> <span class="tok-n">keeping</span> <span class="tok-nb">one</span> <span class="tok-n">animal</span> <span class="tok-n">only</span> <span class="tok-n">We're</span> <span class="tok-n">going</span> <span class="tok-nb">to</span> <span class="tok-k">let</span> <span class="tok-n">go:</span> <span class="tok-n">vicuña</span> <span class="tok-n">llama</span> <span class="tok-o">and</span> <span class="tok-nb">keep</span> <span class="tok-n">the</span> <span class="tok-n">camel</span></code></pre> </div> </div> <div class="paragraph"> <div class="title">Explanation</div> <p><code>.elems</code> returns the number of elements in an array.<br> <code>.push()</code> adds one or more elements to the array.<br> We can access a specific element in the array by specifying its position <code>@animals[0]</code>.<br> <code>.pop</code> removes the last element from the array and returns it.<br> <code>.splice(a,b)</code> will remove <code>b</code> elements starting at position <code>a</code>.</p> </div> <div class="sect3"> <h4 id="_fixed_size_arrays">3.2.1. Fixed-size arrays</h4> <div class="paragraph"> <p>A basic array is declared as following:</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">@array</span>;</code></pre> </div> </div> <div class="paragraph"> <p>The basic array can have indefinite length and thus is called auto-extending.<br> The array will accept any number of values with no restriction.</p> </div> <div class="paragraph"> <p>In contrast, we can also create fixed-size arrays.<br> These arrays cannot be accessed beyond their defined size.</p> </div> <div class="paragraph"> <p>To declare an array of fixed size, specify its maximum number of elements in square brackets immediately after its name:</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">@array</span>[<span class="tok-mi">3</span>];</code></pre> </div> </div> <div class="paragraph"> <p>This array will be able to hold a maximum of 3 values, indexed from 0 to 2.</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">@array</span>[<span class="tok-mi">3</span>]; <span class="tok-nv">@array</span>[<span class="tok-mi">0</span>] = <span class="tok-s">"first value"</span>; <span class="tok-nv">@array</span>[<span class="tok-mi">1</span>] = <span class="tok-s">"second value"</span>; <span class="tok-nv">@array</span>[<span class="tok-mi">2</span>] = <span class="tok-s">"third value"</span>;</code></pre> </div> </div> <div class="paragraph"> <p>You will not be able to add a fourth value to this array:</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">@array</span>[<span class="tok-mi">3</span>]; <span class="tok-nv">@array</span>[<span class="tok-mi">0</span>] = <span class="tok-s">"first value"</span>; <span class="tok-nv">@array</span>[<span class="tok-mi">1</span>] = <span class="tok-s">"second value"</span>; <span class="tok-nv">@array</span>[<span class="tok-mi">2</span>] = <span class="tok-s">"third value"</span>; <span class="tok-nv">@array</span>[<span class="tok-mi">3</span>] = <span class="tok-s">"fourth value"</span>;</code></pre> </div> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-n">Index</span> <span class="tok-mi">3</span> <span class="tok-k">for</span> <span class="tok-n">dimension</span> <span class="tok-mi">1</span> <span class="tok-n">out</span> <span class="tok-nb">of</span> <span class="tok-nb">range</span> (<span class="tok-n">must</span> <span class="tok-n">be</span> <span class="tok-mi">0</span><span class="tok-o">..</span><span class="tok-mi">2</span>)</code></pre> </div> </div> </div> <div class="sect3"> <h4 id="_multidimensional_arrays">3.2.2. Multidimensional arrays</h4> <div class="paragraph"> <p>The arrays we saw until now are one-dimensional.<br> Fortunately, we can define multi-dimensional arrays in Raku.</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">@tbl</span>[<span class="tok-mi">3</span>;<span class="tok-mi">2</span>];</code></pre> </div> </div> <div class="paragraph"> <p>This array is two-dimensional. The first dimension can have a maximum of 3 values and the second dimension a maximum of 2 values.</p> </div> <div class="paragraph"> <p>Think of it as a 3x2 grid.</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">@tbl</span>[<span class="tok-mi">3</span>;<span class="tok-mi">2</span>]; <span class="tok-nv">@tbl</span>[<span class="tok-mi">0</span>;<span class="tok-mi">0</span>] = <span class="tok-mi">1</span>; <span class="tok-nv">@tbl</span>[<span class="tok-mi">0</span>;<span class="tok-mi">1</span>] = <span class="tok-s">"x"</span>; <span class="tok-nv">@tbl</span>[<span class="tok-mi">1</span>;<span class="tok-mi">0</span>] = <span class="tok-mi">2</span>; <span class="tok-nv">@tbl</span>[<span class="tok-mi">1</span>;<span class="tok-mi">1</span>] = <span class="tok-s">"y"</span>; <span class="tok-nv">@tbl</span>[<span class="tok-mi">2</span>;<span class="tok-mi">0</span>] = <span class="tok-mi">3</span>; <span class="tok-nv">@tbl</span>[<span class="tok-mi">2</span>;<span class="tok-mi">1</span>] = <span class="tok-s">"z"</span>; <span class="tok-nb">say</span> <span class="tok-nv">@tbl</span></code></pre> </div> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span>[[<span class="tok-mi">1</span> <span class="tok-nb">x</span>] [<span class="tok-mi">2</span> <span class="tok-n">y</span>] [<span class="tok-mi">3</span> <span class="tok-nb">z</span>]]</code></pre> </div> </div> <div class="listingblock"> <div class="title">Visual representation of the array:</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span>[<span class="tok-mi">1</span> <span class="tok-nb">x</span>] [<span class="tok-mi">2</span> <span class="tok-n">y</span>] [<span class="tok-mi">3</span> <span class="tok-nb">z</span>]</code></pre> </div> </div> <div class="admonitionblock note"> <table> <tr> <td class="icon"> <i class="fa icon-note" title="Note"></i> </td> <td class="content"> For the complete Array reference, see <a href="https://docs.raku.org/type/Array" class="bare">https://docs.raku.org/type/Array</a> </td> </tr> </table> </div> </div> </div> <div class="sect2"> <h3 id="_hashes">3.3. Hashes</h3> <div class="listingblock"> <div class="title">A Hash is a set of Key/Value pairs.</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">%capitals</span> = <span class="tok-s">'UK'</span>,<span class="tok-s">'London'</span>,<span class="tok-s">'Germany'</span>,<span class="tok-s">'Berlin'</span>; <span class="tok-nb">say</span> <span class="tok-nv">%capitals</span>;</code></pre> </div> </div> <div class="listingblock"> <div class="title">Another succinct way of filling the hash:</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">%capitals</span> = <span class="tok-n">UK</span> => <span class="tok-s">'London'</span>, <span class="tok-n">Germany</span> => <span class="tok-s">'Berlin'</span>; <span class="tok-nb">say</span> <span class="tok-nv">%capitals</span>;</code></pre> </div> </div> <div class="paragraph"> <p>Some of the methods that can be called on hashes are:</p> </div> <div class="listingblock"> <div class="title"><code>Script</code></div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">%capitals</span> = <span class="tok-n">UK</span> => <span class="tok-s">'London'</span>, <span class="tok-n">Germany</span> => <span class="tok-s">'Berlin'</span>; <span class="tok-nv">%capitals</span>.<span class="tok-n">push:</span> (<span class="tok-n">France</span> => <span class="tok-s">'Paris'</span>); <span class="tok-nb">say</span> <span class="tok-nv">%capitals</span>.<span class="tok-nb">kv</span>; <span class="tok-nb">say</span> <span class="tok-nv">%capitals</span>.<span class="tok-nb">keys</span>; <span class="tok-nb">say</span> <span class="tok-nv">%capitals</span>.<span class="tok-nb">values</span>; <span class="tok-nb">say</span> <span class="tok-s">"The capital of France is: "</span> ~ <span class="tok-nv">%capitals<France></span>;</code></pre> </div> </div> <div class="listingblock"> <div class="title"><code>Output</code></div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span>(<span class="tok-n">France</span> <span class="tok-n">Paris</span> <span class="tok-n">Germany</span> <span class="tok-n">Berlin</span> <span class="tok-n">UK</span> <span class="tok-n">London</span>) (<span class="tok-n">France</span> <span class="tok-n">Germany</span> <span class="tok-n">UK</span>) (<span class="tok-n">Paris</span> <span class="tok-n">Berlin</span> <span class="tok-n">London</span>) <span class="tok-n">The</span> <span class="tok-n">capital</span> <span class="tok-nb">of</span> <span class="tok-n">France</span> <span class="tok-n">is:</span> <span class="tok-n">Paris</span></code></pre> </div> </div> <div class="paragraph"> <div class="title">Explanation</div> <p><code>.push: (key => 'Value')</code> adds a new key/value pair.<br> <code>.kv</code> returns a list containing all keys and values.<br> <code>.keys</code> returns a list that contains all keys.<br> <code>.values</code> returns a list that contains all values.<br> We can access a specific value in the hash by specifying its key <code>%hash<key></code></p> </div> <div class="admonitionblock note"> <table> <tr> <td class="icon"> <i class="fa icon-note" title="Note"></i> </td> <td class="content"> For the complete Hash reference, see <a href="https://docs.raku.org/type/Hash" class="bare">https://docs.raku.org/type/Hash</a> </td> </tr> </table> </div> </div> <div class="sect2"> <h3 id="_types">3.4. Types</h3> <div class="paragraph"> <p>In the previous examples, we did not specify what type of values the variables should hold.</p> </div> <div class="admonitionblock tip"> <table> <tr> <td class="icon"> <i class="fa icon-tip" title="Tip"></i> </td> <td class="content"> <code>.WHAT</code> will return the type of value held in a variable. </td> </tr> </table> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">$var</span> = <span class="tok-s">'Text'</span>; <span class="tok-nb">say</span> <span class="tok-nv">$var</span>; <span class="tok-nb">say</span> <span class="tok-nv">$var</span>.<span class="tok-nb">WHAT</span>; <span class="tok-nv">$var</span> = <span class="tok-mi">123</span>; <span class="tok-nb">say</span> <span class="tok-nv">$var</span>; <span class="tok-nb">say</span> <span class="tok-nv">$var</span>.<span class="tok-nb">WHAT</span>;</code></pre> </div> </div> <div class="paragraph"> <p>As you can see in the above example, the type of value in <code>$var</code> was once (Str) and then (Int).</p> </div> <div class="paragraph"> <p>This style of programming is called dynamic typing. Dynamic in the sense that variables may contain values of Any type.</p> </div> <div class="paragraph"> <p>Now try running the below example:<br> Notice <code>Int</code> before the variable name.</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nb">Int</span> <span class="tok-nv">$var</span> = <span class="tok-s">'Text'</span>; <span class="tok-nb">say</span> <span class="tok-nv">$var</span>; <span class="tok-nb">say</span> <span class="tok-nv">$var</span>.<span class="tok-nb">WHAT</span>;</code></pre> </div> </div> <div class="paragraph"> <p>It will fail and return this error message: <code>Type check failed in assignment to $var; expected Int but got Str</code></p> </div> <div class="paragraph"> <p>What happened is that we specified beforehand that the variable should be of type (Int). When we tried to assign an (Str) to it, it failed.</p> </div> <div class="paragraph"> <p>This style of programming is called static typing. Static in the sense that variable types are defined before assignment and cannot change.</p> </div> <div class="paragraph"> <p>Raku is classified as <strong>gradually typed</strong>; it allows both <strong>static</strong> and <strong>dynamic</strong> typing.</p> </div> <div class="listingblock"> <div class="title">Arrays and hashes can also be statically typed:</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nb">Int</span> <span class="tok-nv">@array</span> = <span class="tok-mi">1</span>,<span class="tok-mi">2</span>,<span class="tok-mi">3</span>; <span class="tok-nb">say</span> <span class="tok-nv">@array</span>; <span class="tok-nb">say</span> <span class="tok-nv">@array</span>.<span class="tok-nb">WHAT</span>; <span class="tok-k">my</span> <span class="tok-nb">Str</span> <span class="tok-nv">@multilingual</span> = <span class="tok-s">"Hello"</span>,<span class="tok-s">"Salut"</span>,<span class="tok-s">"Hallo"</span>,<span class="tok-s">"您好"</span>,<span class="tok-s">"안녕하세요"</span>,<span class="tok-s">"こんにちは"</span>; <span class="tok-nb">say</span> <span class="tok-nv">@multilingual</span>; <span class="tok-nb">say</span> <span class="tok-nv">@multilingual</span>.<span class="tok-nb">WHAT</span>; <span class="tok-k">my</span> <span class="tok-nb">Str</span> <span class="tok-nv">%capitals</span> = <span class="tok-n">UK</span> => <span class="tok-s">'London'</span>, <span class="tok-n">Germany</span> => <span class="tok-s">'Berlin'</span>; <span class="tok-nb">say</span> <span class="tok-nv">%capitals</span>; <span class="tok-nb">say</span> <span class="tok-nv">%capitals</span>.<span class="tok-nb">WHAT</span>; <span class="tok-k">my</span> <span class="tok-nb">Int</span> <span class="tok-nv">%country-codes</span> = <span class="tok-n">UK</span> => <span class="tok-mi">44</span>, <span class="tok-n">Germany</span> => <span class="tok-mi">49</span>; <span class="tok-nb">say</span> <span class="tok-nv">%country-codes</span>; <span class="tok-nb">say</span> <span class="tok-nv">%country-codes</span>.<span class="tok-nb">WHAT</span>;</code></pre> </div> </div> <div class="paragraph"> <div class="title">Below is a list of the most commonly used types:</div> <p>You will most probably never use the first two but they are listed for informational purpose.</p> </div> <table class="tableblock frame-all grid-all stretch"> <colgroup> <col style="width: 14.2857%;"> <col style="width: 42.8571%;"> <col style="width: 28.5714%;"> <col style="width: 14.2858%;"> </colgroup> <tbody> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code><strong>Type</strong></code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code><strong>Description</strong></code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code><strong>Example</strong></code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code><strong>Result</strong></code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>Mu</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>The root of the Raku type hierarchy</code></p></td> <td class="tableblock halign-left valign-middle"></td> <td class="tableblock halign-left valign-middle"></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>Any</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>Default base class for new classes and for most built-in classes</code></p></td> <td class="tableblock halign-left valign-middle"></td> <td class="tableblock halign-left valign-middle"></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>Cool</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>Value that can be treated as a string or number interchangeably</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>my Cool $var = 31; say $var.flip; say $var * 2;</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>13 62</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>Str</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>String of characters</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>my Str $var = "NEON"; say $var.flip;</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>NOEN</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>Int</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>Integer (arbitrary-precision)</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>7 + 7</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>14</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>Rat</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>Rational number (limited-precision)</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>0.1 + 0.2</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>0.3</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>Bool</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>Boolean</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>!True</code></p></td> <td class="tableblock halign-left valign-middle"><p class="tableblock"><code>False</code></p></td> </tr> </tbody> </table> </div> <div class="sect2"> <h3 id="_introspection">3.5. Introspection</h3> <div class="paragraph"> <p>Introspection is the process of getting information about an object properties like its type.<br> In one of the previous example we used <code>.WHAT</code> to return the type of the variable.</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nb">Int</span> <span class="tok-nv">$var</span>; <span class="tok-nb">say</span> <span class="tok-nv">$var</span>.<span class="tok-nb">WHAT</span>; <span class="tok-c1"># (Int)</span> <span class="tok-k">my</span> <span class="tok-nv">$var2</span>; <span class="tok-nb">say</span> <span class="tok-nv">$var2</span>.<span class="tok-nb">WHAT</span>; <span class="tok-c1"># (Any)</span> <span class="tok-nv">$var2</span> = <span class="tok-mi">1</span>; <span class="tok-nb">say</span> <span class="tok-nv">$var2</span>.<span class="tok-nb">WHAT</span>; <span class="tok-c1"># (Int)</span> <span class="tok-nv">$var2</span> = <span class="tok-s">"Hello"</span>; <span class="tok-nb">say</span> <span class="tok-nv">$var2</span>.<span class="tok-nb">WHAT</span>; <span class="tok-c1"># (Str)</span> <span class="tok-nv">$var2</span> = <span class="tok-nb">True</span>; <span class="tok-nb">say</span> <span class="tok-nv">$var2</span>.<span class="tok-nb">WHAT</span>; <span class="tok-c1"># (Bool)</span> <span class="tok-nv">$var2</span> = <span class="tok-nb">Nil</span>; <span class="tok-nb">say</span> <span class="tok-nv">$var2</span>.<span class="tok-nb">WHAT</span>; <span class="tok-c1"># (Any)</span></code></pre> </div> </div> <div class="paragraph"> <p>The type of a variable holding a value is correlated to its value.<br> The type of a strongly declared empty variable is the type with which it was declared.<br> The type of an empty variable that wasn’t strongly declared is <code>(Any)</code><br> To clear the value of a variable, assign <code>Nil</code> to it.</p> </div> </div> <div class="sect2"> <h3 id="_scoping">3.6. Scoping</h3> <div class="paragraph"> <p>Before using a variable for the first time, it needs to be declared.</p> </div> <div class="paragraph"> <p>Several declarators are used in Raku. We’ve been using <code>my</code>, so far.</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">$var</span>=<span class="tok-mi">1</span>;</code></pre> </div> </div> <div class="paragraph"> <p>The <code>my</code> declarator give the variable <strong>lexical</strong> scope. In other words, the variable will only be accessible in the same block it was declared.</p> </div> <div class="paragraph"> <p>A block in Raku is delimited by <code>{ }</code>. If no block is found, the variable will be available in the whole Raku script.</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span>{ <span class="tok-k">my</span> <span class="tok-nb">Str</span> <span class="tok-nv">$var</span> = <span class="tok-s">'Text'</span>; <span class="tok-nb">say</span> <span class="tok-nv">$var</span>; <span class="tok-c1"># is accessible</span> } <span class="tok-nb">say</span> <span class="tok-nv">$var</span>; <span class="tok-c1"># is not accessible, returns an error</span></code></pre> </div> </div> <div class="paragraph"> <p>Since a variable is only accessible in the block where it is defined, the same variable name can be used in another block.</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span>{ <span class="tok-k">my</span> <span class="tok-nb">Str</span> <span class="tok-nv">$var</span> = <span class="tok-s">'Text'</span>; <span class="tok-nb">say</span> <span class="tok-nv">$var</span>; } <span class="tok-k">my</span> <span class="tok-nb">Int</span> <span class="tok-nv">$var</span> = <span class="tok-mi">123</span>; <span class="tok-nb">say</span> <span class="tok-nv">$var</span>;</code></pre> </div> </div> </div> <div class="sect2"> <h3 id="_assignment_vs_binding">3.7. Assignment vs. Binding</h3> <div class="paragraph"> <p>We’ve seen in the previous examples, how to <strong>assign</strong> values to variables.<br> <strong>Assignment</strong> is done using the <code>=</code> operator.</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nb">Int</span> <span class="tok-nv">$var</span> = <span class="tok-mi">123</span>; <span class="tok-nb">say</span> <span class="tok-nv">$var</span>;</code></pre> </div> </div> <div class="paragraph"> <p>We can change the value assigned to a variable:</p> </div> <div class="listingblock"> <div class="title">Assignment</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nb">Int</span> <span class="tok-nv">$var</span> = <span class="tok-mi">123</span>; <span class="tok-nb">say</span> <span class="tok-nv">$var</span>; <span class="tok-nv">$var</span> = <span class="tok-mi">999</span>; <span class="tok-nb">say</span> <span class="tok-nv">$var</span>;</code></pre> </div> </div> <div class="listingblock"> <div class="title"><code>Output</code></div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-mi">123</span> <span class="tok-mi">999</span></code></pre> </div> </div> <div class="paragraph"> <p>On the other hand, we cannot change the value <strong>bound</strong> to a variable.<br> <strong>Binding</strong> is done using the <code>:=</code> operator.</p> </div> <div class="listingblock"> <div class="title">Binding</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nb">Int</span> <span class="tok-nv">$var</span> := <span class="tok-mi">123</span>; <span class="tok-nb">say</span> <span class="tok-nv">$var</span>; <span class="tok-nv">$var</span> = <span class="tok-mi">999</span>; <span class="tok-nb">say</span> <span class="tok-nv">$var</span>;</code></pre> </div> </div> <div class="listingblock"> <div class="title"><code>Output</code></div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-mi">123</span> <span class="tok-n">Cannot</span> <span class="tok-n">assign</span> <span class="tok-nb">to</span> <span class="tok-n">an</span> <span class="tok-n">immutable</span> <span class="tok-nb">value</span></code></pre> </div> </div> <div class="listingblock"> <div class="title">Variables can also be bound to other variables:</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">$a</span>; <span class="tok-k">my</span> <span class="tok-nv">$b</span>; <span class="tok-nv">$b</span> := <span class="tok-nv">$a</span>; <span class="tok-nv">$a</span> = <span class="tok-mi">7</span>; <span class="tok-nb">say</span> <span class="tok-nv">$b</span>; <span class="tok-nv">$b</span> = <span class="tok-mi">8</span>; <span class="tok-nb">say</span> <span class="tok-nv">$a</span>;</code></pre> </div> </div> <div class="listingblock"> <div class="title"><code>Output</code></div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-mi">7</span> <span class="tok-mi">8</span></code></pre> </div> </div> <div class="paragraph"> <p>Binding variables is bi-directional.<br> <code>$a := $b</code> and <code>$b := $a</code> have the same effect.</p> </div> <div class="admonitionblock note"> <table> <tr> <td class="icon"> <i class="fa icon-note" title="Note"></i> </td> <td class="content"> For more info on variables, see <a href="https://docs.raku.org/language/variables" class="bare">https://docs.raku.org/language/variables</a> </td> </tr> </table> </div> </div> </div> </div> <div class="sect1"> <h2 id="_functions_and_mutators">4. Functions and mutators</h2> <div class="sectionbody"> <div class="paragraph"> <p>It is important to differentiate between functions and mutators.<br> Functions do not change the state of the object they were called on.<br> Mutators modify the state of the object.</p> </div> <div class="listingblock"> <div class="title"><code>Script</code></div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><div class="lineno"><table class="linenotable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span> <span class="normal"> 2</span> <span class="normal"> 3</span> <span class="normal"> 4</span> <span class="normal"> 5</span> <span class="normal"> 6</span> <span class="normal"> 7</span> <span class="normal"> 8</span> <span class="normal"> 9</span> <span class="normal">10</span></pre></div></td><td class="code"><div><pre><span></span><span class="tok-k">my</span> <span class="tok-nv">@numbers</span> = [<span class="tok-mi">7</span>,<span class="tok-mi">2</span>,<span class="tok-mi">4</span>,<span class="tok-mi">9</span>,<span class="tok-mi">11</span>,<span class="tok-mi">3</span>]; <span class="tok-nv">@numbers</span>.<span class="tok-nb">push</span>(<span class="tok-mi">99</span>); <span class="tok-nb">say</span> <span class="tok-nv">@numbers</span>; <span class="tok-c1">#1</span> <span class="tok-nb">say</span> <span class="tok-nv">@numbers</span>.<span class="tok-nb">sort</span>; <span class="tok-c1">#2</span> <span class="tok-nb">say</span> <span class="tok-nv">@numbers</span>; <span class="tok-c1">#3</span> <span class="tok-nv">@numbers</span>.=<span class="tok-nb">sort</span>; <span class="tok-nb">say</span> <span class="tok-nv">@numbers</span>; <span class="tok-c1">#4</span> </pre></div></td></tr></table></div></code></pre> </div> </div> <div class="listingblock"> <div class="title"><code>Output</code></div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span>[<span class="tok-mi">7</span> <span class="tok-mi">2</span> <span class="tok-mi">4</span> <span class="tok-mi">9</span> <span class="tok-mi">11</span> <span class="tok-mi">3</span> <span class="tok-mi">99</span>] <span class="tok-c1">#1</span> (<span class="tok-mi">2</span> <span class="tok-mi">3</span> <span class="tok-mi">4</span> <span class="tok-mi">7</span> <span class="tok-mi">9</span> <span class="tok-mi">11</span> <span class="tok-mi">99</span>) <span class="tok-c1">#2</span> [<span class="tok-mi">7</span> <span class="tok-mi">2</span> <span class="tok-mi">4</span> <span class="tok-mi">9</span> <span class="tok-mi">11</span> <span class="tok-mi">3</span> <span class="tok-mi">99</span>] <span class="tok-c1">#3</span> [<span class="tok-mi">2</span> <span class="tok-mi">3</span> <span class="tok-mi">4</span> <span class="tok-mi">7</span> <span class="tok-mi">9</span> <span class="tok-mi">11</span> <span class="tok-mi">99</span>] <span class="tok-c1">#4</span></code></pre> </div> </div> <div class="paragraph"> <div class="title">Explanation</div> <p><code>.push</code> is a mutator; it changes the state of the array (#1)</p> </div> <div class="paragraph"> <p><code>.sort</code> is a function; it returns a sorted array but doesn’t modify the state of the initial array:</p> </div> <div class="ulist"> <ul> <li> <p>(#2) shows that it returned a sorted array.</p> </li> <li> <p>(#3) shows that the initial array is still unmodified.</p> </li> </ul> </div> <div class="paragraph"> <p>In order to enforce a function to act as a mutator, we use <code>.=</code> instead of <code>.</code> (#4) (Line 9 of the script)</p> </div> </div> </div> <div class="sect1"> <h2 id="_loops_and_conditions">5. Loops and conditions</h2> <div class="sectionbody"> <div class="paragraph"> <p>Raku has many conditional and looping constructs.</p> </div> <div class="sect2"> <h3 id="_if">5.1. if</h3> <div class="paragraph"> <p>The code runs only if a condition has been met; i.e., an expression evaluates to <code>True</code>.</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">$age</span> = <span class="tok-mi">19</span>; <span class="tok-k">if</span> <span class="tok-nv">$age</span> > <span class="tok-mi">18</span> { <span class="tok-nb">say</span> <span class="tok-s">'Welcome'</span> }</code></pre> </div> </div> <div class="paragraph"> <p>In Raku, we can invert the code and the condition.<br> Even if the code and the condition have been inverted, the condition is always evaluated first.</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">$age</span> = <span class="tok-mi">19</span>; <span class="tok-nb">say</span> <span class="tok-s">'Welcome'</span> <span class="tok-k">if</span> <span class="tok-nv">$age</span> > <span class="tok-mi">18</span>;</code></pre> </div> </div> <div class="paragraph"> <p>If the condition is not met, we can specify alternate blocks for execution by using:</p> </div> <div class="ulist"> <ul> <li> <p><code>else</code></p> </li> <li> <p><code>elsif</code></p> </li> </ul> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-c1"># run the same code for different values of the variable</span> <span class="tok-k">my</span> <span class="tok-nv">$number-of-seats</span> = <span class="tok-mi">9</span>; <span class="tok-k">if</span> <span class="tok-nv">$number-of-seats</span> <= <span class="tok-mi">5</span> { <span class="tok-nb">say</span> <span class="tok-s">'I am a sedan'</span> } <span class="tok-k">elsif</span> <span class="tok-nv">$number-of-seats</span> <= <span class="tok-mi">7</span> { <span class="tok-nb">say</span> <span class="tok-s">'I am 7 seater'</span> } <span class="tok-k">else</span> { <span class="tok-nb">say</span> <span class="tok-s">'I am a van'</span> }</code></pre> </div> </div> </div> <div class="sect2"> <h3 id="_unless">5.2. unless</h3> <div class="paragraph"> <p>The negated version of an if statement can be written using <code>unless</code>.</p> </div> <div class="paragraph"> <p>The following code:</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">$clean-shoes</span> = <span class="tok-nb">False</span>; <span class="tok-k">if</span> <span class="tok-nb">not</span> <span class="tok-nv">$clean-shoes</span> { <span class="tok-nb">say</span> <span class="tok-s">'Clean your shoes'</span> }</code></pre> </div> </div> <div class="paragraph"> <p>can be written as:</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">$clean-shoes</span> = <span class="tok-nb">False</span>; <span class="tok-k">unless</span> <span class="tok-nv">$clean-shoes</span> { <span class="tok-nb">say</span> <span class="tok-s">'Clean your shoes'</span> }</code></pre> </div> </div> <div class="paragraph"> <p>Negation in Raku is done using either <code>!</code> or <code>not</code>.</p> </div> <div class="paragraph"> <p><code>unless (condition)</code> is used instead of <code>if not (condition)</code>.</p> </div> <div class="paragraph"> <p><code>unless</code> cannot have an <code>else</code> clause.</p> </div> </div> <div class="sect2"> <h3 id="_with">5.3. with</h3> <div class="paragraph"> <p><code>with</code> behaves like the <code>if</code> statement, but checks if the variable is defined.</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nb">Int</span> <span class="tok-nv">$var</span>=<span class="tok-mi">1</span>; <span class="tok-k">with</span> <span class="tok-nv">$var</span> { <span class="tok-nb">say</span> <span class="tok-s">'Hello'</span> }</code></pre> </div> </div> <div class="paragraph"> <p>If you run the code without assigning a value to the variable, nothing should happen.</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nb">Int</span> <span class="tok-nv">$var</span>; <span class="tok-k">with</span> <span class="tok-nv">$var</span> { <span class="tok-nb">say</span> <span class="tok-s">'Hello'</span> }</code></pre> </div> </div> <div class="paragraph"> <p><code>without</code> is the negated version of <code>with</code>. You should be able to relate it to <code>unless</code>.</p> </div> <div class="paragraph"> <p>If the first <code>with</code> condition is not met, an alternate path can be specified using <code>orwith</code>.<br> <code>with</code> and <code>orwith</code> can be compared to <code>if</code> and <code>elsif</code>.</p> </div> </div> <div class="sect2"> <h3 id="_for">5.4. for</h3> <div class="paragraph"> <p>The <code>for</code> loop iterates over multiple values.</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">@array</span> = <span class="tok-mi">1</span>,<span class="tok-mi">2</span>,<span class="tok-mi">3</span>; <span class="tok-k">for</span> <span class="tok-nv">@array</span> -> <span class="tok-nv">$array-item</span> { <span class="tok-nb">say</span> <span class="tok-nv">$array-item</span> * <span class="tok-mi">100</span> }</code></pre> </div> </div> <div class="paragraph"> <p>Notice that we created an iteration variable <code>$array-item</code> and then performed the operation <code>*100</code> on each array item.</p> </div> </div> <div class="sect2"> <h3 id="_given">5.5. given</h3> <div class="paragraph"> <p><code>given</code> is the Raku equivalent of the switch statement in other languages, but much more powerful.</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">$var</span> = <span class="tok-mi">42</span>; <span class="tok-k">given</span> <span class="tok-nv">$var</span> { <span class="tok-k">when</span> <span class="tok-mi">0</span><span class="tok-o">..</span><span class="tok-mi">50</span> { <span class="tok-nb">say</span> <span class="tok-s">'Less than or equal to 50'</span>} <span class="tok-k">when</span> <span class="tok-nb">Int</span> { <span class="tok-nb">say</span> <span class="tok-s">"is an Int"</span> } <span class="tok-k">when</span> <span class="tok-mi">42</span> { <span class="tok-nb">say</span> <span class="tok-mi">42</span> } <span class="tok-k">default</span> { <span class="tok-nb">say</span> <span class="tok-s">"huh?"</span> } }</code></pre> </div> </div> <div class="paragraph"> <p>After a successful match, the matching process will stop.</p> </div> <div class="paragraph"> <p>Alternatively <code>proceed</code> will instruct Raku to continue matching even after a successful match.</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">$var</span> = <span class="tok-mi">42</span>; <span class="tok-k">given</span> <span class="tok-nv">$var</span> { <span class="tok-k">when</span> <span class="tok-mi">0</span><span class="tok-o">..</span><span class="tok-mi">50</span> { <span class="tok-nb">say</span> <span class="tok-s">'Less than or equal to 50'</span>;<span class="tok-k">proceed</span>} <span class="tok-k">when</span> <span class="tok-nb">Int</span> { <span class="tok-nb">say</span> <span class="tok-s">"is an Int"</span>;<span class="tok-k">proceed</span>} <span class="tok-k">when</span> <span class="tok-mi">42</span> { <span class="tok-nb">say</span> <span class="tok-mi">42</span> } <span class="tok-k">default</span> { <span class="tok-nb">say</span> <span class="tok-s">"huh?"</span> } }</code></pre> </div> </div> </div> <div class="sect2"> <h3 id="_loop">5.6. loop</h3> <div class="paragraph"> <p><code>loop</code> is another way of writing a <code>for</code> loop.</p> </div> <div class="paragraph"> <p>Actually, <code>loop</code> is how <code>for</code> loops are written in C-family programming languages.</p> </div> <div class="paragraph"> <p>Raku belongs to the C-family languages.</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">loop</span> (<span class="tok-k">my</span> <span class="tok-nv">$i</span> = <span class="tok-mi">0</span>; <span class="tok-nv">$i</span> < <span class="tok-mi">5</span>; <span class="tok-nv">$i</span>++) { <span class="tok-nb">say</span> <span class="tok-s">"The current number is $i"</span> }</code></pre> </div> </div> <div class="admonitionblock note"> <table> <tr> <td class="icon"> <i class="fa icon-note" title="Note"></i> </td> <td class="content"> For more info on loops and conditions, see <a href="https://docs.raku.org/language/control" class="bare">https://docs.raku.org/language/control</a> </td> </tr> </table> </div> </div> </div> </div> <div class="sect1"> <h2 id="_io">6. I/O</h2> <div class="sectionbody"> <div class="paragraph"> <p>In Raku, two of the most common <em>Input/Output</em> interfaces are the <em>Terminal</em> and <em>Files</em>.</p> </div> <div class="sect2"> <h3 id="_basic_io_using_the_terminal">6.1. Basic I/O using the Terminal</h3> <div class="sect3"> <h4 id="_say">6.1.1. say</h4> <div class="paragraph"> <p><code>say</code> writes to the standard output. It appends a newline at the end. In other words, the following code:</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-nb">say</span> <span class="tok-s">'Hello Mam.'</span>; <span class="tok-nb">say</span> <span class="tok-s">'Hello Sir.'</span>;</code></pre> </div> </div> <div class="paragraph"> <p>will be written on 2 separate lines.</p> </div> </div> <div class="sect3"> <h4 id="_print">6.1.2. print</h4> <div class="paragraph"> <p><code>print</code> on the other hand behaves like <code>say</code> but doesn’t add a new line.</p> </div> <div class="paragraph"> <p>Try replacing <code>say</code> with <code>print</code> and compare the results.</p> </div> </div> <div class="sect3"> <h4 id="_get">6.1.3. get</h4> <div class="paragraph"> <p><code>get</code> is used to capture input from the terminal.</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">$name</span>; <span class="tok-nb">say</span> <span class="tok-s">"Hi, what's your name?"</span>; <span class="tok-nv">$name</span> = <span class="tok-nb">get</span>; <span class="tok-nb">say</span> <span class="tok-s">"Dear $name welcome to Raku"</span>;</code></pre> </div> </div> <div class="paragraph"> <p>When the above code runs, the terminal will be waiting for you to input your name. Enter it and then hit [Enter]. Subsequently, it will greet you.</p> </div> </div> <div class="sect3"> <h4 id="_prompt">6.1.4. prompt</h4> <div class="paragraph"> <p><code>prompt</code> is a combination of <code>print</code> and <code>get</code>.</p> </div> <div class="paragraph"> <p>The above example can be written like this:</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">$name</span> = <span class="tok-nb">prompt</span> <span class="tok-s">"Hi, what's your name? "</span>; <span class="tok-nb">say</span> <span class="tok-s">"Dear $name welcome to Raku"</span>;</code></pre> </div> </div> </div> </div> <div class="sect2"> <h3 id="_running_shell_commands">6.2. Running Shell Commands</h3> <div class="paragraph"> <p>Two subroutines can be used to run shell commands:</p> </div> <div class="ulist"> <ul> <li> <p><code>run</code> Runs an external command without involving a shell</p> </li> <li> <p><code>shell</code> Runs a command through the system shell. It is platform and shell dependent. All shell meta characters are interpreted by the shell, including pipes, redirects, environment variable substitutions and so on.</p> </li> </ul> </div> <div class="listingblock"> <div class="title">Run this if you’re on Linux/macOS</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">$name</span> = <span class="tok-s">'Neo'</span>; <span class="tok-nb">run</span> <span class="tok-s">'echo'</span>, <span class="tok-s">"hello $name"</span>; <span class="tok-nb">shell</span> <span class="tok-s">"ls"</span>;</code></pre> </div> </div> <div class="listingblock"> <div class="title">Run this if you’re on Windows</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-nb">shell</span> <span class="tok-s">"dir"</span>;</code></pre> </div> </div> <div class="paragraph"> <p><code>echo</code> and <code>ls</code> are common shell keywords on Linux:<br> <code>echo</code> prints text to the terminal (the equivalent of <code>say</code> in Raku)<br> <code>ls</code> lists all files and folders in the current directory</p> </div> <div class="paragraph"> <p><code>dir</code> is the equivalent of <code>ls</code> on Windows.</p> </div> </div> <div class="sect2"> <h3 id="_file_io">6.3. File I/O</h3> <div class="sect3"> <h4 id="_slurp">6.3.1. slurp</h4> <div class="paragraph"> <p><code>slurp</code> is used to read data from a file.</p> </div> <div class="paragraph"> <p>Create a text file with the following content:</p> </div> <div class="listingblock"> <div class="title">datafile.txt</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-n">John</span> <span class="tok-mi">9</span> <span class="tok-n">Johnnie</span> <span class="tok-mi">7</span> <span class="tok-n">Jane</span> <span class="tok-mi">8</span> <span class="tok-n">Joanna</span> <span class="tok-mi">7</span></code></pre> </div> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">$data</span> = <span class="tok-nb">slurp</span> <span class="tok-s">"datafile.txt"</span>; <span class="tok-nb">say</span> <span class="tok-nv">$data</span>;</code></pre> </div> </div> </div> <div class="sect3"> <h4 id="_spurt">6.3.2. spurt</h4> <div class="paragraph"> <p><code>spurt</code> is used to write data to a file.</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">$newdata</span> = <span class="tok-s">"New scores:</span> <span class="tok-s">Paul 10</span> <span class="tok-s">Paulie 9</span> <span class="tok-s">Paulo 11"</span>; <span class="tok-nb">spurt</span> <span class="tok-s">"newdatafile.txt"</span>, <span class="tok-nv">$newdata</span>;</code></pre> </div> </div> <div class="paragraph"> <p>After running the above code, a new file named <em>newdatafile.txt</em> will be created. It will contain the new scores.</p> </div> </div> </div> <div class="sect2"> <h3 id="_working_with_files_and_directories">6.4. Working with files and directories</h3> <div class="paragraph"> <p>Raku can list the contents of a directory without resorting to shell commands (by using <code>ls</code>, for example).</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-nb">say</span> <span class="tok-nb">dir</span>; <span class="tok-c1"># List files and folders in the current directory</span> <span class="tok-nb">say</span> <span class="tok-nb">dir</span> <span class="tok-s">"/Documents"</span>; <span class="tok-c1"># List files and folders in the specified directory</span></code></pre> </div> </div> <div class="paragraph"> <p>In addition, you can create and delete directories.</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-nb">mkdir</span> <span class="tok-s">"newfolder"</span>; <span class="tok-nb">rmdir</span> <span class="tok-s">"newfolder"</span>;</code></pre> </div> </div> <div class="paragraph"> <p><code>mkdir</code> creates a new directory.<br> <code>rmdir</code> deletes an empty directory and returns an error if not empty.</p> </div> <div class="paragraph"> <p>You can also check if a path exists; if it is a file; or a directory:</p> </div> <div class="paragraph"> <p>In the directory where you will be running the below script, create an empty folder <code>folder123</code> and an empty raku file <code>script123.raku</code></p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-nb">say</span> <span class="tok-s">"script123.raku"</span>.<span class="tok-nb">IO</span>.<span class="tok-nb">e</span>; <span class="tok-nb">say</span> <span class="tok-s">"folder123"</span>.<span class="tok-nb">IO</span>.<span class="tok-nb">e</span>; <span class="tok-nb">say</span> <span class="tok-s">"script123.raku"</span>.<span class="tok-nb">IO</span>.<span class="tok-nb">d</span>; <span class="tok-nb">say</span> <span class="tok-s">"folder123"</span>.<span class="tok-nb">IO</span>.<span class="tok-nb">d</span>; <span class="tok-nb">say</span> <span class="tok-s">"script123.raku"</span>.<span class="tok-nb">IO</span>.<span class="tok-nb">f</span>; <span class="tok-nb">say</span> <span class="tok-s">"folder123"</span>.<span class="tok-nb">IO</span>.<span class="tok-nb">f</span>;</code></pre> </div> </div> <div class="paragraph"> <p><code>IO.e</code> checks if the directory/file exists.<br> <code>IO.f</code> checks if the path is a file.<br> <code>IO.d</code> checks if the path is a directory.</p> </div> <div class="admonitionblock warning"> <table> <tr> <td class="icon"> <i class="fa icon-warning" title="Warning"></i> </td> <td class="content"> Windows users can use <code>/</code> or <code>\\</code> to define directories<br> <code>C:\\rakudo\\bin</code><br> <code>C:/rakudo/bin</code><br> </td> </tr> </table> </div> <div class="admonitionblock note"> <table> <tr> <td class="icon"> <i class="fa icon-note" title="Note"></i> </td> <td class="content"> For more info on I/O, see <a href="https://docs.raku.org/type/IO" class="bare">https://docs.raku.org/type/IO</a> </td> </tr> </table> </div> </div> </div> </div> <div class="sect1"> <h2 id="_subroutines">7. Subroutines</h2> <div class="sectionbody"> <div class="sect2"> <h3 id="_definition">7.1. Definition</h3> <div class="paragraph"> <p><strong>Subroutines</strong> (also called <strong>subs</strong> or <strong>functions</strong>) are a means of packaging and reusing functionality.<br></p> </div> <div class="paragraph"> <p>A subroutine definition begins with the keyword <code>sub</code>. After their definition, they can be called by their handle.<br> Check out the below example:</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">sub</span> <span class="tok-n">alien-greeting</span> { <span class="tok-nb">say</span> <span class="tok-s">"Hello earthlings"</span>; } <span class="tok-n">alien-greeting</span>;</code></pre> </div> </div> <div class="paragraph"> <p>The previous example showcased a subroutine that doesn’t require any input.</p> </div> </div> <div class="sect2"> <h3 id="_signature">7.2. Signature</h3> <div class="paragraph"> <p>Subroutines can require input. That input is provided by <strong>arguments</strong>. A subroutine may define zero or more <strong>parameters</strong>. The number and type of parameters that a subroutine defines is called its <strong>signature</strong>.</p> </div> <div class="paragraph"> <p>The below subroutine accepts a string argument.</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">sub</span> <span class="tok-n">say-hello</span> (<span class="tok-nb">Str</span> <span class="tok-nv">$name</span>) { <span class="tok-nb">say</span> <span class="tok-s">"Hello "</span> ~ <span class="tok-nv">$name</span> ~ <span class="tok-s">"!!!!"</span> } <span class="tok-n">say-hello</span> <span class="tok-s">"Paul"</span>; <span class="tok-n">say-hello</span> <span class="tok-s">"Paula"</span>;</code></pre> </div> </div> </div> <div class="sect2"> <h3 id="_multiple_dispatch">7.3. Multiple dispatch</h3> <div class="paragraph"> <p>It is possible to define multiple subroutines that have the same name but different signatures. When the subroutine is called, the runtime environment will decide which version to use based on the number and type of supplied arguments. This type of subroutine is defined the same way as normal subs except that we use the <code>multi</code> keyword instead of <code>sub</code>.</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">multi</span> <span class="tok-n">greet</span>(<span class="tok-nv">$name</span>) { <span class="tok-nb">say</span> <span class="tok-s">"Good morning $name"</span>; } <span class="tok-k">multi</span> <span class="tok-n">greet</span>(<span class="tok-nv">$name</span>, <span class="tok-nv">$title</span>) { <span class="tok-nb">say</span> <span class="tok-s">"Good morning $title $name"</span>; } <span class="tok-n">greet</span> <span class="tok-s">"Johnnie"</span>; <span class="tok-n">greet</span> <span class="tok-s">"Laura"</span>,<span class="tok-s">"Mrs."</span>;</code></pre> </div> </div> </div> <div class="sect2"> <h3 id="_default_and_optional_parameters">7.4. Default and Optional Parameters</h3> <div class="paragraph"> <p>If a subroutine is defined to accept an argument, and we call it without providing it with the required argument, it will fail.</p> </div> <div class="paragraph"> <p>Raku provides us the ability to define subroutines with:</p> </div> <div class="ulist"> <ul> <li> <p>Optional Parameters</p> </li> <li> <p>Default Parameters</p> </li> </ul> </div> <div class="paragraph"> <p>Optional parameters are defined by appending <code>?</code> to the parameter name.</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">sub</span> <span class="tok-n">say-hello</span>(<span class="tok-nv">$name</span>?) { <span class="tok-k">with</span> <span class="tok-nv">$name</span> { <span class="tok-nb">say</span> <span class="tok-s">"Hello "</span> ~ <span class="tok-nv">$name</span> } <span class="tok-k">else</span> { <span class="tok-nb">say</span> <span class="tok-s">"Hello Human"</span> } } <span class="tok-n">say-hello</span>; <span class="tok-n">say-hello</span>(<span class="tok-s">"Laura"</span>);</code></pre> </div> </div> <div class="paragraph"> <p>If the user doesn’t need to supply an argument, a default value can be defined.<br> This is done by assigning a value to the parameter within the subroutine definition.</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">sub</span> <span class="tok-n">say-hello</span>(<span class="tok-nv">$name</span>=<span class="tok-s">"Matt"</span>) { <span class="tok-nb">say</span> <span class="tok-s">"Hello "</span> ~ <span class="tok-nv">$name</span>; } <span class="tok-n">say-hello</span>; <span class="tok-n">say-hello</span>(<span class="tok-s">"Laura"</span>);</code></pre> </div> </div> </div> <div class="sect2"> <h3 id="_returning_values">7.5. Returning values</h3> <div class="paragraph"> <p>All the subroutines we’ve seen so far <strong>do something</strong> — they display some text on the terminal.</p> </div> <div class="paragraph"> <p>Sometimes, though, we execute a subroutine for its <strong>return</strong> value so we can use it later in the flow of our program.</p> </div> <div class="paragraph"> <p>If a function is allowed to run through it’s block to the end, the last statement or expression will determine the return value.</p> </div> <div class="listingblock"> <div class="title">Implicit return</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">sub</span> <span class="tok-n">squared</span> (<span class="tok-nv">$x</span>) { <span class="tok-nv">$x</span> ** <span class="tok-mi">2</span>; } <span class="tok-nb">say</span> <span class="tok-s">"7 squared is equal to "</span> ~ <span class="tok-n">squared</span>(<span class="tok-mi">7</span>);</code></pre> </div> </div> <div class="paragraph"> <p>For the sake of clarity, it might be a good idea to <em>explicitly</em> specify what we want returned. This can be done using the <code>return</code> keyword.</p> </div> <div class="listingblock"> <div class="title">Explicit return</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">sub</span> <span class="tok-n">squared</span> (<span class="tok-nv">$x</span>) { <span class="tok-k">return</span> <span class="tok-nv">$x</span> ** <span class="tok-mi">2</span>; } <span class="tok-nb">say</span> <span class="tok-s">"7 squared is equal to "</span> ~ <span class="tok-n">squared</span>(<span class="tok-mi">7</span>);</code></pre> </div> </div> <div class="sect3"> <h4 id="_restricting_return_values">7.5.1. Restricting return values</h4> <div class="paragraph"> <p>In one of the previous examples, we saw how we can restrict the accepted argument to be of a certain type. The same can be done with return values.</p> </div> <div class="paragraph"> <p>To restrict the return value to a certain type, we use the arrow notation <code>--></code> in the signature.</p> </div> <div class="listingblock"> <div class="title">Indicating return type</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">sub</span> <span class="tok-n">squared</span> (<span class="tok-nv">$x</span> --> <span class="tok-nb">Int</span>) { <span class="tok-k">return</span> <span class="tok-nv">$x</span> ** <span class="tok-mi">2</span>; } <span class="tok-nb">say</span> <span class="tok-s">"1.2 squared is equal to "</span> ~ <span class="tok-n">squared</span>(<span class="tok-mf">1.2</span>);</code></pre> </div> </div> <div class="paragraph"> <p>If we fail to provide a return value that matches the type constraint, an error will be thrown.</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-n">Type</span> <span class="tok-n">check</span> <span class="tok-n">failed</span> <span class="tok-k">for</span> <span class="tok-k">return</span> <span class="tok-nb">value</span>; <span class="tok-nb">expected</span> <span class="tok-nb">Int</span> <span class="tok-k">but</span> <span class="tok-nb">got</span> <span class="tok-nb">Rat</span> (<span class="tok-mf">1.44</span>)</code></pre> </div> </div> <div class="admonitionblock tip"> <table> <tr> <td class="icon"> <i class="fa icon-tip" title="Tip"></i> </td> <td class="content"> <div class="paragraph"> <p>Not only can type constraints control the type of the return value; they can also control its definedness.</p> </div> <div class="paragraph"> <p>In the previous examples, we specified that the return value should be an <code>Int</code>.</p> </div> <div class="paragraph"> <p>We could also have specified that the returned <code>Int</code> should be strictly defined or undefined using the following signatures:<br> <code>-→ Int:D</code> and <code>-→ Int:U</code></p> </div> <div class="paragraph"> <p>That being said, it is good practice to use those type constraints.<br> Below is the modified version of the previous example that uses <code>:D</code> to force the returned <code>Int</code> to be defined.</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">sub</span> <span class="tok-n">squared</span> (<span class="tok-nv">$x</span> --> <span class="tok-nb">Int:D</span>) { <span class="tok-k">return</span> <span class="tok-nv">$x</span> ** <span class="tok-mi">2</span>; } <span class="tok-nb">say</span> <span class="tok-s">"1.2 squared is equal to "</span> ~ <span class="tok-n">squared</span>(<span class="tok-mf">1.2</span>);</code></pre> </div> </div> </td> </tr> </table> </div> <div class="admonitionblock note"> <table> <tr> <td class="icon"> <i class="fa icon-note" title="Note"></i> </td> <td class="content"> For more info on subroutines and functions, see <a href="https://docs.raku.org/language/functions" class="bare">https://docs.raku.org/language/functions</a> </td> </tr> </table> </div> </div> </div> </div> </div> <div class="sect1"> <h2 id="_functional_programming">8. Functional Programming</h2> <div class="sectionbody"> <div class="paragraph"> <p>In this chapter we will take a look at some of the features that facilitate Functional Programming.</p> </div> <div class="sect2"> <h3 id="_functions_are_first_class_citizens">8.1. Functions are first-class citizens</h3> <div class="paragraph"> <p>Functions/subroutines are first-class citizens:</p> </div> <div class="ulist"> <ul> <li> <p>They can be passed as arguments</p> </li> <li> <p>They can be returned from other functions</p> </li> <li> <p>They can be assigned to variables</p> </li> </ul> </div> <div class="paragraph"> <p>A great example is the <code>map</code> function.<br> <code>map</code> is a <em>higher order function</em>, it can accept another function as an argument.</p> </div> <div class="listingblock"> <div class="title">Script</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">@array</span> = <span class="tok-s"><1 2 3 4 5></span>; <span class="tok-k">sub</span> <span class="tok-n">squared</span>(<span class="tok-nv">$x</span>) { <span class="tok-nv">$x</span> ** <span class="tok-mi">2</span> } <span class="tok-nb">say</span> <span class="tok-n">map</span>(<span class="tok-nv">&squared</span>,<span class="tok-nv">@array</span>);</code></pre> </div> </div> <div class="listingblock"> <div class="title">Output</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span>(<span class="tok-mi">1</span> <span class="tok-mi">4</span> <span class="tok-mi">9</span> <span class="tok-mi">16</span> <span class="tok-mi">25</span>)</code></pre> </div> </div> <div class="paragraph"> <div class="title">Explanation</div> <p>We defined a subroutine called <code>squared</code> that takes an argument and multiplies that argument by itself.<br> Next, we used <code>map</code>, a higher order function, and gave it two arguments, the <code>squared</code> subroutine and an array.<br> The result is a list of the squared elements of the array.</p> </div> <div class="paragraph"> <p>Notice that when passing a subroutine as an argument, we need to prepend <code>&</code> to its name.</p> </div> </div> <div class="sect2"> <h3 id="_anonymous_functions">8.2. Anonymous functions</h3> <div class="paragraph"> <p>An <strong>anonymous function</strong> is also called a <strong>lambda</strong>.<br> An anonymous function is not bound to an identifier (it has no name).</p> </div> <div class="paragraph"> <p>Let’s rewrite the <code>map</code> example and have it use an anonymous function</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">@array</span> = <span class="tok-s"><1 2 3 4 5></span>; <span class="tok-nb">say</span> <span class="tok-n">map</span>(-> <span class="tok-nv">$x</span> {<span class="tok-nv">$x</span> ** <span class="tok-mi">2</span>},<span class="tok-nv">@array</span>);</code></pre> </div> </div> <div class="paragraph"> <p>Notice that instead of declaring the squared subroutine and passing it as an argument to <code>map</code>, we defined it within the anonymous subroutine as <code>-> $x {$x ** 2}</code>.</p> </div> <div class="paragraph"> <p>In Raku parlance, we call this notation a <strong>pointy block</strong></p> </div> <div class="listingblock"> <div class="title">A pointy block may also be used to assign functions to variables:</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">$squared</span> = -> <span class="tok-nv">$x</span> { <span class="tok-nv">$x</span> ** <span class="tok-mi">2</span> } <span class="tok-nb">say</span> <span class="tok-nv">$squared</span>(<span class="tok-mi">9</span>);</code></pre> </div> </div> </div> <div class="sect2"> <h3 id="_chaining">8.3. Chaining</h3> <div class="paragraph"> <p>In Raku, methods can be chained, so you’re not required to pass the result of one method to another as an argument.</p> </div> <div class="paragraph"> <p>To illustrate: Given an array, you may need to return the unique values of the array, sorted from biggest to smallest.</p> </div> <div class="paragraph"> <p>Here’s a non-chained solution:</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">@array</span> = <span class="tok-s"><7 8 9 0 1 2 4 3 5 6 7 8 9></span>; <span class="tok-k">my</span> <span class="tok-nv">@final-array</span> = <span class="tok-nb">reverse</span>(<span class="tok-nb">sort</span>(<span class="tok-nb">unique</span>(<span class="tok-nv">@array</span>))); <span class="tok-nb">say</span> <span class="tok-nv">@final-array</span>;</code></pre> </div> </div> <div class="paragraph"> <p>Here, we call <code>unique</code> on <code>@array</code>, pass the result as an argument to <code>sort</code>, and then pass that result to <code>reverse</code>.</p> </div> <div class="paragraph"> <p>In contrast, with chained methods, the above example can be rewritten as:</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">@array</span> = <span class="tok-s"><7 8 9 0 1 2 4 3 5 6 7 8 9></span>; <span class="tok-k">my</span> <span class="tok-nv">@final-array</span> = <span class="tok-nv">@array</span>.<span class="tok-nb">unique</span>.<span class="tok-nb">sort</span>.<span class="tok-nb">reverse</span>; <span class="tok-nb">say</span> <span class="tok-nv">@final-array</span>;</code></pre> </div> </div> <div class="paragraph"> <p>You can already see that chaining methods is <em>easier on the eye</em>.</p> </div> </div> <div class="sect2"> <h3 id="_feed_operator">8.4. Feed Operator</h3> <div class="paragraph"> <p>The <strong>feed operator</strong>, called <em>pipe</em> in some functional programming languages, further illustrates method chaining.</p> </div> <div class="listingblock"> <div class="title">Forward Feed</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">@array</span> = <span class="tok-s"><7 8 9 0 1 2 4 3 5 6 7 8 9></span>; <span class="tok-nv">@array</span> ==> <span class="tok-nb">unique</span>() ==> <span class="tok-nb">sort</span>() ==> <span class="tok-nb">reverse</span>() ==> <span class="tok-k">my</span> <span class="tok-nv">@final-array</span>; <span class="tok-nb">say</span> <span class="tok-nv">@final-array</span>;</code></pre> </div> </div> <div class="listingblock"> <div class="title">Explanation</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-n">Start</span> <span class="tok-k">with</span> `<span class="tok-nv">@array</span>` <span class="tok-nb">then</span> <span class="tok-k">return</span> <span class="tok-n">a</span> <span class="tok-n">list</span> <span class="tok-nb">of</span> <span class="tok-nb">unique</span> <span class="tok-n">elements</span> <span class="tok-nb">then</span> <span class="tok-nb">sort</span> <span class="tok-n">it</span> <span class="tok-nb">then</span> <span class="tok-nb">reverse</span> <span class="tok-n">it</span> <span class="tok-nb">then</span> <span class="tok-n">store</span> <span class="tok-n">the</span> <span class="tok-nb">result</span> <span class="tok-nb">in</span> <span class="tok-nv">@final-array</span></code></pre> </div> </div> <div class="paragraph"> <p>Note that the flow of the method calls is top-down — from first to final step.</p> </div> <div class="listingblock"> <div class="title">Backward Feed</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">@array</span> = <span class="tok-s"><7 8 9 0 1 2 4 3 5 6 7 8 9></span>; <span class="tok-k">my</span> <span class="tok-nv">@final-array-v2</span> <== <span class="tok-nb">reverse</span>() <== <span class="tok-nb">sort</span>() <== <span class="tok-nb">unique</span>() <== <span class="tok-nv">@array</span>; <span class="tok-nb">say</span> <span class="tok-nv">@final-array-v2</span>;</code></pre> </div> </div> <div class="paragraph"> <div class="title">Explanation</div> <p>The backward feed is like the forward feed, but in reverse.<br> The flow of the method calls is bottom-up — from final to first step.</p> </div> </div> <div class="sect2"> <h3 id="_hyper_operator">8.5. Hyper operator</h3> <div class="paragraph"> <p>The <strong>hyper operator</strong> <code>>>.</code> will call a method on all elements of a list and return a list of the results.</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">@array</span> = <span class="tok-s"><0 1 2 3 4 5 6 7 8 9 10></span>; <span class="tok-k">sub</span> <span class="tok-n">is-even</span>(<span class="tok-nv">$var</span>) { <span class="tok-nv">$var</span> %% <span class="tok-mi">2</span> }; <span class="tok-nb">say</span> <span class="tok-nv">@array</span>>>.<span class="tok-nb">is-prime</span>; <span class="tok-nb">say</span> <span class="tok-nv">@array</span>>>.<span class="tok-nv">&is-even</span>;</code></pre> </div> </div> <div class="paragraph"> <p>Using the hyper operator we can call methods already defined in Raku, e.g. <code>is-prime</code> that tells us if a number is prime or not.<br> In addition we can define new subroutines and call them using the hyper operator. In this case we have to prepend <code>&</code> to the name of the method; e.g., <code>&is-even</code>.</p> </div> <div class="paragraph"> <p>This is very practical as it relieves us from writing a <code>for</code> loop to iterate over each value.</p> </div> <div class="admonitionblock warning"> <table> <tr> <td class="icon"> <i class="fa icon-warning" title="Warning"></i> </td> <td class="content"> Raku guarantees that the order of the results is the same as that of the original list. However, there is <strong>no guarantee</strong> that Raku will actually call the methods in list order or in the same thread. So, be careful with methods that have side-effects, such as <code>say</code> or <code>print</code>. </td> </tr> </table> </div> </div> <div class="sect2"> <h3 id="_junctions">8.6. Junctions</h3> <div class="paragraph"> <p>A <strong>junction</strong> is a logical superposition of values.</p> </div> <div class="paragraph"> <p>In the below example <code>1|2|3</code> is a junction.</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">$var</span> = <span class="tok-mi">2</span>; <span class="tok-k">if</span> <span class="tok-nv">$var</span> == <span class="tok-mi">1</span><span class="tok-o">|</span><span class="tok-mi">2</span><span class="tok-o">|</span><span class="tok-mi">3</span> { <span class="tok-nb">say</span> <span class="tok-s">"The variable is 1 or 2 or 3"</span> }</code></pre> </div> </div> <div class="paragraph"> <p>The use of junctions usually triggers <strong>autothreading</strong>; the operation is carried out for each junction element, and all the results are combined into a new junction and returned.</p> </div> </div> <div class="sect2"> <h3 id="_lazy_lists">8.7. Lazy Lists</h3> <div class="paragraph"> <p>A <strong>lazy list</strong> is a list that is lazily evaluated.<br> Lazy evaluation delays the evaluation of an expression until required, and avoids repeating evaluations by storing results in a lookup table.</p> </div> <div class="paragraph"> <p>The benefits include:</p> </div> <div class="ulist"> <ul> <li> <p>Performance increase by avoiding needless calculations</p> </li> <li> <p>The ability to construct potentially infinite data structures</p> </li> <li> <p>The ability to define control flow</p> </li> </ul> </div> <div class="paragraph"> <p>To build a lazy list we use the infix operator <code>…​</code><br> A lazy list has <strong>initial element(s)</strong>, a <strong>generator</strong> and an <strong>endpoint</strong>.</p> </div> <div class="listingblock"> <div class="title">Simple lazy list</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">$lazylist</span> = (<span class="tok-mi">1</span> ... <span class="tok-mi">10</span>); <span class="tok-nb">say</span> <span class="tok-nv">$lazylist</span>;</code></pre> </div> </div> <div class="paragraph"> <p>The initial element is 1 and the endpoint is 10. No generator was defined so the default generator is the successor (+1)<br> In other words this lazy list may return (if requested) the following elements (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)</p> </div> <div class="listingblock"> <div class="title">Infinite lazy list</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">$lazylist</span> = (<span class="tok-mi">1</span> ... <span class="tok-n">Inf</span>); <span class="tok-nb">say</span> <span class="tok-nv">$lazylist</span>;</code></pre> </div> </div> <div class="paragraph"> <p>This list may return (if requested) any integer between 1 and infinity, in other words any integer number.</p> </div> <div class="listingblock"> <div class="title">Lazy list built using a deduced generator</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">$lazylist</span> = (<span class="tok-mi">0</span>,<span class="tok-mi">2</span> ... <span class="tok-mi">10</span>); <span class="tok-nb">say</span> <span class="tok-nv">$lazylist</span>;</code></pre> </div> </div> <div class="paragraph"> <p>The initial elements are 0 and 2 and the endpoint is 10. No generator was defined, but using the initial elements, Raku will deduce that the generator is (+2)<br> This lazy list may return (if requested) the following elements (0, 2, 4, 6, 8, 10)</p> </div> <div class="listingblock"> <div class="title">Lazy list built using a defined generator</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">$lazylist</span> = (<span class="tok-mi">0</span>, { <span class="tok-nv">$_</span> + <span class="tok-mi">3</span> } ... <span class="tok-mi">12</span>); <span class="tok-nb">say</span> <span class="tok-nv">$lazylist</span>;</code></pre> </div> </div> <div class="paragraph"> <p>In this example, we defined explicitly a generator enclosed in <code>{ }</code><br> This lazy list may return (if requested) the following elements (0, 3, 6, 9, 12)</p> </div> <div class="admonitionblock warning"> <table> <tr> <td class="icon"> <i class="fa icon-warning" title="Warning"></i> </td> <td class="content"> <div class="paragraph"> <p>When using an explicit generator, the endpoint must be one of the values that the generator can return.<br> If we reproduce the above example with the endpoint being 10 instead of 12, it will not stop. The generator <em>jumps over</em> the endpoint.</p> </div> <div class="paragraph"> <p>Alternatively you can replace <code>0 …​ 10</code> with <code>0 …​^ * > 10</code><br> You can read it as: From 0 until the first value greater than 10 (excluding it)</p> </div> <div class="listingblock"> <div class="title">This will not stop the generator</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">$lazylist</span> = (<span class="tok-mi">0</span>, { <span class="tok-nv">$_</span> + <span class="tok-mi">3</span> } ... <span class="tok-mi">10</span>); <span class="tok-nb">say</span> <span class="tok-nv">$lazylist</span>;</code></pre> </div> </div> <div class="listingblock"> <div class="title">This will stop the generator</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">$lazylist</span> = (<span class="tok-mi">0</span>, { <span class="tok-nv">$_</span> + <span class="tok-mi">3</span> } ...^ * > <span class="tok-mi">10</span>); <span class="tok-nb">say</span> <span class="tok-nv">$lazylist</span>;</code></pre> </div> </div> </td> </tr> </table> </div> </div> <div class="sect2"> <h3 id="_closures">8.8. Closures</h3> <div class="paragraph"> <p>All code objects in Raku are closures, which means they can reference lexical variables from an outer scope.</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">sub</span> <span class="tok-n">generate-greeting</span> { <span class="tok-k">my</span> <span class="tok-nv">$name</span> = <span class="tok-s">"John Doe"</span>; <span class="tok-k">sub</span> <span class="tok-n">greeting</span> { <span class="tok-nb">say</span> <span class="tok-s">"Good Morning $name"</span>; }; <span class="tok-k">return</span> <span class="tok-nv">&greeting</span>; } <span class="tok-k">my</span> <span class="tok-nv">$generated</span> = <span class="tok-n">generate-greeting</span>; <span class="tok-nv">$generated</span>();</code></pre> </div> </div> <div class="paragraph"> <p>If you run the above code, it will display <code>Good Morning John Doe</code> on the terminal.<br> While the result is fairly simple, what is interesting about this example, is that the <code>greeting</code> inner subroutine was returned from the outer subroutine before being executed.</p> </div> <div class="paragraph"> <p><code>$generated</code> has become a <strong>closure</strong>.</p> </div> <div class="paragraph"> <p>A <strong>closure</strong> is a special kind of object that combines two things:</p> </div> <div class="ulist"> <ul> <li> <p>A Subroutine</p> </li> <li> <p>The Environment in which that subroutine was created.</p> </li> </ul> </div> <div class="paragraph"> <p>The environment consists of any local variable that was in-scope at the time that the closure was created. In this case, <code>$generated</code> is a closure that incorporates both the <code>greeting</code> subroutine and the <code>John Doe</code> string that existed when the closure was created.</p> </div> <div class="paragraph"> <p>Let’s take a look at a more interesting example.</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">sub</span> <span class="tok-n">greeting-generator</span>(<span class="tok-nv">$period</span>) { <span class="tok-k">return</span> <span class="tok-k">sub</span> (<span class="tok-nv">$name</span>) { <span class="tok-k">return</span> <span class="tok-s">"Good $period $name"</span> } } <span class="tok-k">my</span> <span class="tok-nv">$morning</span> = <span class="tok-n">greeting-generator</span>(<span class="tok-s">"Morning"</span>); <span class="tok-k">my</span> <span class="tok-nv">$evening</span> = <span class="tok-n">greeting-generator</span>(<span class="tok-s">"Evening"</span>); <span class="tok-nb">say</span> <span class="tok-nv">$morning</span>(<span class="tok-s">"John"</span>); <span class="tok-nb">say</span> <span class="tok-nv">$evening</span>(<span class="tok-s">"Jane"</span>);</code></pre> </div> </div> <div class="paragraph"> <p>In this example, we have defined a subroutine <code>greeting-generator($period)</code> that accepts a single argument <code>$period</code> and returns a new subroutine. The subroutine it returns accepts a single argument <code>$name</code> and returns the constructed greeting.</p> </div> <div class="paragraph"> <p>Basically, <code>greeting-generator</code> is a subroutine factory. In this example, we used <code>greeting-generator</code> to create two new subroutines, one that says <code>Good Morning</code> and one that says <code>Good Evening</code>.</p> </div> <div class="paragraph"> <p><code>$morning</code> and <code>$evening</code> are both closures. They share the same subroutine body definition, but store different environments.<br> In <code>$morning</code> 's environment <code>$period</code> is <code>Morning</code>. In <code>$evening</code> 's environment <code>$period</code> is <code>Evening</code>.</p> </div> </div> </div> </div> <div class="sect1"> <h2 id="_classes_objects">9. Classes & Objects</h2> <div class="sectionbody"> <div class="paragraph"> <p>In the previous chapter, we learned how Raku facilitates Functional Programming.<br> In this chapter we will take a look at Object Oriented programming in Raku.</p> </div> <div class="sect2"> <h3 id="_introduction_2">9.1. Introduction</h3> <div class="paragraph"> <p><em>Object Oriented</em> programming is one of the widely used paradigms nowadays.<br> An <strong>object</strong> is a set of variables and subroutines bundled together.<br> The variables are called <strong>attributes</strong> and the subroutines are called <strong>methods</strong>.<br> Attributes define the <strong>state</strong> and methods define the <strong>behavior</strong> of an object.</p> </div> <div class="paragraph"> <p>A <strong>class</strong> is a template for creating <strong>objects</strong>.<br></p> </div> <div class="paragraph"> <p>In order to understand the relationship consider the below example:</p> </div> <table class="tableblock frame-all grid-all stretch"> <colgroup> <col style="width: 50%;"> <col style="width: 50%;"> </colgroup> <tbody> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">There are 4 people present in a room</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>objects</strong> ⇒ 4 people</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">These 4 people are humans</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>class</strong> ⇒ Human</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">They have different names, age, sex and nationality</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>attributes</strong> ⇒ name, age, sex, nationality</p></td> </tr> </tbody> </table> <div class="paragraph"> <p>In <em>object oriented</em> parlance, we say that objects are <strong>instances</strong> of a class.</p> </div> <div class="paragraph"> <p>Consider the below script:</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">class</span> <span class="tok-n">Human</span> { <span class="tok-k">has</span> <span class="tok-nv">$.name</span>; <span class="tok-k">has</span> <span class="tok-nv">$.age</span>; <span class="tok-k">has</span> <span class="tok-nv">$.sex</span>; <span class="tok-k">has</span> <span class="tok-nv">$.nationality</span>; } <span class="tok-k">my</span> <span class="tok-nv">$john</span> = <span class="tok-n">Human</span>.<span class="tok-nb">new</span>(<span class="tok-nb">name</span> => <span class="tok-s">'John'</span>, <span class="tok-n">age</span> => <span class="tok-mi">23</span>, <span class="tok-n">sex</span> => <span class="tok-s">'M'</span>, <span class="tok-n">nationality</span> => <span class="tok-s">'American'</span>); <span class="tok-nb">say</span> <span class="tok-nv">$john</span>;</code></pre> </div> </div> <div class="paragraph"> <p>The <code>class</code> keyword is used to define a class.<br> The <code>has</code> keyword is used to define attributes of a class.<br> The <code>.new()</code> method is called a <strong>constructor</strong>. It creates the object as an instance of the class it has been called on.</p> </div> <div class="paragraph"> <p>In the above script, a new variable <code>$john</code> holds a reference to a new instance of "Human" defined by <code>Human.new()</code>.<br> The arguments passed to the <code>.new()</code> method are used to set the attributes of the underlying object.</p> </div> <div class="paragraph"> <p>A class can be given <em>lexical scope</em> using <code>my</code>:</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-k">class</span> <span class="tok-n">Human</span> { }</code></pre> </div> </div> </div> <div class="sect2"> <h3 id="_encapsulation">9.2. Encapsulation</h3> <div class="paragraph"> <p>Encapsulation is an object oriented concept that bundles a set of data and methods together.<br> The data (attributes) within an object should be <strong>private</strong>, in other words, accessible only from within the object.<br> In order to access the attributes from outside the object, we use methods called <strong>accessors</strong>.</p> </div> <div class="paragraph"> <p>The below two scripts have the same result.</p> </div> <div class="listingblock"> <div class="title">Direct access to the variable:</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">$var</span> = <span class="tok-mi">7</span>; <span class="tok-nb">say</span> <span class="tok-nv">$var</span>;</code></pre> </div> </div> <div class="listingblock"> <div class="title">Encapsulation:</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">$var</span> = <span class="tok-mi">7</span>; <span class="tok-k">sub</span> <span class="tok-n">sayvar</span> { <span class="tok-nv">$var</span>; } <span class="tok-nb">say</span> <span class="tok-n">sayvar</span>;</code></pre> </div> </div> <div class="paragraph"> <p>The method <code>sayvar</code> is an accessor. It lets us access the value of the variable without getting direct access to it.</p> </div> <div class="paragraph"> <p>Encapsulation is facilitated in Raku with the use of <strong>twigils</strong>.<br> Twigils are secondary <em>sigils</em>. They come between the sigil and the attribute name.<br> Two twigils are used in classes:</p> </div> <div class="ulist"> <ul> <li> <p><code>!</code> is used to explicitly declare that the attribute is private.</p> </li> <li> <p><code>.</code> is used to automatically generate an accessor for the attribute.</p> </li> </ul> </div> <div class="paragraph"> <p>By default, all attributes are private but it is a good habit to always use the <code>!</code> twigil.</p> </div> <div class="paragraph"> <p>Therefore, we should rewrite the above class as:</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">class</span> <span class="tok-n">Human</span> { <span class="tok-k">has</span> <span class="tok-nv">$!name</span>; <span class="tok-k">has</span> <span class="tok-nv">$!age</span>; <span class="tok-k">has</span> <span class="tok-nv">$!sex</span>; <span class="tok-k">has</span> <span class="tok-nv">$!nationality</span>; } <span class="tok-k">my</span> <span class="tok-nv">$john</span> = <span class="tok-n">Human</span>.<span class="tok-nb">new</span>(<span class="tok-nb">name</span> => <span class="tok-s">'John'</span>, <span class="tok-n">age</span> => <span class="tok-mi">23</span>, <span class="tok-n">sex</span> => <span class="tok-s">'M'</span>, <span class="tok-n">nationality</span> => <span class="tok-s">'American'</span>); <span class="tok-nb">say</span> <span class="tok-nv">$john</span>;</code></pre> </div> </div> <div class="paragraph"> <p>Append to the script the following statement: <code>say $john.age;</code><br> It will return this error: <code>Method 'age' not found for invocant of class 'Human'</code> because <code>$!age</code> is private and can only be used within the object. Trying to access it outside the object will return an error.</p> </div> <div class="paragraph"> <p>Now replace <code>has $!age</code> with <code>has $.age</code> and observe the result of <code>say $john.age;</code></p> </div> </div> <div class="sect2"> <h3 id="_named_vs_positional_parameters">9.3. Named vs. Positional Parameters</h3> <div class="paragraph"> <p>In Raku, all classes inherit a default <code>.new()</code> constructor.<br> It can be used to create objects by providing it with arguments.<br> The default constructor can only be provided with <strong>named arguments</strong>.<br> In our example above, notice that the arguments supplied to <code>.new()</code> are defined by name:</p> </div> <div class="ulist"> <ul> <li> <p>name => 'John'</p> </li> <li> <p>age => 23</p> </li> </ul> </div> <div class="paragraph"> <p>What if I do not want to supply the name of each attribute each time I want to create an object?<br> Then I need to create another constructor that accepts <strong>positional arguments</strong>.</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">class</span> <span class="tok-n">Human</span> { <span class="tok-k">has</span> <span class="tok-nv">$.name</span>; <span class="tok-k">has</span> <span class="tok-nv">$.age</span>; <span class="tok-k">has</span> <span class="tok-nv">$.sex</span>; <span class="tok-k">has</span> <span class="tok-nv">$.nationality</span>; <span class="tok-c1"># new constructor that overrides the default one.</span> <span class="tok-k">method</span> <span class="tok-nb">new</span> (<span class="tok-nv">$name</span>,<span class="tok-nv">$age</span>,<span class="tok-nv">$sex</span>,<span class="tok-nv">$nationality</span>) { <span class="tok-nb">self</span>.<span class="tok-nb">bless</span>(:<span class="tok-nv">$name</span>,:<span class="tok-nv">$age</span>,:<span class="tok-nv">$sex</span>,:<span class="tok-nv">$nationality</span>); } } <span class="tok-k">my</span> <span class="tok-nv">$john</span> = <span class="tok-n">Human</span>.<span class="tok-nb">new</span>(<span class="tok-s">'John'</span>,<span class="tok-mi">23</span>,<span class="tok-s">'M'</span>,<span class="tok-s">'American'</span>); <span class="tok-nb">say</span> <span class="tok-nv">$john</span>;</code></pre> </div> </div> </div> <div class="sect2"> <h3 id="_methods">9.4. Methods</h3> <div class="sect3"> <h4 id="_introduction_3">9.4.1. Introduction</h4> <div class="paragraph"> <p>Methods are the <em>subroutines</em> of an object.<br> Like subroutines, they are a means of packaging a set of functionality, they accept <strong>arguments</strong>, have a <strong>signature</strong> and can be defined as <strong>multi</strong>.</p> </div> <div class="paragraph"> <p>Methods are defined using the <code>method</code> keyword.<br> In normal circumstances, methods are required to perform some sort of action on the objects' attributes. This enforces the concept of encapsulation. Object attributes can only be manipulated from within the object using methods. The outside world can only interact with the object methods, and has no direct access to its attributes.</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">class</span> <span class="tok-n">Human</span> { <span class="tok-k">has</span> <span class="tok-nv">$.name</span>; <span class="tok-k">has</span> <span class="tok-nv">$.age</span>; <span class="tok-k">has</span> <span class="tok-nv">$.sex</span>; <span class="tok-k">has</span> <span class="tok-nv">$.nationality</span>; <span class="tok-k">has</span> <span class="tok-nv">$.eligible</span>; <span class="tok-k">method</span> <span class="tok-n">assess-eligibility</span> { <span class="tok-k">if</span> <span class="tok-nb">self</span>.<span class="tok-n">age</span> < <span class="tok-mi">21</span> { <span class="tok-nv">$!eligible</span> = <span class="tok-s">'No'</span> } <span class="tok-k">else</span> { <span class="tok-nv">$!eligible</span> = <span class="tok-s">'Yes'</span> } } } <span class="tok-k">my</span> <span class="tok-nv">$john</span> = <span class="tok-n">Human</span>.<span class="tok-nb">new</span>(<span class="tok-nb">name</span> => <span class="tok-s">'John'</span>, <span class="tok-n">age</span> => <span class="tok-mi">23</span>, <span class="tok-n">sex</span> => <span class="tok-s">'M'</span>, <span class="tok-n">nationality</span> => <span class="tok-s">'American'</span>); <span class="tok-nv">$john</span>.<span class="tok-n">assess-eligibility</span>; <span class="tok-nb">say</span> <span class="tok-nv">$john</span>.<span class="tok-n">eligible</span>;</code></pre> </div> </div> <div class="paragraph"> <p>Once methods are defined within a class, they can be called on an object using the <em>dot notation</em>:<br> <em>object</em> <strong>.</strong> <em>method</em> or as in the above example: <code>$john.assess-eligibility</code></p> </div> <div class="paragraph"> <p>Within the definition of a method, if we need to reference the object itself to call another method we use the <code>self</code> keyword.<br></p> </div> <div class="paragraph"> <p>Within the definition of a method, if we need to reference an attribute we use <code>!</code> even if it was defined with <code>.</code><br> The rationale being that what the <code>.</code> twigil does is declare an attribute with <code>!</code> and automate the creation of an accessor.</p> </div> <div class="paragraph"> <p>In the above example, <code>if self.age < 21</code> and <code>if $!age < 21</code> would have the same effect, although they are technically different:</p> </div> <div class="ulist"> <ul> <li> <p><code>self.age</code> calls the <code>.age</code> method (accessor)<br> Can be written alternatively as <code>$.age</code></p> </li> <li> <p><code>$!age</code> is a direct call to the variable</p> </li> </ul> </div> </div> <div class="sect3"> <h4 id="_private_methods">9.4.2. Private methods</h4> <div class="paragraph"> <p>Normal methods can be called on objects from outside the class.</p> </div> <div class="paragraph"> <p><strong>Private methods</strong> are methods that can only be called from within the class.<br> A possible use case would be a method that calls another one for specific action. The method that interfaces with the outside world is public while the one referenced should stay private. We do not want users to call it directly, so we declare it as private.</p> </div> <div class="paragraph"> <p>The declaration of a private method requires the use of the <code>!</code> twigil before its name.<br> Private methods are called with <code>!</code> instead of <code>.</code></p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">method</span> !<span class="tok-n">iamprivate</span> { <span class="tok-c1"># code goes in here</span> } <span class="tok-k">method</span> <span class="tok-n">iampublic</span> { <span class="tok-nb">self</span><span class="tok-o">!</span><span class="tok-n">iamprivate</span>; <span class="tok-c1"># do additional things</span> }</code></pre> </div> </div> </div> </div> <div class="sect2"> <h3 id="_class_attributes">9.5. Class Attributes</h3> <div class="paragraph"> <p><strong>Class attributes</strong> are attributes that belong to the class itself and not to its objects.<br> They can be initialized during definition.<br> Class attributes are declared using <code>my</code> instead of <code>has</code>.<br> They are called on the class itself instead of its objects.</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">class</span> <span class="tok-n">Human</span> { <span class="tok-k">has</span> <span class="tok-nv">$.name</span>; <span class="tok-k">my</span> <span class="tok-nv">$.counter</span> = <span class="tok-mi">0</span>; <span class="tok-k">method</span> <span class="tok-nb">new</span>(<span class="tok-nv">$name</span>) { <span class="tok-n">Human</span>.<span class="tok-n">counter</span>++; <span class="tok-nb">self</span>.<span class="tok-nb">bless</span>(:<span class="tok-nv">$name</span>); } } <span class="tok-k">my</span> <span class="tok-nv">$a</span> = <span class="tok-n">Human</span>.<span class="tok-nb">new</span>(<span class="tok-s">'a'</span>); <span class="tok-k">my</span> <span class="tok-nv">$b</span> = <span class="tok-n">Human</span>.<span class="tok-nb">new</span>(<span class="tok-s">'b'</span>); <span class="tok-nb">say</span> <span class="tok-n">Human</span>.<span class="tok-n">counter</span>;</code></pre> </div> </div> </div> <div class="sect2"> <h3 id="_access_type">9.6. Access Type</h3> <div class="paragraph"> <p>Until now, all the examples that we’ve seen have used accessors to <strong>get</strong> information from the objects' attributes.</p> </div> <div class="paragraph"> <p>What if we need to modify the value of an attribute?<br> We need to label it as <em>read/write</em> using the keywords <code>is rw</code></p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">class</span> <span class="tok-n">Human</span> { <span class="tok-k">has</span> <span class="tok-nv">$.name</span>; <span class="tok-k">has</span> <span class="tok-nv">$.age</span> <span class="tok-k">is</span> <span class="tok-k">rw</span>; } <span class="tok-k">my</span> <span class="tok-nv">$john</span> = <span class="tok-n">Human</span>.<span class="tok-nb">new</span>(<span class="tok-nb">name</span> => <span class="tok-s">'John'</span>, <span class="tok-n">age</span> => <span class="tok-mi">21</span>); <span class="tok-nb">say</span> <span class="tok-nv">$john</span>.<span class="tok-n">age</span>; <span class="tok-nv">$john</span>.<span class="tok-n">age</span> = <span class="tok-mi">23</span>; <span class="tok-nb">say</span> <span class="tok-nv">$john</span>.<span class="tok-n">age</span>;</code></pre> </div> </div> <div class="paragraph"> <p>By default, all attributes are declared as <em>read only</em> but you can explicitly do it using <code>is readonly</code></p> </div> </div> <div class="sect2"> <h3 id="_inheritance">9.7. Inheritance</h3> <div class="sect3"> <h4 id="_introduction_4">9.7.1. Introduction</h4> <div class="paragraph"> <p><strong>Inheritance</strong> is another concept of object oriented programming.</p> </div> <div class="paragraph"> <p>When defining classes, soon enough we will realize that some attributes/methods are common to many classes.<br> Should we duplicate code?<br> NO! We should use <strong>inheritance</strong></p> </div> <div class="paragraph"> <p>Let’s consider we want to define two classes, a class for Human beings and a class for Employees.<br> Human beings have 2 attributes: name and age.<br> Employees have 4 attributes: name, age, company and salary</p> </div> <div class="paragraph"> <p>One would be tempted to define the classes as:</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">class</span> <span class="tok-n">Human</span> { <span class="tok-k">has</span> <span class="tok-nv">$.name</span>; <span class="tok-k">has</span> <span class="tok-nv">$.age</span>; } <span class="tok-k">class</span> <span class="tok-n">Employee</span> { <span class="tok-k">has</span> <span class="tok-nv">$.name</span>; <span class="tok-k">has</span> <span class="tok-nv">$.age</span>; <span class="tok-k">has</span> <span class="tok-nv">$.company</span>; <span class="tok-k">has</span> <span class="tok-nv">$.salary</span>; }</code></pre> </div> </div> <div class="paragraph"> <p>While technically correct, the above piece of code is considered conceptually poor.</p> </div> <div class="paragraph"> <p>A better way to write this would be:</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">class</span> <span class="tok-n">Human</span> { <span class="tok-k">has</span> <span class="tok-nv">$.name</span>; <span class="tok-k">has</span> <span class="tok-nv">$.age</span>; } <span class="tok-k">class</span> <span class="tok-n">Employee</span> <span class="tok-k">is</span> <span class="tok-n">Human</span> { <span class="tok-k">has</span> <span class="tok-nv">$.company</span>; <span class="tok-k">has</span> <span class="tok-nv">$.salary</span>; }</code></pre> </div> </div> <div class="paragraph"> <p>The <code>is</code> keyword defines inheritance.<br> In object oriented parlance, we say Employee is a <strong>child</strong> of Human and that Human is a <strong>parent</strong> of Employee.</p> </div> <div class="paragraph"> <p>All child classes inherit the attributes and methods of the parent class, so there is no need to redefine them.</p> </div> </div> <div class="sect3"> <h4 id="_overriding">9.7.2. Overriding</h4> <div class="paragraph"> <p>Classes inherit all attributes and methods from their parent classes.<br> There are cases where we need the method in the child class to behave differently than the one inherited.<br> To achieve this, we redefine the method in the child class.<br> This concept is called <strong>overriding</strong>.</p> </div> <div class="paragraph"> <p>In the below example, the method <code>introduce-yourself</code> is inherited by the Employee class.</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">class</span> <span class="tok-n">Human</span> { <span class="tok-k">has</span> <span class="tok-nv">$.name</span>; <span class="tok-k">has</span> <span class="tok-nv">$.age</span>; <span class="tok-k">method</span> <span class="tok-n">introduce-yourself</span> { <span class="tok-nb">say</span> <span class="tok-s">'Hi I am a human being, my name is '</span> ~ <span class="tok-nb">self</span>.<span class="tok-nb">name</span>; } } <span class="tok-k">class</span> <span class="tok-n">Employee</span> <span class="tok-k">is</span> <span class="tok-n">Human</span> { <span class="tok-k">has</span> <span class="tok-nv">$.company</span>; <span class="tok-k">has</span> <span class="tok-nv">$.salary</span>; } <span class="tok-k">my</span> <span class="tok-nv">$john</span> = <span class="tok-n">Human</span>.<span class="tok-nb">new</span>(<span class="tok-nb">name</span> =><span class="tok-s">'John'</span>, <span class="tok-n">age</span> => <span class="tok-mi">23</span>,); <span class="tok-k">my</span> <span class="tok-nv">$jane</span> = <span class="tok-n">Employee</span>.<span class="tok-nb">new</span>(<span class="tok-nb">name</span> =><span class="tok-s">'Jane'</span>, <span class="tok-n">age</span> => <span class="tok-mi">25</span>, <span class="tok-n">company</span> => <span class="tok-s">'Acme'</span>, <span class="tok-n">salary</span> => <span class="tok-mi">4000</span>); <span class="tok-nv">$john</span>.<span class="tok-n">introduce-yourself</span>; <span class="tok-nv">$jane</span>.<span class="tok-n">introduce-yourself</span>;</code></pre> </div> </div> <div class="paragraph"> <p>Overriding works like this:</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">class</span> <span class="tok-n">Human</span> { <span class="tok-k">has</span> <span class="tok-nv">$.name</span>; <span class="tok-k">has</span> <span class="tok-nv">$.age</span>; <span class="tok-k">method</span> <span class="tok-n">introduce-yourself</span> { <span class="tok-nb">say</span> <span class="tok-s">'Hi I am a human being, my name is '</span> ~ <span class="tok-nb">self</span>.<span class="tok-nb">name</span>; } } <span class="tok-k">class</span> <span class="tok-n">Employee</span> <span class="tok-k">is</span> <span class="tok-n">Human</span> { <span class="tok-k">has</span> <span class="tok-nv">$.company</span>; <span class="tok-k">has</span> <span class="tok-nv">$.salary</span>; <span class="tok-k">method</span> <span class="tok-n">introduce-yourself</span> { <span class="tok-nb">say</span> <span class="tok-s">'Hi I am a employee, my name is '</span> ~ <span class="tok-nb">self</span>.<span class="tok-nb">name</span> ~ <span class="tok-s">' and I work at: '</span> ~ <span class="tok-nb">self</span>.<span class="tok-n">company</span>; } } <span class="tok-k">my</span> <span class="tok-nv">$john</span> = <span class="tok-n">Human</span>.<span class="tok-nb">new</span>(<span class="tok-nb">name</span> =><span class="tok-s">'John'</span>,<span class="tok-n">age</span> => <span class="tok-mi">23</span>,); <span class="tok-k">my</span> <span class="tok-nv">$jane</span> = <span class="tok-n">Employee</span>.<span class="tok-nb">new</span>(<span class="tok-nb">name</span> =><span class="tok-s">'Jane'</span>,<span class="tok-n">age</span> => <span class="tok-mi">25</span>,<span class="tok-n">company</span> => <span class="tok-s">'Acme'</span>,<span class="tok-n">salary</span> => <span class="tok-mi">4000</span>); <span class="tok-nv">$john</span>.<span class="tok-n">introduce-yourself</span>; <span class="tok-nv">$jane</span>.<span class="tok-n">introduce-yourself</span>;</code></pre> </div> </div> <div class="paragraph"> <p>Depending of which class the object is, the right method will be called.</p> </div> </div> <div class="sect3"> <h4 id="_submethods">9.7.3. Submethods</h4> <div class="paragraph"> <p><strong>Submethods</strong> are a type of method that are not inherited by child classes.<br> They are only accessible from the class they were declared in.<br> They are defined using the <code>submethod</code> keyword.</p> </div> </div> </div> <div class="sect2"> <h3 id="_multiple_inheritance">9.8. Multiple Inheritance</h3> <div class="paragraph"> <p>Multiple inheritance is allowed in Raku. A class can inherit from multiple other classes.</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">class</span> <span class="tok-n">bar-chart</span> { <span class="tok-k">has</span> <span class="tok-nb">Int</span> <span class="tok-nv">@.bar-values</span>; <span class="tok-k">method</span> <span class="tok-n">plot</span> { <span class="tok-nb">say</span> <span class="tok-nv">@.bar-values</span>; } } <span class="tok-k">class</span> <span class="tok-n">line-chart</span> { <span class="tok-k">has</span> <span class="tok-nb">Int</span> <span class="tok-nv">@.line-values</span>; <span class="tok-k">method</span> <span class="tok-n">plot</span> { <span class="tok-nb">say</span> <span class="tok-nv">@.line-values</span>; } } <span class="tok-k">class</span> <span class="tok-n">combo-chart</span> <span class="tok-k">is</span> <span class="tok-n">bar-chart</span> <span class="tok-k">is</span> <span class="tok-n">line-chart</span> { } <span class="tok-k">my</span> <span class="tok-nv">$actual-sales</span> = <span class="tok-n">bar-chart</span>.<span class="tok-nb">new</span>(<span class="tok-n">bar-values</span> => [<span class="tok-mi">10</span>,<span class="tok-mi">9</span>,<span class="tok-mi">11</span>,<span class="tok-mi">8</span>,<span class="tok-mi">7</span>,<span class="tok-mi">10</span>]); <span class="tok-k">my</span> <span class="tok-nv">$forecast-sales</span> = <span class="tok-n">line-chart</span>.<span class="tok-nb">new</span>(<span class="tok-n">line-values</span> => [<span class="tok-mi">9</span>,<span class="tok-mi">8</span>,<span class="tok-mi">10</span>,<span class="tok-mi">7</span>,<span class="tok-mi">6</span>,<span class="tok-mi">9</span>]); <span class="tok-k">my</span> <span class="tok-nv">$actual-vs-forecast</span> = <span class="tok-n">combo-chart</span>.<span class="tok-nb">new</span>(<span class="tok-n">bar-values</span> => [<span class="tok-mi">10</span>,<span class="tok-mi">9</span>,<span class="tok-mi">11</span>,<span class="tok-mi">8</span>,<span class="tok-mi">7</span>,<span class="tok-mi">10</span>], <span class="tok-n">line-values</span> => [<span class="tok-mi">9</span>,<span class="tok-mi">8</span>,<span class="tok-mi">10</span>,<span class="tok-mi">7</span>,<span class="tok-mi">6</span>,<span class="tok-mi">9</span>]); <span class="tok-nb">say</span> <span class="tok-s">"Actual sales:"</span>; <span class="tok-nv">$actual-sales</span>.<span class="tok-n">plot</span>; <span class="tok-nb">say</span> <span class="tok-s">"Forecast sales:"</span>; <span class="tok-nv">$forecast-sales</span>.<span class="tok-n">plot</span>; <span class="tok-nb">say</span> <span class="tok-s">"Actual vs Forecast:"</span>; <span class="tok-nv">$actual-vs-forecast</span>.<span class="tok-n">plot</span>;</code></pre> </div> </div> <div class="listingblock"> <div class="title"><code>Output</code></div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-n">Actual</span> <span class="tok-n">sales:</span> [<span class="tok-mi">10</span> <span class="tok-mi">9</span> <span class="tok-mi">11</span> <span class="tok-mi">8</span> <span class="tok-mi">7</span> <span class="tok-mi">10</span>] <span class="tok-n">Forecast</span> <span class="tok-n">sales:</span> [<span class="tok-mi">9</span> <span class="tok-mi">8</span> <span class="tok-mi">10</span> <span class="tok-mi">7</span> <span class="tok-mi">6</span> <span class="tok-mi">9</span>] <span class="tok-n">Actual</span> <span class="tok-n">vs</span> <span class="tok-n">Forecast:</span> [<span class="tok-mi">10</span> <span class="tok-mi">9</span> <span class="tok-mi">11</span> <span class="tok-mi">8</span> <span class="tok-mi">7</span> <span class="tok-mi">10</span>]</code></pre> </div> </div> <div class="paragraph"> <div class="title">Explanation</div> <p>The <code>combo-chart</code> class should be able to hold two series, one for the actual values plotted on bars, and another for forecast values plotted on a line.<br> This is why we defined it as a child of <code>line-chart</code> and <code>bar-chart</code>.<br> You should have noticed that calling the method <code>plot</code> on the <code>combo-chart</code> didn’t yield the required result. Only one series was plotted.<br> Why did this happen?<br> <code>combo-chart</code> inherits from <code>line-chart</code> and <code>bar-chart</code>, and both of them have a method called <code>plot</code>. When we call that method on <code>combo-chart</code> Raku internals will try to resolve the conflict by calling one of the inherited methods.</p> </div> <div class="paragraph"> <div class="title">Correction</div> <p>In order to behave correctly, we should have overridden the method <code>plot</code> in the <code>combo-chart</code>.</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">class</span> <span class="tok-n">bar-chart</span> { <span class="tok-k">has</span> <span class="tok-nb">Int</span> <span class="tok-nv">@.bar-values</span>; <span class="tok-k">method</span> <span class="tok-n">plot</span> { <span class="tok-nb">say</span> <span class="tok-nv">@.bar-values</span>; } } <span class="tok-k">class</span> <span class="tok-n">line-chart</span> { <span class="tok-k">has</span> <span class="tok-nb">Int</span> <span class="tok-nv">@.line-values</span>; <span class="tok-k">method</span> <span class="tok-n">plot</span> { <span class="tok-nb">say</span> <span class="tok-nv">@.line-values</span>; } } <span class="tok-k">class</span> <span class="tok-n">combo-chart</span> <span class="tok-k">is</span> <span class="tok-n">bar-chart</span> <span class="tok-k">is</span> <span class="tok-n">line-chart</span> { <span class="tok-k">method</span> <span class="tok-n">plot</span> { <span class="tok-nb">say</span> <span class="tok-nv">@.bar-values</span>; <span class="tok-nb">say</span> <span class="tok-nv">@.line-values</span>; } } <span class="tok-k">my</span> <span class="tok-nv">$actual-sales</span> = <span class="tok-n">bar-chart</span>.<span class="tok-nb">new</span>(<span class="tok-n">bar-values</span> => [<span class="tok-mi">10</span>,<span class="tok-mi">9</span>,<span class="tok-mi">11</span>,<span class="tok-mi">8</span>,<span class="tok-mi">7</span>,<span class="tok-mi">10</span>]); <span class="tok-k">my</span> <span class="tok-nv">$forecast-sales</span> = <span class="tok-n">line-chart</span>.<span class="tok-nb">new</span>(<span class="tok-n">line-values</span> => [<span class="tok-mi">9</span>,<span class="tok-mi">8</span>,<span class="tok-mi">10</span>,<span class="tok-mi">7</span>,<span class="tok-mi">6</span>,<span class="tok-mi">9</span>]); <span class="tok-k">my</span> <span class="tok-nv">$actual-vs-forecast</span> = <span class="tok-n">combo-chart</span>.<span class="tok-nb">new</span>(<span class="tok-n">bar-values</span> => [<span class="tok-mi">10</span>,<span class="tok-mi">9</span>,<span class="tok-mi">11</span>,<span class="tok-mi">8</span>,<span class="tok-mi">7</span>,<span class="tok-mi">10</span>], <span class="tok-n">line-values</span> => [<span class="tok-mi">9</span>,<span class="tok-mi">8</span>,<span class="tok-mi">10</span>,<span class="tok-mi">7</span>,<span class="tok-mi">6</span>,<span class="tok-mi">9</span>]); <span class="tok-nb">say</span> <span class="tok-s">"Actual sales:"</span>; <span class="tok-nv">$actual-sales</span>.<span class="tok-n">plot</span>; <span class="tok-nb">say</span> <span class="tok-s">"Forecast sales:"</span>; <span class="tok-nv">$forecast-sales</span>.<span class="tok-n">plot</span>; <span class="tok-nb">say</span> <span class="tok-s">"Actual vs Forecast:"</span>; <span class="tok-nv">$actual-vs-forecast</span>.<span class="tok-n">plot</span>;</code></pre> </div> </div> <div class="listingblock"> <div class="title"><code>Output</code></div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-n">Actual</span> <span class="tok-n">sales:</span> [<span class="tok-mi">10</span> <span class="tok-mi">9</span> <span class="tok-mi">11</span> <span class="tok-mi">8</span> <span class="tok-mi">7</span> <span class="tok-mi">10</span>] <span class="tok-n">Forecast</span> <span class="tok-n">sales:</span> [<span class="tok-mi">9</span> <span class="tok-mi">8</span> <span class="tok-mi">10</span> <span class="tok-mi">7</span> <span class="tok-mi">6</span> <span class="tok-mi">9</span>] <span class="tok-n">Actual</span> <span class="tok-n">vs</span> <span class="tok-n">Forecast:</span> [<span class="tok-mi">10</span> <span class="tok-mi">9</span> <span class="tok-mi">11</span> <span class="tok-mi">8</span> <span class="tok-mi">7</span> <span class="tok-mi">10</span>] [<span class="tok-mi">9</span> <span class="tok-mi">8</span> <span class="tok-mi">10</span> <span class="tok-mi">7</span> <span class="tok-mi">6</span> <span class="tok-mi">9</span>]</code></pre> </div> </div> </div> <div class="sect2"> <h3 id="_roles">9.9. Roles</h3> <div class="paragraph"> <p><strong>Roles</strong> are similar to classes in that they are a collection of attributes and methods.</p> </div> <div class="paragraph"> <p>Roles are declared with the keyword <code>role</code>. Classes that wish to implement a role, do so using the <code>does</code> keyword.</p> </div> <div class="listingblock"> <div class="title">Let’s rewrite the multiple inheritance example using roles:</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">role</span> <span class="tok-n">bar-chart</span> { <span class="tok-k">has</span> <span class="tok-nb">Int</span> <span class="tok-nv">@.bar-values</span>; <span class="tok-k">method</span> <span class="tok-n">plot</span> { <span class="tok-nb">say</span> <span class="tok-nv">@.bar-values</span>; } } <span class="tok-k">role</span> <span class="tok-n">line-chart</span> { <span class="tok-k">has</span> <span class="tok-nb">Int</span> <span class="tok-nv">@.line-values</span>; <span class="tok-k">method</span> <span class="tok-n">plot</span> { <span class="tok-nb">say</span> <span class="tok-nv">@.line-values</span>; } } <span class="tok-k">class</span> <span class="tok-n">combo-chart</span> <span class="tok-k">does</span> <span class="tok-n">bar-chart</span> <span class="tok-k">does</span> <span class="tok-n">line-chart</span> { <span class="tok-k">method</span> <span class="tok-n">plot</span> { <span class="tok-nb">say</span> <span class="tok-nv">@.bar-values</span>; <span class="tok-nb">say</span> <span class="tok-nv">@.line-values</span>; } } <span class="tok-k">my</span> <span class="tok-nv">$actual-sales</span> = <span class="tok-n">bar-chart</span>.<span class="tok-nb">new</span>(<span class="tok-n">bar-values</span> => [<span class="tok-mi">10</span>,<span class="tok-mi">9</span>,<span class="tok-mi">11</span>,<span class="tok-mi">8</span>,<span class="tok-mi">7</span>,<span class="tok-mi">10</span>]); <span class="tok-k">my</span> <span class="tok-nv">$forecast-sales</span> = <span class="tok-n">line-chart</span>.<span class="tok-nb">new</span>(<span class="tok-n">line-values</span> => [<span class="tok-mi">9</span>,<span class="tok-mi">8</span>,<span class="tok-mi">10</span>,<span class="tok-mi">7</span>,<span class="tok-mi">6</span>,<span class="tok-mi">9</span>]); <span class="tok-k">my</span> <span class="tok-nv">$actual-vs-forecast</span> = <span class="tok-n">combo-chart</span>.<span class="tok-nb">new</span>(<span class="tok-n">bar-values</span> => [<span class="tok-mi">10</span>,<span class="tok-mi">9</span>,<span class="tok-mi">11</span>,<span class="tok-mi">8</span>,<span class="tok-mi">7</span>,<span class="tok-mi">10</span>], <span class="tok-n">line-values</span> => [<span class="tok-mi">9</span>,<span class="tok-mi">8</span>,<span class="tok-mi">10</span>,<span class="tok-mi">7</span>,<span class="tok-mi">6</span>,<span class="tok-mi">9</span>]); <span class="tok-nb">say</span> <span class="tok-s">"Actual sales:"</span>; <span class="tok-nv">$actual-sales</span>.<span class="tok-n">plot</span>; <span class="tok-nb">say</span> <span class="tok-s">"Forecast sales:"</span>; <span class="tok-nv">$forecast-sales</span>.<span class="tok-n">plot</span>; <span class="tok-nb">say</span> <span class="tok-s">"Actual vs Forecast:"</span>; <span class="tok-nv">$actual-vs-forecast</span>.<span class="tok-n">plot</span>;</code></pre> </div> </div> <div class="paragraph"> <p>Run the above script and you will see that results are the same.</p> </div> <div class="paragraph"> <p>By now you’re asking yourself: If roles behave like classes, what’s their use?<br> To answer your question, modify the first script used to showcase multiple inheritance, the one where we <em>forgot</em> to override the <code>plot</code> method.</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">role</span> <span class="tok-n">bar-chart</span> { <span class="tok-k">has</span> <span class="tok-nb">Int</span> <span class="tok-nv">@.bar-values</span>; <span class="tok-k">method</span> <span class="tok-n">plot</span> { <span class="tok-nb">say</span> <span class="tok-nv">@.bar-values</span>; } } <span class="tok-k">role</span> <span class="tok-n">line-chart</span> { <span class="tok-k">has</span> <span class="tok-nb">Int</span> <span class="tok-nv">@.line-values</span>; <span class="tok-k">method</span> <span class="tok-n">plot</span> { <span class="tok-nb">say</span> <span class="tok-nv">@.line-values</span>; } } <span class="tok-k">class</span> <span class="tok-n">combo-chart</span> <span class="tok-k">does</span> <span class="tok-n">bar-chart</span> <span class="tok-k">does</span> <span class="tok-n">line-chart</span> { } <span class="tok-k">my</span> <span class="tok-nv">$actual-sales</span> = <span class="tok-n">bar-chart</span>.<span class="tok-nb">new</span>(<span class="tok-n">bar-values</span> => [<span class="tok-mi">10</span>,<span class="tok-mi">9</span>,<span class="tok-mi">11</span>,<span class="tok-mi">8</span>,<span class="tok-mi">7</span>,<span class="tok-mi">10</span>]); <span class="tok-k">my</span> <span class="tok-nv">$forecast-sales</span> = <span class="tok-n">line-chart</span>.<span class="tok-nb">new</span>(<span class="tok-n">line-values</span> => [<span class="tok-mi">9</span>,<span class="tok-mi">8</span>,<span class="tok-mi">10</span>,<span class="tok-mi">7</span>,<span class="tok-mi">6</span>,<span class="tok-mi">9</span>]); <span class="tok-k">my</span> <span class="tok-nv">$actual-vs-forecast</span> = <span class="tok-n">combo-chart</span>.<span class="tok-nb">new</span>(<span class="tok-n">bar-values</span> => [<span class="tok-mi">10</span>,<span class="tok-mi">9</span>,<span class="tok-mi">11</span>,<span class="tok-mi">8</span>,<span class="tok-mi">7</span>,<span class="tok-mi">10</span>], <span class="tok-n">line-values</span> => [<span class="tok-mi">9</span>,<span class="tok-mi">8</span>,<span class="tok-mi">10</span>,<span class="tok-mi">7</span>,<span class="tok-mi">6</span>,<span class="tok-mi">9</span>]); <span class="tok-nb">say</span> <span class="tok-s">"Actual sales:"</span>; <span class="tok-nv">$actual-sales</span>.<span class="tok-n">plot</span>; <span class="tok-nb">say</span> <span class="tok-s">"Forecast sales:"</span>; <span class="tok-nv">$forecast-sales</span>.<span class="tok-n">plot</span>; <span class="tok-nb">say</span> <span class="tok-s">"Actual vs Forecast:"</span>; <span class="tok-nv">$actual-vs-forecast</span>.<span class="tok-n">plot</span>;</code></pre> </div> </div> <div class="listingblock"> <div class="title"><code>Output</code></div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span>===<span class="tok-n">SORRY</span>!=== <span class="tok-nb">Method</span> <span class="tok-s">'plot'</span> <span class="tok-n">must</span> <span class="tok-n">be</span> <span class="tok-n">resolved</span> <span class="tok-n">by</span> <span class="tok-k">class</span> <span class="tok-n">combo-chart</span> <span class="tok-n">because</span> <span class="tok-n">it</span> <span class="tok-n">exists</span> <span class="tok-nb">in</span> <span class="tok-n">multiple</span> <span class="tok-n">roles</span> (<span class="tok-n">line-chart</span>, <span class="tok-n">bar-chart</span>)</code></pre> </div> </div> <div class="paragraph"> <div class="title">Explanation</div> <p>If multiple roles are applied to the same class and a conflict exists, a compile-time error will be thrown.<br> This is a much safer approach than multiple inheritance, where conflicts are not considered errors and are simply resolved at runtime.</p> </div> <div class="paragraph"> <p>Roles will warn you that there’s a conflict.</p> </div> </div> <div class="sect2"> <h3 id="_introspection_2">9.10. Introspection</h3> <div class="paragraph"> <p><strong>Introspection</strong> is the process of getting information about an object, like its type, attributes or methods.</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">class</span> <span class="tok-n">Human</span> { <span class="tok-k">has</span> <span class="tok-nb">Str</span> <span class="tok-nv">$.name</span>; <span class="tok-k">has</span> <span class="tok-nb">Int</span> <span class="tok-nv">$.age</span>; <span class="tok-k">method</span> <span class="tok-n">introduce-yourself</span> { <span class="tok-nb">say</span> <span class="tok-s">'Hi I am a human being, my name is '</span> ~ <span class="tok-nb">self</span>.<span class="tok-nb">name</span>; } } <span class="tok-k">class</span> <span class="tok-n">Employee</span> <span class="tok-k">is</span> <span class="tok-n">Human</span> { <span class="tok-k">has</span> <span class="tok-nb">Str</span> <span class="tok-nv">$.company</span>; <span class="tok-k">has</span> <span class="tok-nb">Int</span> <span class="tok-nv">$.salary</span>; <span class="tok-k">method</span> <span class="tok-n">introduce-yourself</span> { <span class="tok-nb">say</span> <span class="tok-s">'Hi I am a employee, my name is '</span> ~ <span class="tok-nb">self</span>.<span class="tok-nb">name</span> ~ <span class="tok-s">' and I work at: '</span> ~ <span class="tok-nb">self</span>.<span class="tok-n">company</span>; } } <span class="tok-k">my</span> <span class="tok-nv">$john</span> = <span class="tok-n">Human</span>.<span class="tok-nb">new</span>(<span class="tok-nb">name</span> =><span class="tok-s">'John'</span>,<span class="tok-n">age</span> => <span class="tok-mi">23</span>,); <span class="tok-k">my</span> <span class="tok-nv">$jane</span> = <span class="tok-n">Employee</span>.<span class="tok-nb">new</span>(<span class="tok-nb">name</span> =><span class="tok-s">'Jane'</span>,<span class="tok-n">age</span> => <span class="tok-mi">25</span>,<span class="tok-n">company</span> => <span class="tok-s">'Acme'</span>,<span class="tok-n">salary</span> => <span class="tok-mi">4000</span>); <span class="tok-nb">say</span> <span class="tok-nv">$john</span>.<span class="tok-nb">WHAT</span>; <span class="tok-nb">say</span> <span class="tok-nv">$jane</span>.<span class="tok-nb">WHAT</span>; <span class="tok-nb">say</span> <span class="tok-nv">$john</span>.^<span class="tok-nb">attributes</span>; <span class="tok-nb">say</span> <span class="tok-nv">$jane</span>.^<span class="tok-nb">attributes</span>; <span class="tok-nb">say</span> <span class="tok-nv">$john</span>.^<span class="tok-nb">methods</span>; <span class="tok-nb">say</span> <span class="tok-nv">$jane</span>.^<span class="tok-nb">methods</span>; <span class="tok-nb">say</span> <span class="tok-nv">$jane</span>.^<span class="tok-nb">parents</span>; <span class="tok-k">if</span> <span class="tok-nv">$jane</span> ~~ <span class="tok-n">Human</span> {<span class="tok-nb">say</span> <span class="tok-s">'Jane is a Human'</span>};</code></pre> </div> </div> <div class="paragraph"> <p>Introspection is facilitated by:</p> </div> <div class="ulist"> <ul> <li> <p><code>.WHAT</code> — returns the class from which the object was created</p> </li> <li> <p><code>.^attributes</code> — returns all the attributes of the object</p> </li> <li> <p><code>.^methods</code> — returns all the methods that can be called on the object</p> </li> <li> <p><code>.^parents</code> — returns the parent classes of the object</p> </li> <li> <p><code>~~</code> is called the smart-match operator. It evaluates to <em>True</em> if the object is created from the class it is being compared against or any of its inheritances.</p> </li> </ul> </div> <div class="admonitionblock note"> <table> <tr> <td class="icon"> <i class="fa icon-note" title="Note"></i> </td> <td class="content"> <div class="paragraph"> <p>For more info on Object Oriented Programming in Raku, see:</p> </div> <div class="ulist"> <ul> <li> <p><a href="https://docs.raku.org/language/classtut" class="bare">https://docs.raku.org/language/classtut</a></p> </li> <li> <p><a href="https://docs.raku.org/language/objects" class="bare">https://docs.raku.org/language/objects</a></p> </li> </ul> </div> </td> </tr> </table> </div> </div> </div> </div> <div class="sect1"> <h2 id="_exception_handling">10. Exception Handling</h2> <div class="sectionbody"> <div class="sect2"> <h3 id="_catching_exceptions">10.1. Catching Exceptions</h3> <div class="paragraph"> <p><strong>Exceptions</strong> are a special behavior that happens at runtime when something goes wrong.<br> We say that exceptions are <em>thrown</em>.</p> </div> <div class="paragraph"> <p>Consider the below script that runs correctly:</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nb">Str</span> <span class="tok-nv">$name</span>; <span class="tok-nv">$name</span> = <span class="tok-s">"Joanna"</span>; <span class="tok-nb">say</span> <span class="tok-s">"Hello "</span> ~ <span class="tok-nv">$name</span>; <span class="tok-nb">say</span> <span class="tok-s">"How are you doing today?"</span></code></pre> </div> </div> <div class="listingblock"> <div class="title"><code>Output</code></div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-n">Hello</span> <span class="tok-n">Joanna</span> <span class="tok-n">How</span> <span class="tok-n">are</span> <span class="tok-n">you</span> <span class="tok-n">doing</span> <span class="tok-nb">today</span>?</code></pre> </div> </div> <div class="paragraph"> <p>Now consider this script that throws an exception:</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nb">Str</span> <span class="tok-nv">$name</span>; <span class="tok-nv">$name</span> = <span class="tok-mi">123</span>; <span class="tok-nb">say</span> <span class="tok-s">"Hello "</span> ~ <span class="tok-nv">$name</span>; <span class="tok-nb">say</span> <span class="tok-s">"How are you doing today?"</span></code></pre> </div> </div> <div class="listingblock"> <div class="title"><code>Output</code></div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-n">Type</span> <span class="tok-n">check</span> <span class="tok-n">failed</span> <span class="tok-nb">in</span> <span class="tok-n">assignment</span> <span class="tok-nb">to</span> <span class="tok-nv">$name</span>; <span class="tok-nb">expected</span> <span class="tok-nb">Str</span> <span class="tok-k">but</span> <span class="tok-nb">got</span> <span class="tok-nb">Int</span> <span class="tok-nb">in</span> <span class="tok-nb">block</span> <span class="tok-s"><unit></span> <span class="tok-nb">at</span> <span class="tok-n">exceptions</span>.<span class="tok-n">raku:2</span></code></pre> </div> </div> <div class="paragraph"> <p>Notice that whenever an error occurs (in this case, assigning a number to a string variable) the program will stop and other lines of code will not be evaluated.</p> </div> <div class="paragraph"> <p><strong>Exception handling</strong> is the process of <em>catching</em> an exception that has been <em>thrown</em> in order for the script to continue working.</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nb">Str</span> <span class="tok-nv">$name</span>; <span class="tok-k">try</span> { <span class="tok-nv">$name</span> = <span class="tok-mi">123</span>; <span class="tok-nb">say</span> <span class="tok-s">"Hello "</span> ~ <span class="tok-nv">$name</span>; <span class="tok-k">CATCH</span> { <span class="tok-k">default</span> { <span class="tok-nb">say</span> <span class="tok-s">"Can you tell us your name again, we couldn't find it in the register."</span>; } } } <span class="tok-nb">say</span> <span class="tok-s">"How are you doing today?"</span>;</code></pre> </div> </div> <div class="listingblock"> <div class="title"><code>Output</code></div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-n">Can</span> <span class="tok-n">you</span> <span class="tok-nb">tell</span> <span class="tok-n">us</span> <span class="tok-n">your</span> <span class="tok-nb">name</span> <span class="tok-n">again</span>, <span class="tok-n">we</span> <span class="tok-n">couldn't</span> <span class="tok-n">find</span> <span class="tok-n">it</span> <span class="tok-nb">in</span> <span class="tok-n">the</span> <span class="tok-n">register</span>. <span class="tok-n">How</span> <span class="tok-n">are</span> <span class="tok-n">you</span> <span class="tok-n">doing</span> <span class="tok-nb">today</span>?</code></pre> </div> </div> <div class="paragraph"> <p>Exception handling is done by using a <code>try-catch</code> block.</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">try</span> { <span class="tok-c1"># code goes in here</span> <span class="tok-c1"># if anything goes wrong, the script will enter the below CATCH block</span> <span class="tok-c1"># if nothing goes wrong, the CATCH block will be ignored</span> <span class="tok-k">CATCH</span> { <span class="tok-k">default</span> { <span class="tok-c1"># the code in here will be evaluated only if an exception has been thrown</span> } } }</code></pre> </div> </div> <div class="paragraph"> <p>The <code>CATCH</code> block can be defined the same way a <code>given</code> block is defined. This means we can <em>catch</em> and handle differently many types of exceptions.</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">try</span> { <span class="tok-c1"># code goes in here</span> <span class="tok-c1"># if anything goes wrong, the script will enter the below CATCH block</span> <span class="tok-c1"># if nothing goes wrong, the CATCH block will be ignored</span> <span class="tok-k">CATCH</span> { <span class="tok-k">when</span> <span class="tok-o">X</span>::<span class="tok-n">AdHoc</span> { <span class="tok-c1"># do something if exception of type X::AdHoc is thrown }</span> <span class="tok-k">when</span> <span class="tok-o">X</span>::<span class="tok-n">IO</span> { <span class="tok-c1"># do something if exception of type X::IO is thrown }</span> <span class="tok-k">when</span> <span class="tok-o">X</span>::<span class="tok-n">OS</span> { <span class="tok-c1"># do something if exception of type X::OS is thrown }</span> <span class="tok-k">default</span> { <span class="tok-c1"># do something if exception is thrown and doesn't belong to the above types }</span> } }</code></pre> </div> </div> </div> <div class="sect2"> <h3 id="_throwing_exceptions">10.2. Throwing Exceptions</h3> <div class="paragraph"> <p>Raku also allows you to explicitly throw exceptions.<br> Two types of exceptions can be thrown:</p> </div> <div class="ulist"> <ul> <li> <p>ad-hoc exceptions</p> </li> <li> <p>typed exceptions</p> </li> </ul> </div> <div class="listingblock"> <div class="title">ad-hoc</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nb">Int</span> <span class="tok-nv">$age</span> = <span class="tok-mi">21</span>; <span class="tok-nb">die</span> <span class="tok-s">"Error !"</span>;</code></pre> </div> </div> <div class="listingblock"> <div class="title">typed</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nb">Int</span> <span class="tok-nv">$age</span> = <span class="tok-mi">21</span>; <span class="tok-o">X</span>::<span class="tok-n">AdHoc</span>.<span class="tok-nb">new</span>(<span class="tok-nb">payload</span> => <span class="tok-s">'Error !'</span>).<span class="tok-nb">throw</span>;</code></pre> </div> </div> <div class="paragraph"> <p>Ad-hoc exceptions are thrown using the <code>die</code> subroutine, followed by the exception message.</p> </div> <div class="paragraph"> <p>Typed exceptions are objects, hence the use of the <code>.new()</code> constructor in the above example.<br> All typed exceptions descend from class <code>X</code> , below are a few examples:<br> <code>X::AdHoc</code> is the simplest exception type<br> <code>X::IO</code> is related to IO errors<br> <code>X::OS</code> is related to OS errors<br> <code>X::Str::Numeric</code> related to trying to coerce a string to a number</p> </div> <div class="admonitionblock note"> <table> <tr> <td class="icon"> <i class="fa icon-note" title="Note"></i> </td> <td class="content"> For a complete list of exception types and their associated methods, go to <a href="https://docs.raku.org/type-exceptions.html" class="bare">https://docs.raku.org/type-exceptions.html</a> </td> </tr> </table> </div> </div> </div> </div> <div class="sect1"> <h2 id="_regular_expressions">11. Regular Expressions</h2> <div class="sectionbody"> <div class="paragraph"> <p>A regular expression, or <em>regex</em>, is a sequence of characters that is used for pattern matching.<br> Think of it as a pattern.</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">if</span> <span class="tok-s">'enlightenment'</span> ~~ <span class="tok-sr">m/ light /</span> { <span class="tok-nb">say</span> <span class="tok-s">"enlightenment contains the word light"</span>; }</code></pre> </div> </div> <div class="paragraph"> <p>In this example, the smart match operator <code>~~</code> is used to check if a string (enlightenment) contains the word (light).<br> "Enlightenment" is matched against the regex <code>m/ light /</code></p> </div> <div class="sect2"> <h3 id="_regex_definition">11.1. Regex definition</h3> <div class="paragraph"> <p>A regular expression can be defined like this:</p> </div> <div class="ulist"> <ul> <li> <p><code>/light/</code></p> </li> <li> <p><code>m/light/</code></p> </li> <li> <p><code>rx/light/</code></p> </li> </ul> </div> <div class="paragraph"> <p>Unless specified explicitly, white space is ignored; <code>m/light/</code> and <code>m/ light /</code> are the same.</p> </div> </div> <div class="sect2"> <h3 id="_matching_characters">11.2. Matching characters</h3> <div class="paragraph"> <p>Alphanumeric characters and the underscore <code>_</code> are written as is.<br> All other characters have to be escaped using a backslash or surrounded by quotes.</p> </div> <div class="listingblock"> <div class="title">Backslash</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">if</span> <span class="tok-s">'Temperature: 13'</span> ~~ <span class="tok-sr">m/ \: /</span> { <span class="tok-nb">say</span> <span class="tok-s">"The string provided contains a colon :"</span>; }</code></pre> </div> </div> <div class="listingblock"> <div class="title">Single quotes</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">if</span> <span class="tok-s">'Age = 13'</span> ~~ <span class="tok-sr">m/ '=' /</span> { <span class="tok-nb">say</span> <span class="tok-s">"The string provided contains an equal character = "</span>; }</code></pre> </div> </div> <div class="listingblock"> <div class="title">Double quotes</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">if</span> <span class="tok-s">'name@company.com'</span> ~~ <span class="tok-sr">m/ "@" /</span> { <span class="tok-nb">say</span> <span class="tok-s">"This is a valid email address because it contains an @ character"</span>; }</code></pre> </div> </div> </div> <div class="sect2"> <h3 id="_matching_categories_of_characters">11.3. Matching categories of characters</h3> <div class="paragraph"> <p>Characters can be classified into categories and we can match against them.<br> We can also match against the inverse of that category (everything except it):</p> </div> <table class="tableblock frame-all grid-all stretch"> <colgroup> <col style="width: 25%;"> <col style="width: 25%;"> <col style="width: 25%;"> <col style="width: 25%;"> </colgroup> <tbody> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>Category</strong></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>Regex</strong></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>Inverse</strong></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><strong>Regex</strong></p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Word character (letter, digit or underscore)</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">\w</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Any character except a word character</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">\W</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Digit</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">\d</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Any character except a digit</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">\D</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Whitespace</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">\s</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Any character except a whitespace</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">\S</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Horizontal whitespace</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">\h</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Any character except a horizontal whitespace</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">\H</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Vertical whitespace</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">\v</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Any character except a vertical whitespace</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">\V</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Tab</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">\t</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Any character except a Tab</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">\T</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">New line</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">\n</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Any character except a new line</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">\N</p></td> </tr> </tbody> </table> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">if</span> <span class="tok-s">"John123"</span> ~~<span class="tok-sr"> / \d /</span> { <span class="tok-nb">say</span> <span class="tok-s">"This is not a valid name, numbers are not allowed"</span>; } <span class="tok-k">else</span> { <span class="tok-nb">say</span> <span class="tok-s">"This is a valid name"</span> } <span class="tok-k">if</span> <span class="tok-s">"John-Doe"</span> ~~<span class="tok-sr"> / \s /</span> { <span class="tok-nb">say</span> <span class="tok-s">"This string contains whitespace"</span>; } <span class="tok-k">else</span> { <span class="tok-nb">say</span> <span class="tok-s">"This string doesn't contain whitespace"</span> }</code></pre> </div> </div> </div> <div class="sect2"> <h3 id="_unicode_properties">11.4. Unicode properties</h3> <div class="paragraph"> <p>Matching against categories of characters, as seen in the preceding section, is convenient.<br> That being said, a more systematic approach would be to use Unicode properties.<br> This allows you to match against categories of characters inside and outside of<br> the ASCII standard.<br> Unicode properties are enclosed in <code><: ></code></p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">if</span> <span class="tok-s">"Devanagari Numbers १२३"</span> ~~<span class="tok-sr"> / <:N> /</span> { <span class="tok-nb">say</span> <span class="tok-s">"Contains a number"</span>; } <span class="tok-k">else</span> { <span class="tok-nb">say</span> <span class="tok-s">"Doesn't contain a number"</span> } <span class="tok-k">if</span> <span class="tok-s">"Привет, Иван."</span> ~~<span class="tok-sr"> / <:Lu> /</span> { <span class="tok-nb">say</span> <span class="tok-s">"Contains an uppercase letter"</span>; } <span class="tok-k">else</span> { <span class="tok-nb">say</span> <span class="tok-s">"Doesn't contain an upper case letter"</span> } <span class="tok-k">if</span> <span class="tok-s">"John-Doe"</span> ~~<span class="tok-sr"> / <:Pd> /</span> { <span class="tok-nb">say</span> <span class="tok-s">"Contains a dash"</span>; } <span class="tok-k">else</span> { <span class="tok-nb">say</span> <span class="tok-s">"Doesn't contain a dash"</span> }</code></pre> </div> </div> </div> <div class="sect2"> <h3 id="_wildcards">11.5. Wildcards</h3> <div class="paragraph"> <p>Wildcards can also be used in a regex.</p> </div> <div class="paragraph"> <p>The dot <code>.</code> means any single character.</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">if</span> <span class="tok-s">'abc'</span> ~~ <span class="tok-sr">m/ a.c /</span> { <span class="tok-nb">say</span> <span class="tok-s">"Match"</span>; } <span class="tok-k">if</span> <span class="tok-s">'a2c'</span> ~~ <span class="tok-sr">m/ a.c /</span> { <span class="tok-nb">say</span> <span class="tok-s">"Match"</span>; } <span class="tok-k">if</span> <span class="tok-s">'ac'</span> ~~ <span class="tok-sr">m/ a.c /</span> { <span class="tok-nb">say</span> <span class="tok-s">"Match"</span>; } <span class="tok-k">else</span> { <span class="tok-nb">say</span> <span class="tok-s">"No Match"</span>; }</code></pre> </div> </div> </div> <div class="sect2"> <h3 id="_quantifiers">11.6. Quantifiers</h3> <div class="paragraph"> <p>Quantifiers come after a character and are used to specify how many times we are expecting it.</p> </div> <div class="paragraph"> <p>The question mark <code>?</code> means zero or one time.</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">if</span> <span class="tok-s">'ac'</span> ~~ <span class="tok-sr">m/ a?c /</span> { <span class="tok-nb">say</span> <span class="tok-s">"Match"</span>; } <span class="tok-k">else</span> { <span class="tok-nb">say</span> <span class="tok-s">"No Match"</span>; } <span class="tok-k">if</span> <span class="tok-s">'c'</span> ~~ <span class="tok-sr">m/ a?c /</span> { <span class="tok-nb">say</span> <span class="tok-s">"Match"</span>; } <span class="tok-k">else</span> { <span class="tok-nb">say</span> <span class="tok-s">"No Match"</span>; }</code></pre> </div> </div> <div class="paragraph"> <p>The star <code>*</code> means zero or multiple times.</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">if</span> <span class="tok-s">'az'</span> ~~ <span class="tok-sr">m/ a*z /</span> { <span class="tok-nb">say</span> <span class="tok-s">"Match"</span>; } <span class="tok-k">else</span> { <span class="tok-nb">say</span> <span class="tok-s">"No Match"</span>; } <span class="tok-k">if</span> <span class="tok-s">'aaz'</span> ~~ <span class="tok-sr">m/ a*z /</span> { <span class="tok-nb">say</span> <span class="tok-s">"Match"</span>; } <span class="tok-k">else</span> { <span class="tok-nb">say</span> <span class="tok-s">"No Match"</span>; } <span class="tok-k">if</span> <span class="tok-s">'aaaaaaaaaaz'</span> ~~ <span class="tok-sr">m/ a*z /</span> { <span class="tok-nb">say</span> <span class="tok-s">"Match"</span>; } <span class="tok-k">else</span> { <span class="tok-nb">say</span> <span class="tok-s">"No Match"</span>; } <span class="tok-k">if</span> <span class="tok-s">'z'</span> ~~ <span class="tok-sr">m/ a*z /</span> { <span class="tok-nb">say</span> <span class="tok-s">"Match"</span>; } <span class="tok-k">else</span> { <span class="tok-nb">say</span> <span class="tok-s">"No Match"</span>; }</code></pre> </div> </div> <div class="paragraph"> <p>The <code>+</code> means at least one time.</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">if</span> <span class="tok-s">'az'</span> ~~ <span class="tok-sr">m/ a+z /</span> { <span class="tok-nb">say</span> <span class="tok-s">"Match"</span>; } <span class="tok-k">else</span> { <span class="tok-nb">say</span> <span class="tok-s">"No Match"</span>; } <span class="tok-k">if</span> <span class="tok-s">'aaz'</span> ~~ <span class="tok-sr">m/ a+z /</span> { <span class="tok-nb">say</span> <span class="tok-s">"Match"</span>; } <span class="tok-k">else</span> { <span class="tok-nb">say</span> <span class="tok-s">"No Match"</span>; } <span class="tok-k">if</span> <span class="tok-s">'aaaaaaaaaaz'</span> ~~ <span class="tok-sr">m/ a+z /</span> { <span class="tok-nb">say</span> <span class="tok-s">"Match"</span>; } <span class="tok-k">else</span> { <span class="tok-nb">say</span> <span class="tok-s">"No Match"</span>; } <span class="tok-k">if</span> <span class="tok-s">'z'</span> ~~ <span class="tok-sr">m/ a+z /</span> { <span class="tok-nb">say</span> <span class="tok-s">"Match"</span>; } <span class="tok-k">else</span> { <span class="tok-nb">say</span> <span class="tok-s">"No Match"</span>; }</code></pre> </div> </div> </div> <div class="sect2"> <h3 id="_match_results">11.7. Match Results</h3> <div class="paragraph"> <p>Whenever the process of matching a string against a regex is successful, the match result is stored in a special variable <code>$/</code></p> </div> <div class="listingblock"> <div class="title">Script</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">if</span> <span class="tok-s">'Rakudo is a Perl 6 compiler'</span> ~~ <span class="tok-sr">m/:s Perl 6/</span> { <span class="tok-nb">say</span> <span class="tok-s">"The match is: "</span> ~ <span class="tok-vg">$/</span>; <span class="tok-nb">say</span> <span class="tok-s">"The string before the match is: "</span> ~ <span class="tok-vg">$/</span>.<span class="tok-nb">prematch</span>; <span class="tok-nb">say</span> <span class="tok-s">"The string after the match is: "</span> ~ <span class="tok-vg">$/</span>.<span class="tok-nb">postmatch</span>; <span class="tok-nb">say</span> <span class="tok-s">"The matching string starts at position: "</span> ~ <span class="tok-vg">$/</span>.<span class="tok-nb">from</span>; <span class="tok-nb">say</span> <span class="tok-s">"The matching string ends at position: "</span> ~ <span class="tok-vg">$/</span>.<span class="tok-nb">to</span>; }</code></pre> </div> </div> <div class="listingblock"> <div class="title">Output</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-n">The</span> <span class="tok-nb">match</span> <span class="tok-n">is:</span> <span class="tok-nb">Perl</span> <span class="tok-mi">6</span> <span class="tok-n">The</span> <span class="tok-n">string</span> <span class="tok-o">before</span> <span class="tok-n">the</span> <span class="tok-nb">match</span> <span class="tok-n">is:</span> <span class="tok-n">Rakudo</span> <span class="tok-k">is</span> <span class="tok-n">a</span> <span class="tok-n">The</span> <span class="tok-n">string</span> <span class="tok-nb">after</span> <span class="tok-n">the</span> <span class="tok-nb">match</span> <span class="tok-n">is:</span> <span class="tok-nb">compiler</span> <span class="tok-n">The</span> <span class="tok-n">matching</span> <span class="tok-n">string</span> <span class="tok-n">starts</span> <span class="tok-nb">at</span> <span class="tok-n">position:</span> <span class="tok-mi">12</span> <span class="tok-n">The</span> <span class="tok-n">matching</span> <span class="tok-n">string</span> <span class="tok-n">ends</span> <span class="tok-nb">at</span> <span class="tok-n">position:</span> <span class="tok-mi">18</span></code></pre> </div> </div> <div class="paragraph"> <div class="title">Explanation</div> <p><code>$/</code> returns a <em>Match Object</em> (the string that matches the regex)<br> The following methods can be called on the <em>Match Object</em>:<br> <code>.prematch</code> returns the string preceding the match.<br> <code>.postmatch</code> returns the string following the match.<br> <code>.from</code> returns the starting position of the match.<br> <code>.to</code> returns the ending position of the match.<br></p> </div> <div class="admonitionblock tip"> <table> <tr> <td class="icon"> <i class="fa icon-tip" title="Tip"></i> </td> <td class="content"> By default, whitespace in a regex definition is ignored.<br> If we want to match against a regex containing whitespace, we have to do so explicitly.<br> The <code>:s</code> in the regex <code>m/:s Perl 6/</code> forces whitespace to be considered.<br> Alternatively, we could have written the regex as <code>m/ Perl\s6 /</code> and used <code>\s</code> which represents a whitespace.<br> If a regex contains more than a single whitespace, using <code>:s</code> is a better option than using <code>\s</code> for each and every whitespace. </td> </tr> </table> </div> </div> <div class="sect2"> <h3 id="_example">11.8. Example</h3> <div class="paragraph"> <p>Let’s check if an email is valid or not.<br> For the sake of this example we will assume that a valid email address has this format:<br> first name [dot] last name [at] company [dot] (com/org/net)</p> </div> <div class="admonitionblock warning"> <table> <tr> <td class="icon"> <i class="fa icon-warning" title="Warning"></i> </td> <td class="content"> The regex used in this example for email validation is not very accurate.<br> Its sole purpose is to demonstrate regex functionality in Raku.<br> Do not use it as-is in production. </td> </tr> </table> </div> <div class="listingblock"> <div class="title">Script</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">$email</span> = <span class="tok-s">'john.doe@perl6.org'</span>; <span class="tok-k">my</span> <span class="tok-nv">$regex</span> =<span class="tok-sr"> / <:L>+\.<:L>+\@<:L+:N>+\.<:L>+ /</span>; <span class="tok-k">if</span> <span class="tok-nv">$email</span> ~~ <span class="tok-nv">$regex</span> { <span class="tok-nb">say</span> <span class="tok-vg">$/</span> ~ <span class="tok-s">" is a valid email"</span>; } <span class="tok-k">else</span> { <span class="tok-nb">say</span> <span class="tok-s">"This is not a valid email"</span>; }</code></pre> </div> </div> <div class="paragraph"> <div class="title">Output</div> <p><code>john.doe@perl6.org is a valid email</code></p> </div> <div class="paragraph"> <div class="title">Explanation</div> <p><code><:L></code> matches a single letter<br> <code><:L>` matches one or more letters + `\.` matches a single [dot] character + `\@` matches a single [at] character + `<:L:N></code> matches a letter or a single number<br> <code><:L+:N>+</code> matches one or more letters or numbers<br></p> </div> <div class="paragraph"> <p>The regex can be decomposed as following:</p> </div> <div class="ulist"> <ul> <li> <p><strong>first name</strong> <code><:L>+</code></p> </li> <li> <p><strong>[dot]</strong> <code>\.</code></p> </li> <li> <p><strong>last name</strong> <code><:L>+</code></p> </li> <li> <p><strong>[at]</strong> <code>\@</code></p> </li> <li> <p><strong>company name</strong> <code><:L+:N>+</code></p> </li> <li> <p><strong>[dot]</strong> <code>\.</code></p> </li> <li> <p><strong>com/org/net</strong> <code><:L>+</code></p> </li> </ul> </div> <div class="listingblock"> <div class="title">Alternatively, a regex can be broken down into multiple named regexes</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">$email</span> = <span class="tok-s">'john.doe@perl6.org'</span>; <span class="tok-k">my</span> <span class="tok-k">regex</span><span class="tok-n"> many-letters</span> {<span class="tok-sr"> <:L>+ </span>}; <span class="tok-k">my</span> <span class="tok-k">regex</span><span class="tok-n"> dot</span> {<span class="tok-sr"> \. </span>}; <span class="tok-k">my</span> <span class="tok-k">regex</span><span class="tok-n"> at</span> {<span class="tok-sr"> \@ </span>}; <span class="tok-k">my</span> <span class="tok-k">regex</span><span class="tok-n"> many-letters-numbers</span> {<span class="tok-sr"> <:L+:N>+ </span>}; <span class="tok-k">if</span> <span class="tok-nv">$email</span> ~~<span class="tok-sr"> / <many-letters> <dot> <many-letters> <at> <many-letters-numbers> <dot> <many-letters> /</span> { <span class="tok-nb">say</span> <span class="tok-vg">$/</span> ~ <span class="tok-s">" is a valid email"</span>; } <span class="tok-k">else</span> { <span class="tok-nb">say</span> <span class="tok-s">"This is not a valid email"</span>; }</code></pre> </div> </div> <div class="paragraph"> <p>A named regex is defined using the following syntax: <code>my regex regex-name { regex definition }</code><br> A named regex can be called using the following syntax: <code><regex-name></code></p> </div> <div class="admonitionblock note"> <table> <tr> <td class="icon"> <i class="fa icon-note" title="Note"></i> </td> <td class="content"> For more info on regexes, see <a href="https://docs.raku.org/language/regexes" class="bare">https://docs.raku.org/language/regexes</a> </td> </tr> </table> </div> </div> </div> </div> <div class="sect1"> <h2 id="_raku_modules">12. Raku Modules</h2> <div class="sectionbody"> <div class="paragraph"> <p>Raku is a general purpose programming language. It can be used to tackle a multitude of tasks including: text manipulation, graphics, web, databases, network protocols etc.</p> </div> <div class="paragraph"> <p>Reusability is a very important concept whereby programmers don’t have to reinvent the wheel each time they want to do a new task.</p> </div> <div class="paragraph"> <p>Raku allows the creation and redistribution of <strong>modules</strong>. Each module is a packaged set of functionality that can be reused once installed.</p> </div> <div class="paragraph"> <p><em>Zef</em> is a module management tool that comes with Rakudo Star.</p> </div> <div class="paragraph"> <p>To install a specific module, type the below command in your terminal:</p> </div> <div class="paragraph"> <p><code>zef install "module name"</code></p> </div> <div class="admonitionblock note"> <table> <tr> <td class="icon"> <i class="fa icon-note" title="Note"></i> </td> <td class="content"> The Raku modules directory can be found on: <a href="https://raku.land/" class="bare">https://raku.land/</a> </td> </tr> </table> </div> <div class="sect2"> <h3 id="_using_modules">12.1. Using Modules</h3> <div class="paragraph"> <p>MD5 is a cryptographic hash function that produces a 128-bit hash value.<br> MD5 has a variety of applications, including the encryption of stored passwords in a database. When a new user registers, their credentials are not stored as plain text but rather <em>hashed</em>. The rationale behind this is that if the DB gets compromised, the attacker will not be able to know what the passwords are.</p> </div> <div class="paragraph"> <p>Luckily, you don’t need to implement the MD5 algorithm yourself; there’s a Raku module already implemented.</p> </div> <div class="paragraph"> <p>Let’s install it:<br> <code>zef install Digest::MD5</code></p> </div> <div class="paragraph"> <p>Now, run the below script:</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">use</span> <span class="tok-n">Digest::MD5</span>; <span class="tok-k">my</span> <span class="tok-nv">$password</span> = <span class="tok-s">"password123"</span>; <span class="tok-k">my</span> <span class="tok-nv">$hashed-password</span> = <span class="tok-n">md5</span>( <span class="tok-nv">$password</span> ); <span class="tok-nb">say</span> <span class="tok-nv">$hashed-password</span>;</code></pre> </div> </div> <div class="paragraph"> <p>In order to run the <code>md5()</code> function that creates hashes, we need to load the required module.<br> The <code>use</code> keyword loads the module for use in the script which provides an <code>md5</code> subroutine.</p> </div> <div class="admonitionblock warning"> <table> <tr> <td class="icon"> <i class="fa icon-warning" title="Warning"></i> </td> <td class="content"> In practice MD5 hashing alone is not sufficient, because it is prone to dictionary attacks.<br> It should be combined with a salt <a href="https://en.wikipedia.org/wiki/Salt_(cryptography)">https://en.wikipedia.org/wiki/Salt_(cryptography)</a>. </td> </tr> </table> </div> </div> </div> </div> <div class="sect1"> <h2 id="_unicode">13. Unicode</h2> <div class="sectionbody"> <div class="paragraph"> <p>Unicode is a standard for encoding and representing text for most writing systems in the world.<br> UTF-8 is a character encoding capable of encoding all possible characters, or code points, in Unicode.</p> </div> <div class="paragraph"> <p>Characters are defined by a:<br> <strong>Grapheme</strong>: Visual representation.<br> <strong>Code point</strong>: A number assigned to the character.<br> <strong>Code point name</strong>: A name assigned to the character.</p> </div> <div class="sect2"> <h3 id="_using_unicode">13.1. Using Unicode</h3> <div class="listingblock"> <div class="title">Let’s look at how we can output characters using Unicode</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-nb">say</span> <span class="tok-s">"a"</span>; <span class="tok-nb">say</span> <span class="tok-s">"\x0061"</span>; <span class="tok-nb">say</span> <span class="tok-s">"\c[LATIN SMALL LETTER A]"</span>;</code></pre> </div> </div> <div class="paragraph"> <p>The above 3 lines showcase different ways of building a character:</p> </div> <div class="olist arabic"> <ol class="arabic"> <li> <p>Writing the character directly (grapheme)</p> </li> <li> <p>Using <code>\x</code> and the code point</p> </li> <li> <p>Using <code>\c</code> and the code point name</p> </li> </ol> </div> <div class="listingblock"> <div class="title">Now lets output a smiley</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-nb">say</span> <span class="tok-s">"☺"</span>; <span class="tok-nb">say</span> <span class="tok-s">"\x263a"</span>; <span class="tok-nb">say</span> <span class="tok-s">"\c[WHITE SMILING FACE]"</span>;</code></pre> </div> </div> <div class="listingblock"> <div class="title">Another example combining two code points</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-nb">say</span> <span class="tok-s">"á"</span>; <span class="tok-nb">say</span> <span class="tok-s">"\x00e1"</span>; <span class="tok-nb">say</span> <span class="tok-s">"\x0061\x0301"</span>; <span class="tok-nb">say</span> <span class="tok-s">"\c[LATIN SMALL LETTER A WITH ACUTE]"</span>;</code></pre> </div> </div> <div class="paragraph"> <p>The letter <code>á</code> can be written:</p> </div> <div class="ulist"> <ul> <li> <p>using its unique code point <code>\x00e1</code></p> </li> <li> <p>or as a combination of the code points of <code>a</code> and acute <code>\x0061\x0301</code></p> </li> </ul> </div> <div class="listingblock"> <div class="title">Some of the methods that can be used:</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-nb">say</span> <span class="tok-s">"á"</span>.<span class="tok-nb">NFC</span>; <span class="tok-nb">say</span> <span class="tok-s">"á"</span>.<span class="tok-nb">NFD</span>; <span class="tok-nb">say</span> <span class="tok-s">"á"</span>.<span class="tok-nb">uniname</span>;</code></pre> </div> </div> <div class="listingblock"> <div class="title"><code>Output</code></div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-n">NFC:0x</span><span class="tok-s"><00e1></span> <span class="tok-n">NFD:0x</span><span class="tok-s"><0061 0301></span> <span class="tok-n">LATIN</span> <span class="tok-n">SMALL</span> <span class="tok-n">LETTER</span> <span class="tok-n">A</span> <span class="tok-n">WITH</span> <span class="tok-n">ACUTE</span></code></pre> </div> </div> <div class="paragraph"> <p><code>NFC</code> returns the unique code point.<br> <code>NFD</code> decomposes the character and return the code point of each part.<br> <code>uniname</code> returns the code point name.</p> </div> <div class="listingblock"> <div class="title">Unicode letters can be used as identifiers:</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">$Δ</span> = <span class="tok-mi">1</span>; <span class="tok-nv">$Δ</span>++; <span class="tok-nb">say</span> <span class="tok-nv">$Δ</span>;</code></pre> </div> </div> <div class="listingblock"> <div class="title">Unicode can be used to do math:</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">$var</span> = <span class="tok-mi">2</span> + <span class="tok-n">⅒</span>; <span class="tok-nb">say</span> <span class="tok-nv">$var</span>;</code></pre> </div> </div> </div> <div class="sect2"> <h3 id="_unicode_aware_operations">13.2. Unicode-aware Operations</h3> <div class="sect3"> <h4 id="_numbers">13.2.1. Numbers</h4> <div class="paragraph"> <p>Arabic numerals are the ten digits: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9. This numeral set is the most used worldwide.</p> </div> <div class="paragraph"> <p>Nonetheless different sets of numerals are used to a lesser extent in different parts of the world.</p> </div> <div class="paragraph"> <p>No special care needs to be taken when using a numeral set different than the Arabic numerals. All methods/operators work as expected.</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-nb">say</span> (<span class="tok-mi">٤</span>,<span class="tok-mi">٥</span>,<span class="tok-mi">٦</span>,<span class="tok-mi">1</span>,<span class="tok-mi">2</span>,<span class="tok-mi">3</span>).<span class="tok-nb">sort</span>; <span class="tok-c1"># (1 2 3 4 5 6)</span> <span class="tok-nb">say</span> <span class="tok-mi">1</span> + <span class="tok-mi">٩</span>; <span class="tok-c1"># 10</span></code></pre> </div> </div> </div> <div class="sect3"> <h4 id="_strings">13.2.2. Strings</h4> <div class="paragraph"> <p>If we were to use generic string operations, we might not always get the result that we were looking for, especially when comparing or sorting.</p> </div> <div class="sect4"> <h5 id="_comparison">Comparison</h5> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-nb">say</span> <span class="tok-s">'a'</span> <span class="tok-o">cmp</span> <span class="tok-s">'B'</span>; <span class="tok-c1"># More</span></code></pre> </div> </div> <div class="paragraph"> <p>The above example shows that <code>a</code> is bigger than <code>B</code>. The reason being that the code point of lowercase <code>a</code> is bigger than the code point of capital <code>B</code>.</p> </div> <div class="paragraph"> <p>While technically correct, this is probably not what we were looking for.</p> </div> <div class="paragraph"> <p>Luckily Raku has methods/operators that implement the <a href="http://unicode.org/reports/tr10/">Unicode Collation Algorithm</a>.<br> One of them is <code>unicmp</code> that behaves like the above showcased <code>cmp</code> but is unicode-aware.</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-nb">say</span> <span class="tok-s">'a'</span> <span class="tok-o">unicmp</span> <span class="tok-s">'B'</span>; <span class="tok-c1"># Less</span></code></pre> </div> </div> <div class="paragraph"> <p>As you can see, using the <code>unicmp</code> operator now yields the expected result that <code>a</code> is smaller than <code>B</code>.</p> </div> </div> <div class="sect4"> <h5 id="_sorting">Sorting</h5> <div class="paragraph"> <p>As an alternative to the <code>sort</code> method that sorts using code points, Raku provides a <code>collate</code> method that implements the <a href="http://unicode.org/reports/tr10/">Unicode Collation Algorithm</a>.</p> </div> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-nb">say</span> (<span class="tok-s">'a'</span>,<span class="tok-s">'b'</span>,<span class="tok-s">'c'</span>,<span class="tok-s">'D'</span>,<span class="tok-s">'E'</span>,<span class="tok-s">'F'</span>).<span class="tok-nb">sort</span>; <span class="tok-c1"># (D E F a b c)</span> <span class="tok-nb">say</span> (<span class="tok-s">'a'</span>,<span class="tok-s">'b'</span>,<span class="tok-s">'c'</span>,<span class="tok-s">'D'</span>,<span class="tok-s">'E'</span>,<span class="tok-s">'F'</span>).<span class="tok-nb">collate</span>; <span class="tok-c1"># (a b c D E F)</span></code></pre> </div> </div> </div> </div> </div> </div> </div> <div class="sect1"> <h2 id="_parallelism_concurrency_and_asynchrony">14. Parallelism, Concurrency and Asynchrony</h2> <div class="sectionbody"> <div class="sect2"> <h3 id="_parallelism">14.1. Parallelism</h3> <div class="paragraph"> <p>Under normal circumstances, all tasks in a program run sequentially.<br> This might not be a problem, unless what you’re trying to do takes a lot of time.</p> </div> <div class="paragraph"> <p>Thankfully, Raku has features that will enable you to run things in parallel.<br> At this stage, it is important to note that parallelism can mean one of two things:</p> </div> <div class="ulist"> <ul> <li> <p><strong>Task Parallelism</strong>: Two (or more) independent expressions running in parallel.</p> </li> <li> <p><strong>Data Parallelism</strong>: A single expression iterating over a list of elements in parallel.</p> </li> </ul> </div> <div class="paragraph"> <p>Let’s begin with the latter.</p> </div> <div class="sect3"> <h4 id="_data_parallelism">14.1.1. Data Parallelism</h4> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">@array</span> = <span class="tok-mi">0</span><span class="tok-o">..</span><span class="tok-mi">50000</span>; <span class="tok-c1"># Array population</span> <span class="tok-k">my</span> <span class="tok-nv">@result</span> = <span class="tok-nv">@array</span>.<span class="tok-n">map</span>({ <span class="tok-nb">is-prime</span> <span class="tok-nv">$_</span> }); <span class="tok-c1"># call is-prime for each array element</span> <span class="tok-nb">say</span> <span class="tok-nb">now</span> - <span class="tok-k">INIT</span> <span class="tok-nb">now</span>; <span class="tok-c1"># Output the time it took for the script to complete</span></code></pre> </div> </div> <div class="paragraph"> <div class="title">Considering the above example:</div> <p>We are only doing one operation <code>@array.map({ is-prime $_ })</code><br> The <code>is-prime</code> subroutine is being called for each array element sequentially:<br> <code>is-prime @array[0]</code> then <code>is-prime @array[1]</code> then <code>is-prime @array[2]</code> etc.</p> </div> <div class="listingblock"> <div class="title">Fortunately we can call <code>is-prime</code> on multiple array elements at the same time:</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">@array</span> = <span class="tok-mi">0</span><span class="tok-o">..</span><span class="tok-mi">50000</span>; <span class="tok-c1"># Array population</span> <span class="tok-k">my</span> <span class="tok-nv">@result</span> = <span class="tok-nv">@array</span>.<span class="tok-nb">race</span>.<span class="tok-n">map</span>({ <span class="tok-nb">is-prime</span> <span class="tok-nv">$_</span> }); <span class="tok-c1"># call is-prime for each array element</span> <span class="tok-nb">say</span> <span class="tok-nb">now</span> - <span class="tok-k">INIT</span> <span class="tok-nb">now</span>; <span class="tok-c1"># Output the time it took to complete</span></code></pre> </div> </div> <div class="paragraph"> <p>Notice the use of <code>race</code> in the expression. This method will enable parallel iteration of the array elements.</p> </div> <div class="paragraph"> <p>After running both examples (with and without <code>race</code>), compare the time it took for both scripts to complete.</p> </div> <div class="admonitionblock tip"> <table> <tr> <td class="icon"> <i class="fa icon-tip" title="Tip"></i> </td> <td class="content"> <div class="paragraph"> <p><code>race</code> will not preserve the order of elements. If you wish to do, so use <code>hyper</code> instead.</p> </div> <div class="listingblock"> <div class="title">race</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">@array</span> = <span class="tok-mi">1</span><span class="tok-o">..</span><span class="tok-mi">1000</span>; <span class="tok-k">my</span> <span class="tok-nv">@result</span> = <span class="tok-nv">@array</span>.<span class="tok-nb">race</span>.<span class="tok-n">map</span>( {<span class="tok-nv">$_</span> + <span class="tok-mi">1</span>} ); .<span class="tok-nb">say</span> <span class="tok-k">for</span> <span class="tok-nv">@result</span>;</code></pre> </div> </div> <div class="listingblock"> <div class="title">hyper</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">@array</span> = <span class="tok-mi">1</span><span class="tok-o">..</span><span class="tok-mi">1000</span>; <span class="tok-k">my</span> <span class="tok-nv">@result</span> = <span class="tok-nv">@array</span>.<span class="tok-nb">hyper</span>.<span class="tok-n">map</span>( {<span class="tok-nv">$_</span> + <span class="tok-mi">1</span>} ); .<span class="tok-nb">say</span> <span class="tok-k">for</span> <span class="tok-nv">@result</span>;</code></pre> </div> </div> <div class="paragraph"> <p>If you run both examples, you should notice that one is sorted and the other is not.</p> </div> </td> </tr> </table> </div> </div> <div class="sect3"> <h4 id="_task_parallelism">14.1.2. Task Parallelism</h4> <div class="listingblock"> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">@array1</span> = <span class="tok-mi">0</span><span class="tok-o">..</span><span class="tok-mi">49999</span>; <span class="tok-k">my</span> <span class="tok-nv">@array2</span> = <span class="tok-mi">2</span><span class="tok-o">..</span><span class="tok-mi">50001</span>; <span class="tok-k">my</span> <span class="tok-nv">@result1</span> = <span class="tok-nv">@array1</span>.<span class="tok-n">map</span>( {<span class="tok-nb">is-prime</span>(<span class="tok-nv">$_</span> + <span class="tok-mi">1</span>)} ); <span class="tok-k">my</span> <span class="tok-nv">@result2</span> = <span class="tok-nv">@array2</span>.<span class="tok-n">map</span>( {<span class="tok-nb">is-prime</span>(<span class="tok-nv">$_</span> - <span class="tok-mi">1</span>)} ); <span class="tok-nb">say</span> <span class="tok-nv">@result1</span> <span class="tok-o">eqv</span> <span class="tok-nv">@result2</span>; <span class="tok-nb">say</span> <span class="tok-nb">now</span> - <span class="tok-k">INIT</span> <span class="tok-nb">now</span>;</code></pre> </div> </div> <div class="olist arabic"> <div class="title">Considering the above example:</div> <ol class="arabic"> <li> <p>We defined 2 arrays</p> </li> <li> <p>applied a different operation for each array and stored the results</p> </li> <li> <p>and checked if both results are the same</p> </li> </ol> </div> <div class="paragraph"> <p>The script waits for <code>@array1.map( {is-prime($_ + 1)} )</code> to finish<br> and then evaluates <code>@array2.map( {is-prime($_ - 1)} )</code></p> </div> <div class="paragraph"> <p>Both operations applied to each array do not depend on each other.</p> </div> <div class="listingblock"> <div class="title">Why not do both in parallel?</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">my</span> <span class="tok-nv">@array1</span> = <span class="tok-mi">0</span><span class="tok-o">..</span><span class="tok-mi">49999</span>; <span class="tok-k">my</span> <span class="tok-nv">@array2</span> = <span class="tok-mi">2</span><span class="tok-o">..</span><span class="tok-mi">50001</span>; <span class="tok-k">my</span> <span class="tok-nv">$promise1</span> = <span class="tok-nb">start</span> <span class="tok-nv">@array1</span>.<span class="tok-n">map</span>( {<span class="tok-nb">is-prime</span>(<span class="tok-nv">$_</span> + <span class="tok-mi">1</span>)} ).<span class="tok-nb">eager</span>; <span class="tok-k">my</span> <span class="tok-nv">$promise2</span> = <span class="tok-nb">start</span> <span class="tok-nv">@array2</span>.<span class="tok-n">map</span>( {<span class="tok-nb">is-prime</span>(<span class="tok-nv">$_</span> - <span class="tok-mi">1</span>)} ).<span class="tok-nb">eager</span>; <span class="tok-k">my</span> <span class="tok-nv">@result1</span> = <span class="tok-nb">await</span> <span class="tok-nv">$promise1</span>; <span class="tok-k">my</span> <span class="tok-nv">@result2</span> = <span class="tok-nb">await</span> <span class="tok-nv">$promise2</span>; <span class="tok-nb">say</span> <span class="tok-nv">@result1</span> <span class="tok-o">eqv</span> <span class="tok-nv">@result2</span>; <span class="tok-nb">say</span> <span class="tok-nb">now</span> - <span class="tok-k">INIT</span> <span class="tok-nb">now</span>;</code></pre> </div> </div> <div class="paragraph"> <div class="title">Explanation</div> <p>The <code>start</code> subroutine evaluates the code and returns <strong>an object of type promise</strong> or shortly <strong>a promise</strong>.<br> If the code is evaluated correctly, the <em>promise</em> will be <strong>kept</strong>.<br> If the code throws an exception, the <em>promise</em> will be <strong>broken</strong>.</p> </div> <div class="paragraph"> <p>The <code>await</code> subroutine waits for a <strong>promise</strong>.<br> If it’s <strong>kept</strong> it will get the returned values.<br> If it’s <strong>broken</strong> it will get the exception thrown.</p> </div> <div class="paragraph"> <p>Check the time it took each script to complete.</p> </div> <div class="admonitionblock warning"> <table> <tr> <td class="icon"> <i class="fa icon-warning" title="Warning"></i> </td> <td class="content"> Parallelism always adds a threading overhead. If that overhead is not offset by gains in computational speed, the script will seem slower.<br> This is why, using <code>race</code>, <code>hyper</code>, <code>start</code> and <code>await</code> for fairly simple scripts can actually slow them down. </td> </tr> </table> </div> </div> </div> <div class="sect2"> <h3 id="_concurrency_and_asynchrony">14.2. Concurrency and Asynchrony</h3> <div class="admonitionblock note"> <table> <tr> <td class="icon"> <i class="fa icon-note" title="Note"></i> </td> <td class="content"> For more info on Concurrency and Asynchronous Programming, see <a href="https://docs.raku.org/language/concurrency" class="bare">https://docs.raku.org/language/concurrency</a> </td> </tr> </table> </div> </div> </div> </div> <div class="sect1"> <h2 id="_native_calling_interface">15. Native Calling Interface</h2> <div class="sectionbody"> <div class="paragraph"> <p>Raku gives us the ability to use C libraries, using the Native Calling Interface.</p> </div> <div class="paragraph"> <p><code>NativeCall</code> is a standard module that ships with Raku and offers a set of functionality to ease the job of interfacing Raku and C.</p> </div> <div class="sect2"> <h3 id="_calling_a_function">15.1. Calling a function</h3> <div class="paragraph"> <p>Consider the below C code that defines a function called <code>hellofromc</code>. This function prints on the terminal <code>Hello from C</code>. It doesn’t accept any argument nor return any value.</p> </div> <div class="listingblock"> <div class="title">ncitest.c</div> <div class="content"> <pre class="pygments highlight"><code data-lang="c"><span></span><span class="tok-cp">#include</span><span class="tok-w"> </span><span class="tok-cpf"><stdio.h></span> <span class="tok-kt">void</span><span class="tok-w"> </span><span class="tok-nf">hellofromc</span><span class="tok-w"> </span><span class="tok-p">()</span><span class="tok-w"> </span><span class="tok-p">{</span> <span class="tok-w"> </span><span class="tok-n">printf</span><span class="tok-p">(</span><span class="tok-s">"Hello from C</span><span class="tok-se">\n</span><span class="tok-s">"</span><span class="tok-p">);</span> <span class="tok-p">}</span></code></pre> </div> </div> <div class="paragraph"> <p>Depending on your OS run the following commands to compile the above C code into a library.</p> </div> <div class="listingblock"> <div class="title">On Linux:</div> <div class="content"> <pre class="pygments highlight"><code data-lang="bash"><span></span>gcc<span class="tok-w"> </span>-c<span class="tok-w"> </span>-fpic<span class="tok-w"> </span>ncitest.c gcc<span class="tok-w"> </span>-shared<span class="tok-w"> </span>-o<span class="tok-w"> </span>libncitest.so<span class="tok-w"> </span>ncitest.o</code></pre> </div> </div> <div class="listingblock"> <div class="title">On Windows:</div> <div class="content"> <pre class="pygments highlight"><code data-lang="bat"><span></span>gcc -c ncitest.c gcc -shared -o ncitest.dll ncitest.o</code></pre> </div> </div> <div class="listingblock"> <div class="title">On macOS:</div> <div class="content"> <pre class="pygments highlight"><code data-lang="bash"><span></span>gcc<span class="tok-w"> </span>-dynamiclib<span class="tok-w"> </span>-o<span class="tok-w"> </span>libncitest.dylib<span class="tok-w"> </span>ncitest.c</code></pre> </div> </div> <div class="paragraph"> <p>Within the same directory where you compiled your C library, create a new Raku file that contains the below code and run it.</p> </div> <div class="listingblock"> <div class="title">ncitest.raku</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">use</span> <span class="tok-n">NativeCall</span>; <span class="tok-k">constant</span> <span class="tok-n">LIBPATH</span> = <span class="tok-s">"$*CWD/ncitest"</span>; <span class="tok-k">sub</span> <span class="tok-n">hellofromc</span>() <span class="tok-k">is</span> <span class="tok-k">native</span>(<span class="tok-n">LIBPATH</span>) { * } <span class="tok-n">hellofromc</span>();</code></pre> </div> </div> <div class="paragraph"> <div class="title">Explanation:</div> <p>First of all we declared that we will be using the <code>NativeCall</code> module.<br> Then we created a constant <code>LIBPATH</code> that holds the path to the C library.<br> Notice that <code>$*CWD</code> returns the current working directory.<br> Then we created a new Raku subroutine called <code>hellofromc()</code> that should act as a wrapper to its counterpart C function having the same name and residing in the C library found in <code>LIBPATH</code>.<br> All of this was done by using the <code>is native</code> trait.<br> Finally we called our Raku subroutine.</p> </div> <div class="paragraph"> <p>In essence, it all boils down to declaring a subroutine with the trait <code>is native</code> and the name of the C library.</p> </div> </div> <div class="sect2"> <h3 id="_renaming_a_function">15.2. Renaming a function</h3> <div class="paragraph"> <p>In the above part, we saw how we can call a very simple C function by wrapping it with a Raku subroutine having the same name, using the <code>is native</code> trait.</p> </div> <div class="paragraph"> <p>In some cases, we would want to change the name of the Raku subroutine.<br> To do so, we use the <code>is symbol</code> trait.</p> </div> <div class="paragraph"> <p>Lets modify the above Raku script and rename the Raku subroutine <code>hello</code> instead of <code>hellofromc</code></p> </div> <div class="listingblock"> <div class="title">ncitest.raku</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">use</span> <span class="tok-n">NativeCall</span>; <span class="tok-k">constant</span> <span class="tok-n">LIBPATH</span> = <span class="tok-s">"$*CWD/ncitest"</span>; <span class="tok-k">sub</span> <span class="tok-n">hello</span>() <span class="tok-k">is</span> <span class="tok-k">native</span>(<span class="tok-n">LIBPATH</span>) <span class="tok-k">is</span> <span class="tok-k">symbol</span>(<span class="tok-s">'hellofromc'</span>) { * } <span class="tok-n">hello</span>();</code></pre> </div> </div> <div class="paragraph"> <div class="title">Explanation:</div> <p>In case the Raku subroutine has a different name than its C counterpart, we should use the <code>is symbol</code> trait with the name of the original C function.</p> </div> </div> <div class="sect2"> <h3 id="_passing_arguments">15.3. Passing Arguments</h3> <div class="paragraph"> <p>Compile the following modified C library and run the Raku script found below again.<br> Notice how we modified both C and Raku code to accept a string (<code>char*</code> in C and <code>Str</code> in Raku)</p> </div> <div class="listingblock"> <div class="title">ncitest.c</div> <div class="content"> <pre class="pygments highlight"><code data-lang="c"><span></span><span class="tok-cp">#include</span><span class="tok-w"> </span><span class="tok-cpf"><stdio.h></span> <span class="tok-kt">void</span><span class="tok-w"> </span><span class="tok-nf">hellofromc</span><span class="tok-w"> </span><span class="tok-p">(</span><span class="tok-kt">char</span><span class="tok-o">*</span><span class="tok-w"> </span><span class="tok-n">name</span><span class="tok-p">)</span><span class="tok-w"> </span><span class="tok-p">{</span> <span class="tok-w"> </span><span class="tok-n">printf</span><span class="tok-p">(</span><span class="tok-s">"Hello, %s! This is C!</span><span class="tok-se">\n</span><span class="tok-s">"</span><span class="tok-p">,</span><span class="tok-w"> </span><span class="tok-n">name</span><span class="tok-p">);</span> <span class="tok-p">}</span></code></pre> </div> </div> <div class="listingblock"> <div class="title">ncitest.raku</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">use</span> <span class="tok-n">NativeCall</span>; <span class="tok-k">constant</span> <span class="tok-n">LIBPATH</span> = <span class="tok-s">"$*CWD/ncitest"</span>; <span class="tok-k">sub</span> <span class="tok-n">hello</span>(<span class="tok-nb">Str</span>) <span class="tok-k">is</span> <span class="tok-k">native</span>(<span class="tok-n">LIBPATH</span>) <span class="tok-k">is</span> <span class="tok-k">symbol</span>(<span class="tok-s">'hellofromc'</span>) { * } <span class="tok-n">hello</span>(<span class="tok-s">'Jane'</span>);</code></pre> </div> </div> </div> <div class="sect2"> <h3 id="_returning_values_2">15.4. Returning values</h3> <div class="paragraph"> <p>Lets repeat the process one more time and create a simple calculator that takes 2 integers and add them.<br> Compile the C library and run the Raku script.</p> </div> <div class="listingblock"> <div class="title">ncitest.c</div> <div class="content"> <pre class="pygments highlight"><code data-lang="c"><span></span><span class="tok-kt">int</span><span class="tok-w"> </span><span class="tok-nf">add</span><span class="tok-w"> </span><span class="tok-p">(</span><span class="tok-kt">int</span><span class="tok-w"> </span><span class="tok-n">a</span><span class="tok-p">,</span><span class="tok-w"> </span><span class="tok-kt">int</span><span class="tok-w"> </span><span class="tok-n">b</span><span class="tok-p">)</span><span class="tok-w"> </span><span class="tok-p">{</span> <span class="tok-w"> </span><span class="tok-k">return</span><span class="tok-w"> </span><span class="tok-p">(</span><span class="tok-n">a</span><span class="tok-w"> </span><span class="tok-o">+</span><span class="tok-w"> </span><span class="tok-n">b</span><span class="tok-p">);</span> <span class="tok-p">}</span></code></pre> </div> </div> <div class="listingblock"> <div class="title">ncitest.raku</div> <div class="content"> <pre class="pygments highlight"><code data-lang="raku"><span></span><span class="tok-k">use</span> <span class="tok-n">NativeCall</span>; <span class="tok-k">constant</span> <span class="tok-n">LIBPATH</span> = <span class="tok-s">"$*CWD/ncitest"</span>; <span class="tok-k">sub</span> <span class="tok-nb">add</span>(<span class="tok-nb">int32</span>,<span class="tok-nb">int32</span> --> <span class="tok-nb">int32</span>) <span class="tok-k">is</span> <span class="tok-k">native</span>(<span class="tok-n">LIBPATH</span>) { * } <span class="tok-nb">say</span> <span class="tok-nb">add</span>(<span class="tok-mi">2</span>,<span class="tok-mi">3</span>);</code></pre> </div> </div> <div class="paragraph"> <p>Notice how both C and Raku functions accept two integers and return one (<code>int</code> in C and <code>int32</code> in Raku)</p> </div> </div> <div class="sect2"> <h3 id="_types_2">15.5. Types</h3> <div class="paragraph"> <p>You might have asked yourself why did we use <code>int32</code> instead of <code>Int</code> in the latest Raku script.<br> Some Raku types like <code>Int</code>, <code>Rat</code> etc. can’t be used as is to pass and receive values from a C function.<br> One must use in Raku the same types as the ones in C.</p> </div> <div class="paragraph"> <p>Luckily Raku provides many types that map to their respective C counterpart.</p> </div> <table class="tableblock frame-all grid-all stretch"> <colgroup> <col style="width: 50%;"> <col style="width: 50%;"> </colgroup> <thead> <tr> <th class="tableblock halign-center valign-middle">C Type</th> <th class="tableblock halign-center valign-middle">Raku Type</th> </tr> </thead> <tbody> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>char</code></p></td> <td class="tableblock halign-center valign-middle" rowspan="2"><p class="tableblock"><code>int8</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>int8_t</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>short</code></p></td> <td class="tableblock halign-center valign-middle" rowspan="2"><p class="tableblock"><code>int16</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>int16_t</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>int</code></p></td> <td class="tableblock halign-center valign-middle" rowspan="2"><p class="tableblock"><code>int32</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>int32_t</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>int64_t</code></p></td> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>int64</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>unsigned char</code></p></td> <td class="tableblock halign-center valign-middle" rowspan="2"><p class="tableblock"><code>uint8</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>uint8_t</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>unsigned short</code></p></td> <td class="tableblock halign-center valign-middle" rowspan="2"><p class="tableblock"><code>uint16</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>uint16_t</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>unsigned int</code></p></td> <td class="tableblock halign-center valign-middle" rowspan="2"><p class="tableblock"><code>uint32</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>uint32_t</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>uint64_t</code></p></td> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>uint64</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>long</code></p></td> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>long</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>long long</code></p></td> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>longlong</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>float</code></p></td> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>num32</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>double</code></p></td> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>num64</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>size_t</code></p></td> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>size_t</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>bool</code></p></td> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>bool</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>char*</code> (String)</p></td> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>Str</code></p></td> </tr> <tr> <td class="tableblock halign-center valign-middle"><p class="tableblock">Arrays: For example <code>int*</code> (Array of int) and <code>double*</code> (Array of double)</p></td> <td class="tableblock halign-center valign-middle"><p class="tableblock"><code>CArray</code>: For example <code>CArray[int32]</code> and <code>CArray[num64]</code></p></td> </tr> </tbody> </table> <div class="admonitionblock note"> <table> <tr> <td class="icon"> <i class="fa icon-note" title="Note"></i> </td> <td class="content"> For more info on the Native Calling Interface, see <a href="https://docs.raku.org/language/nativecall" class="bare">https://docs.raku.org/language/nativecall</a> </td> </tr> </table> </div> </div> </div> </div> <div class="sect1"> <h2 id="_the_community">16. The Community</h2> <div class="sectionbody"> <div class="ulist"> <ul> <li> <p><a href="https://web.libera.chat/#raku">#raku</a> IRC channel. Much discussion happens on IRC.<br> This should be your go to place for any enquiry for which you want an immediate answer: <a href="https://raku.org/community/irc" class="bare">https://raku.org/community/irc</a></p> </li> <li> <p><a href="https://stackoverflow.com/questions/tagged/raku">StackOverflow Raku questions</a> is a place where questions about Raku can be answered more in-depth.</p> </li> <li> <p><a href="https://rakudoweekly.blog">Rakudo Weekly</a> a weekly overview of changes in and around Rakudo.</p> </li> <li> <p><a href="https://planet.raku.org/">Planet Raku</a> blog aggregator. Stay tuned by reading blog posts that focus on Raku.</p> </li> <li> <p><a href="https://www.reddit.com/r/rakulang/">/r/rakulang</a> subscribe to the Raku subreddit.</p> </li> <li> <p><a href="https://x.com/raku_news">@raku_news</a> follow the community on X.</p> </li> <li> <p><a href="https://fosstodon.org/@rakulang">@rakulang</a> follow the community on Mastodon.</p> </li> </ul> </div> </div> </div> </div> <div id="footnotes"> <hr> <div class="footnote" id="_footnotedef_1"> <a href="#_footnoteref_1">1</a>. Notations for intervals: <a href="https://en.wikipedia.org/wiki/Interval_(mathematics)#Notations_for_intervals" class="bare">https://en.wikipedia.org/wiki/Interval_(mathematics)#Notations_for_intervals</a> </div> </div> <div id="footer"> <div id="footer-text"> Last updated 2024-05-26 23:53:18 +0300 </div> </div> </body> </html>