本页面试图索引 Ruby 和 Raku 之间语法和语义上的高级差异。任何在 Ruby 中有效但在 Raku 中必须以不同方式编写的内容都应列在此处(而许多 Raku 特性和习惯用法则不会)。
因此,这不能被误认为是 Raku 的初学者教程或概述;它旨在作为具有强大 Ruby 背景的 Raku 学习者的技术参考。
基本语法§
语句结束分号§
Ruby 通过换行符(以及一些例外)检测大多数语句的结束,只要表达式完整即可。通常通过将运算符悬挂在行尾来分解长表达式,以确保解析将继续
foo + # In Ruby a trailing operator means parsing should continue
bar +
baz
在 Raku 中,您必须使用 ;
显式地终止语句,这允许更好地反馈并在分解长行时提供更大的灵活性。两个不需要显式 ;
的例外是块中的最后一个语句,以及块本身的右花括号之后(如果该行上没有其他内容)
my ;...;if 5 < < 10# No ; required after closing } because of the newlinesay "Done!"; # The ; is not required here if nothing follows
空格§
Ruby 允许在使用空格方面有惊人的灵活性,即使在严格模式下并打开警告的情况下也是如此
# unidiomatic but valid Ruby
puts"Hello "+
(people [ i]
. name
) . upcase+"!"if$greeted[i]<1
Raku 也支持程序员的自由和创造力,但将语法灵活性与它的一致、确定性、可扩展语法的设计目标相平衡,该语法支持单遍解析和有用的错误消息,干净地集成诸如自定义运算符之类的功能,并且不会导致程序员意外地错误地表达他们的意图。此外,"代码高尔夫" 的做法略微淡化了;Raku 的设计目的是在概念上比在按键上更简洁。
因此,在语法中有一些地方,空格在 Ruby 中是可选的,但在 Raku 中是强制性的或禁止的。许多这些限制不太可能影响到现实生活中的 Perl 代码(例如,在数组变量及其方括号之间不允许使用空格),但有一些限制不幸地会与一些 Ruby 黑客的习惯编码风格发生冲突
在参数列表的左括号之前不允许使用空格。
foo (3, 4, 1); # Not right in Ruby or Raku (in Raku this would# try to pass a single argument of type List to foo)foo(3, 4, 1); # Ruby and Rakufoo 3, 4, 1; # Ruby and Raku - alternative parentheses-less style在关键字之后必须使用空格
if(a < 0); ...; end # OK in Ruby
my ; ...;if ( < 0) # Rakuif < 0 # Raku, more idiomatic
while(x > 5); ...; end # OK in Ruby
my ; ...;while ( > 5) # Rakuwhile > 5 # Raku, more idiomatic
在后缀/后缀运算符(包括数组/哈希下标)之前不允许使用空格。
seen [ :fish ] = 1 # Ruby, not idiomatic but allowed
< fish > = 1; # Raku, no space allowed after 'seen'如果与现有的后缀/后缀运算符冲突,则在中缀运算符之前需要使用空格。
n<1 # Ruby (in Raku this would conflict with postcircumfix < >)
< 1; # Raku
.
方法调用,.public_send
§
方法调用语法使用点,就像 Ruby 一样
person.name # Ruby
my ; ...;.name # Raku
要调用一个直到运行时才知道其名称的方法
object.public_send(methodname, args); # Ruby
my ; my Str ; my ; ...;."$methodname"(); # Raku
如果您省略引号,那么 Raku 期望 $methodname
包含一个 Method
对象,而不是方法的简单字符串名称。
变量、符号、作用域和常见类型§
在 Ruby 中,变量使用符号主要用于指示作用域。$
用于全局作用域,@@
用于类作用域,@
用于实例作用域,没有符号用于局部变量(包括参数)。&
符号也用于指示方法引用。符号以 :
为前缀,但它们不是变量,因此不是真正的符号。
在 Raku 中,符号主要用于指示包含的值实现的角色,表明值的类型(或至少是接口)。符号是不变的,无论变量如何使用 - 你可以将它们视为变量名称的一部分。
变量的作用域由声明本身指示(my
、has
、our
等)。
变量作用域§
对于局部变量,Ruby 在赋值时使用隐式变量声明,并且仅限于当前块。在 Ruby 中,if
或 while
内置构造的内容不是块或作用域。
Raku 使用显式作用域指示符,并且从不隐式创建变量。你看到的每个 { ... }
都是一个作用域,包括条件或循环的主体。常用的作用域声明
foo = 7 # Ruby, variable scope is defined by first assignment and
# extends to the end of the current block
my = 7; # Raku, lexical scoped to the current blockour = 7; # Raku, package scopedhas = 7; # Raku, instance scoped (attribute)
$
标量§
$
符号始终与“标量”变量一起使用(例如 $name
)。这些是单值容器。
这是最通用的变量类型,对它的内容没有限制。请注意,你仍然可以访问/使用它的内容,例如 $x[1]
、$x{"foo"}
和 $f("foo")
。
@
数组§
@
符号始终与“数组”变量一起使用(例如 @months
、@months[2]
、@months[2, 4]
用于数组切片)。使用 @
符号的变量只能包含执行 Positional
角色的内容,表示位置索引和切片功能。
索引
puts months[2]; # Ruby
say [2]; # Raku值切片
puts months[8..11].join(',') # Ruby
say [8..11].join(',') # Raku
%
哈希§
%
符号始终与“哈希”变量一起使用(例如 %calories
、%calories<apple>
、%calories<pear plum>
)。使用 %
符号的变量只能包含执行 Associative
角色的内容。
Ruby 使用方括号来访问数组和哈希的值。Raku 使用花括号来表示哈希。可以使用尖括号版本,它始终自动引用其内容(没有引号的字符串)
副词可用于控制切片的类型。
索引
puts calories["apple"] # Ruby
say ; # Rakuputs calories["apple"] # Ruby puts calories[:apple] # Ruby, symbols for keys are common
say <apple>; # Raku - angle brackets instead of single-quotessay «"$key"»; # Raku - double angles interpolate as double-quotes值切片
puts calories.values_at('pear', 'plum').join(',') # Ruby puts calories.values_at(%w(pear plum)).join(',') # Ruby, pretty?
say .join(','); # Rakusay <pear plum>.join(','); # Raku (prettier)my = 'pear plum';say « ».join(','); # Raku, interpolated split键/值切片
puts calories.slice('pear', 'plum') # Ruby >= 2.5
say :kv.Hash; # Raku - use :kv adverbsay <pear plum>:kv.Hash; # Raku (prettier version)
&
子例程§
&
符号的使用方式与 Ruby 的 &
非常相似,用于引用命名子例程/运算符的函数对象而不调用它,即使用名称作为“名词”而不是“动词”。使用 &
符号的变量只能包含执行 Callable
角色的内容。
add = -> n, m { n + m } # Ruby lambda for an addition function
add.(2, 3) # => 5, Ruby invocation of a lambda
add.call(2, 3) # => 5, Ruby invocation of a lambda
my = -> , ; # Raku addition function(2, 3); # => 5, you can keep the sigiladd(2, 3); # => 5, and it works without it
def foo
...
end
foo_method = method(:foo); # Ruby
sub foo ;my = ; # Raku
some_func(&say) # Ruby pass a function reference
sub some_func ;some_func() # Raku passes function references the same way
在 Ruby 中,我们通常将一个块作为最后一个参数传递,这在 DSL 中尤其常用。这可以是通过 yield
调用的隐式参数,也可以是带有 &
前缀的显式块。在 Raku 中,Callable
参数始终被列出并通过变量名调用(而不是 yield),并且有多种调用函数的方法。
# Ruby, declare a method and call the implicit block argument
def f
yield 2
end
# Ruby, invoke f, pass it a block with 1 argument
f do |n|
puts "Hi #{n}"
end
# Raku, declare a method with an explicit block argumentsub f(:($))# Raku, invoke f, pass it a block with 1 argument# There are several other ways to do thisf(-> ); # Explicit argumentf -> ; # Explicit argument, no parenthesis# Additionally, if 'f' is a method on instance 'obj' you can use ':'# instead of parenthesismy ; ...;.f(-> ); # Explicit argument.f: -> ; # Explicit argument, no parenthesis
*
贪婪参数/参数扩展§
在 Ruby 中,你可以声明一个参数来使用 *
前缀将传递的参数的其余部分吸收到一个数组中。它在 Raku 中的工作方式类似
def foo(*args); puts "I got #{args.length} args!"; end # Ruby
sub foo(*) # Raku
上面的 Raku 版本略有不同,因为它在将参数吸收到 @args
中时,会自动删除一层嵌套(如果有)。
sub foo(*)foo([1, [2, 3], 4], 5, [6, 7]); # [1, [2, 3], 4, 5, 6, 7]
要保留参数的结构,可以使用 **
sub foo(**)foo([1, [2, 3], 4], 5, [6, 7]); # [[1, [2, 3], 4], 5, [6, 7]]
你可能希望将一个数组扩展为一组参数。在 Raku 中,这是使用 Slip
|
完成的
args = %w(a b c) # Ruby
foo(*args)
sub foo(, , ) ;my = <a b c>; # Rakufoo(|);
Raku 有许多更高级的传递参数和接收参数的方法,请参见 签名 和 捕获。
枝节§
Raku 另外使用“枝节”,它们是关于变量的进一步指示,位于符号和变量名的其余部分之间。示例
变量 | 描述 |
---|---|
$foo | 没有枝节的标量 |
$!foo | 私有实例变量 |
$.foo | 实例变量访问器 |
$*foo | 动态作用域变量 |
$^foo | 块的位置(占位符)参数 |
$:foo | 块的命名(占位符)参数 |
$=foo | POD(文档)变量 |
$?FILE | 当前源文件名。? 枝节表示编译时值 |
$~foo | 解析器看到的子语言,不常见 |
虽然这些示例都使用$
符号,但大多数可以使用@
(位置)或%
(关联)。
:
符号§
Raku 通常在 Ruby 使用符号的地方使用字符串。一个主要例子是在哈希键中。
address[:joe][:street] # Typical Ruby nested hash with symbol keys
my ; ...;<joe><street> # Typical Raku nested hash with string keys
Raku 有冒号对语法,有时看起来像 Ruby 符号。
:age # Ruby symbol
# All of these are equivalent for Raku:age ;# Raku pair with implicit True value:age(True) ;# Raku pair with explicit True valueage => True ;# Raku pair using arrow notation"age" => True ;# Raku pair using arrow notation and explicit quotes
你可能可以不用显式值就使用冒号对,并假装它是一个 Ruby 符号,但这不是 Raku 的惯用法。
运算符§
许多运算符在 Ruby 和 Raku 中都有类似的用法
,
列表分隔符+
数值加法-
数值减法*
数值乘法/
数值除法%
数值模运算**
数值幂运算! && ||
布尔值,高优先级not and or
布尔值,低优先级
你可以使用$x++
代替x += 1
作为递增变量的快捷方式。这可以用作前递增++$x
(递增,返回新值)或后递增$x++
(递增,返回旧值)。
你可以使用$x--
代替x -= 1
作为递减变量的快捷方式。这可以用作前递减--$x
(递减,返回新值)或后递减$x--
(递减,返回旧值)。
== != < > <= >=
比较§
Raku 中的比较在数值和字符串之间分开,以避免常见的错误。
== != < > <= >=
比较eq ne lt gt le ge
字符串比较
例如,使用==
尝试将值转换为数字,而eq
尝试将值转换为字符串。
<=>
三元比较§
在 Ruby 中,<=>
运算符返回 -1、0 或 1。在 Raku 中,它们返回Order::Less
、Order::Same
或Order::More
。
<=>
强制比较为数值上下文。
leg
(“Less, Equal, or Greater?”)强制比较为字符串上下文。
cmp
执行<=>
或leg
,具体取决于其参数的现有类型。
~~
智能匹配运算符§
这是一个非常常见的匹配运算符,类似于 Ruby 中的===
。以下是一些示例
my ; ...;say "match!" if ~~ /bar/; # Regex matchsay "match!" if ~~ "bar"; # String matchsay "match!" if ~~ :(Int, Str); # Signature match (destructure)
Ruby 中的等效代码为
foo = "bar"
puts "match 1!" if /bar/ === foo # Regex match
puts "match 2!" if foo === "bar" # String match
puts "match 3!" if String === foo # Class match
请注意,在这种情况下,===
不是对称的;在第一种和最后一种情况下,变量必须位于右侧。Ruby 中也没有等效于签名类的类。
有关此功能的更多信息,请参阅S03/智能匹配。
& | ^
数值按位运算§
& | ^
布尔运算§
在 Raku 中,这些单字符运算符已被删除,并被替换为双字符运算符,这些运算符会将其参数强制转换为所需的上下文。
# Infix ops (two arguments; one on each side of the op) +& +| +^ And Or Xor: Numeric ~& ~| ~^ And Or Xor: String ?& ?| ?^ And Or Xor: Boolean # Prefix ops (one argument, after the op) +^ Not: Numeric ~^ Not: String ?^ Not: Boolean (same as the ! op)
&.
条件链运算符§
Ruby 使用&.
运算符来链接方法,而不会在其中一个调用返回 nil 时引发错误。在 Raku 中,使用.?
来实现相同目的。
<< >>
数值左移、右移运算符,铲子运算符§
被+<
和+>
替换。
puts 42 << 3 # Ruby
say 42 +< 3; # Raku
请注意,Ruby 通常使用<<
运算符作为“铲子运算符”,它类似于.push
。这种用法在 Raku 中并不常见。
=>
和:
键值分隔符§
在 Ruby 中,=>
用于哈希字面量声明和参数传递中的键值对上下文中。当左侧是符号时,:
用作简写。
在 Raku 中,=>
是 Pair 运算符,其原理完全不同,但在许多情况下工作方式相同。
如果您在哈希字面量中使用 =>
,那么用法非常相似
hash = { "AAA" => 1, "BBB" => 2 } # Ruby, though symbol keys are more common
my = ( AAA => 1, BBB => 2 ); # Raku, uses ()'s though {} usually work
? :
三元运算符§
在 Raku 中,这是用两个问号而不是一个问号,以及两个感叹号而不是一个冒号来拼写的。这种与常见三元运算符的偏差消除了几种情况的歧义,并使 false-case 更突出。
result = ( score > 60 ) ? 'Pass' : 'Fail'; # Ruby
my ; ...;my = ( > 60 ) ?? 'Pass' !! 'Fail'; # Raku
+
字符串连接§
被波浪号替换。助记符:想想用针线将两个字符串“缝合”在一起。
$food = 'grape' + 'fruit' # Ruby
my = 'grape' ~ 'fruit'; # Raku
字符串插值§
在 Ruby 中,"#{foo}s"
将嵌入双引号字符串中的块分隔开。在 Raku 中,去掉 #
前缀:"{$foo}s"
。与 Ruby 一样,您可以将任意代码放入嵌入块中,它将在字符串上下文中呈现。
简单变量可以插值到双引号字符串中,而无需使用块语法
# Ruby
name = "Bob"
puts "Hello! My name is #{name}!"
# Raku
my $name = "Bob";
say "Hello! My name is $name!"
Ruby 中嵌入块的结果使用 .to_s
获取字符串上下文。Raku 使用 .Str
或 .gist
来实现相同的效果。
复合语句§
条件语句§
if
elsif
else
unless
§
这在 Ruby 和 Raku 之间非常相似,但 Raku 使用 { }
来清楚地划分块。
# Ruby
if x > 5
puts "Bigger!"
elsif x == 5
puts "The same!"
else
puts "Smaller!"
end
# Rakumy ; ...;if > 5elsif == 5else
将条件表达式绑定到变量的方式略有不同
if x = dostuff(); ...; end # Ruby
sub dostuff() ;if dostuff() -> # Raku, block-assignment uses arrow
unless
条件语句在 Raku 中只允许一个块;它不允许 elsif
或 else
子句。
case
-when
§
Raku 的 given
-when
结构就像一系列 if
-elsif
-else
语句,它的直接对应物是 Ruby 的 case
-when
结构。就像 Ruby 对 case
-when
表达式中的每个条件使用 ===
(case 等于)运算符一样,Raku 同样使用 given
-when
中的智能匹配 ~~
运算符。
它具有以下一般结构
given EXPR { when EXPR { ... } when EXPR { ... } default { ... } }
在最简单的形式中,该结构如下
my ; ...;given
这很简单,因为标量值在 when
语句中匹配。更一般地说,匹配实际上是对输入值的智能匹配,因此可以使用更复杂的实体(如正则表达式)而不是标量值来进行查找。
循环§
while
until
§
基本保持不变;条件周围的括号是可选的,但如果使用,则不能紧跟关键字,否则它将被视为函数调用。将条件表达式绑定到变量的方式也略有不同
while x = dostuff(); ...; end # Ruby
sub dostuff ; ...;while dostuff() -> # Raku
for
.each
§
for
循环在 Ruby 中很少见,相反,我们通常对可枚举对象使用 .each
。对 Raku 的最直接翻译是使用 .map
来代替 .each
和 .map
,但我们通常直接使用 for
循环。
# Ruby for loop
for n in 0..5
puts "n: #{n}"
end
# Ruby, more common usage of .each
(0..5).each do |n|
puts "n: #{n}"
end
# Rakufor 0..5 -># Raku, misusing .map(0..5).map: ->
在 Ruby 中,.each
的迭代变量是列表元素的副本,修改它不会对原始列表产生任何影响。请注意,它是引用的副本,因此您仍然可以更改它引用的值。
在 Raku 中,该别名是只读的(为了安全起见),因此行为与 Ruby 完全相同,除非您将 ->
更改为 <->
。
cars.each { |car| ... } # Ruby; read-only reference
my ; ...;for -> # Raku; read-onlyfor <-> # Raku; read-write
流程中断语句§
与 Ruby 相同
下一个
重做
Ruby 的 break
在 Raku 中是 last
。
正则表达式 (regex / regexp)§
Raku 中的正则表达式与 Ruby 中的正则表达式有很大不同,并且功能更强大。例如,默认情况下会忽略空格,并且所有字符都必须转义。正则表达式可以轻松地组合和声明,以构建高效的语法。
Raku 正则表达式有很多强大的功能,特别是使用相同的语法定义整个语法。请参阅 正则表达式 和 语法。
.match
方法和 =~
运算符§
在 Ruby 中,可以使用 =~
正则表达式匹配运算符或 .match
方法对变量进行正则表达式匹配。在 Raku 中,使用 ~~
智能匹配运算符或 .match
方法。
next if line =~ /static/ # Ruby
next if line !~ /dynamic/; # Ruby
next if line.match(/static/) # Ruby
my ; ...;next if ~~ /static/; # Rakunext if !~~ /dynamic/ ; # Rakunext if .match(/static/); # Raku
或者,可以使用 .match
和 .subst
方法。请注意,.subst
是非变异的。请参阅 S05/Substitution。
.sub
和 .sub!
§
在 Raku 中,通常使用 s///
运算符进行正则表达式替换。
fixed = line.sub(/foo/, 'bar') # Ruby, non-mutating
my ; ...;my = .subst(/foo/, 'bar') # Raku, non-mutating
line.sub!(/foo/, 'bar') # Ruby, mutating
my ; ...;~~ s/foo/bar/; # Raku, mutating
正则表达式选项§
将任何选项从正则表达式的末尾移动到开头。这可能需要您在普通匹配(如 /abc/
)上添加可选的 m
。
next if $line =~ /static/i # Ruby
my ; ...;next if ~~ m:i/static/; # Raku
空格被忽略,大多数内容必须用引号括起来§
为了提高可读性和可重用性,Raku 正则表达式中的空格不重要。
/this is a test/ # Ruby, boring string
/this.*/ # Ruby, possibly interesting string
/ this " " is " " a " " test /; # Raku, each space is quoted/ "this is a test" /; # Raku, quoting the whole string/ this .* /; # Raku, possibly interesting string
特殊匹配器通常位于 <> 语法下§
Raku 正则表达式支持许多特殊匹配语法的用例。这里不会列出所有用例,但通常情况下,断言不会被 ()
包围,而是被 <>
包围。
对于字符类,这意味着
[abc]
变成<[abc]>
[^abc]
变成<-[abc]>
[a-zA-Z]
变成<[a..zA..Z]>
[[:upper:]]
变成<:upper>
[abc[:upper:]]
变成<[abc]+:Upper>
对于环视断言
(?=[abc])
变成<?[abc]>
(?=ar?bitrary* pattern)
变成<before ar?bitrary* pattern>
(?!=[abc])
变成<![abc]>
(?!=ar?bitrary* pattern)
变成<!before ar?bitrary* pattern>
(?<=ar?bitrary* pattern)
变成<after ar?bitrary* pattern>
(?<!ar?bitrary* pattern)
变成<!after ar?bitrary* pattern>
(与 <> 语法无关,“环视” /foo\Kbar/
变成 /foo <( bar )> /
(?(?{condition))yes-pattern|no-pattern)
变成[ <?{condition}> yes-pattern | no-pattern ]
最长标记匹配 (LTM) 替代了交替§
在 Raku 正则表达式中,|
执行最长标记匹配 (LTM),它根据一组规则来决定哪个交替匹配模棱两可的匹配,而不是根据哪个在正则表达式中先写。
要避免新的逻辑,请将 Ruby 正则表达式中的任何 |
更改为 ||
。
与文件相关的操作§
将文本文件中的行读取到数组中§
Ruby 和 Raku 都可以轻松地将文件中的所有行读取到单个变量中,并且在这两种情况下,每行都删除了换行符。
lines = File.readlines("file") # Ruby
my = "file".IO.lines; # Raku, create an IO object from a string
遍历文本文件中的行§
不建议将整个文件读入内存。Raku 中的 .lines
方法返回一个延迟序列,但将其分配给数组会强制读取文件。最好迭代结果
# Ruby
File.foreach("file") do |line|
puts line
end
# Rakufor "file".IO.lines ->
面向对象§
基本类、方法、属性§
Ruby 和 Raku 中的类定义方式类似,都使用 class
关键字。Ruby 使用 def
定义方法,而 Raku 使用 method
。
# Ruby
class Foo
def greet(name)
puts "Hi #{name}!"
end
end
# Raku
在 Ruby 中,你可以在不事先声明的情况下使用属性,你可以通过 @
符号识别它是属性。你还可以使用 attr_accessor
及其变体轻松创建访问器。在 Raku 中,你使用 has
声明和各种符号。你可以使用 !
符号表示私有属性,或使用 .
创建访问器。
# Ruby
class Person
attr_accessor :age # Declare .age as an accessor method for @age
def initialize
@name = 'default' # Assign default value to private instance var
end
end
# Raku
创建类的实例使用 .new
方法。在 Ruby 中,你必须在 initialize
中手动分配实例变量。在 Raku 中,你获得一个默认构造函数,它接受访问器属性的键值对,并且可以在 TWEAK
方法中进行进一步设置。与 Ruby 一样,你可以覆盖 new
本身以实现更高级的功能,但这很少见。
# Ruby
class Person
attr_accessor :name, :age
def initialize(attrs)
@name = attrs[:name] || 'Jill'
@age = attrs[:age] || 42
@birth_year = Time.now.year - @age
end
end
p = Person.new( name: 'Jack', age: 23 )
# Rakumy = Person.new( name => 'Jack', age => 23 )
私有方法§
Raku 中的私有方法在声明时在名称前加 !
,并且使用 !
而不是 .
调用。
# Ruby
class Foo
def visible
puts "I can be seen!"
hidden
end
private
def hidden
puts "I cannot easily be called!"
end
end
# Raku
需要注意的是,在 Ruby 中,子对象可以访问父对象的私有方法(因此它们更像是其他语言中的“受保护”方法)。在 Raku 中,子对象不能调用父对象的私有方法。
元编程§
以下是一些元编程的示例。请注意,Raku 使用插入符号将元方法与普通方法区分开来。
# Ruby
person = Person.new
person.class
person.methods
person.instance_variables
# Raku;...my = Person.new;.^name; # Raku, returns Person (class).^methods; # Raku, using .^ syntax to access metamethods.^attributes;
与 Ruby 一样,在 Raku 中,一切都是对象,但并非所有操作都等同于 .public_send
。许多运算符是全局函数,它们使用类型化多重分派(带有类型的函数签名)来决定使用哪个实现。
5.public_send(:+, 3) # => 8, Ruby
&[+](5, 3) # => 8, Raku, reference to infix addition operator&[+].^candidates # Raku, lists all signatures for the + operator
有关更多详细信息,请参阅 元对象协议。
环境变量§
Raku 模块库路径§
在 Ruby 中,用于指定模块额外搜索路径的环境变量之一是 RUBYLIB
。
$ RUBYLIB="/some/module/lib" ruby program.rb
在 Raku 中,这类似,你只需要更改名称。正如你可能猜到的,你只需要使用 RAKULIB
$ RAKULIB="/some/module/lib" raku program.raku
与 Ruby 一样,如果你没有指定 RAKULIB
,则需要通过 use lib
编译指示在程序中指定库路径
# Ruby and Rakuuse lib '/some/module/lib';
其他§
从模块中导入特定函数§
在 Ruby 中,没有内置方法可以从模块中选择性地导入/导出方法。
在 Raku 中,你使用 is export
角色指定要导出的函数,并且具有此角色的所有子程序都将被导出。因此,以下模块 Bar
导出子程序 foo
和 bar
,但不导出 baz
unit ; # remainder of the file is in module Bar { ... }sub foo() is exportsub bar() is exportsub baz()
要使用此模块,只需 use Bar
,函数 foo
和 bar
即可使用
use Bar;foo(1); #=> "foo 1"bar(2); #=> "bar 2"
如果你尝试使用 baz
,编译时会引发“未声明的例程”错误。
一些模块允许选择性地导入函数,这将类似于
use Bar <foo>; # Import only foofoo(1); #=> "foo 1"bar(2); # Error!
OptionParser
,解析命令行标志§
Raku 中的命令行参数开关解析由 MAIN
子程序的参数列表完成。
# Ruby
require 'optparse'
options = {}
OptionParser.new do |opts|
opts.banner = 'Usage: example.rb --length=abc'
opts.on("--length", "Set the file") do |length|
raise "Length must be > 0" unless length.to_i > 0
options[:length] = length
end
opts.on("--filename", "Set the file") do |filename|
options[:file] = filename
end
opts.on("--verbose", "Increase verbosity") do |verbose|
options[:verbose] = true
end
end.parse!
puts options[:length]
puts options[:filename]
puts 'Verbosity ', (options[:verbose] ? 'on' : 'off')
ruby example.rb --filename=foo --length=42 --verbose
42
foo
Verbosity on
ruby example.rb --length=abc
Length must be > 0
# Rakusub MAIN ( Int : where * > 0, : = 'file.dat', Bool : )
raku example.raku --file=foo --length=42 --verbose
42
foo
Verbosity on
raku example.raku --length=abc
Usage:
example.raku [--length=<Int>] [--file=<Any>] [--verbose]
请注意,Raku 在命令行解析错误时会自动生成完整的用法消息。
RubyGems,外部库§
请参阅 https://raku.land/,这里提供了越来越多的 Raku 库以及管理它们的工具。
如果您使用的模块尚未转换为 Raku,并且本文件中未列出替代方案,则其在 Raku 下的使用可能尚未得到解决。
您可以尝试使用 Inline::Ruby 从您的 Raku 程序中调用现有的 Ruby 代码。这使用嵌入的 ruby
解释器实例来运行从您的 Raku 脚本调用的 Ruby 代码。请注意,这是一个实验性库。您可以类似地使用 Inline::Perl5、Inline::Python 等调用其他语言的库。