[譯][Perl 6] 5to6-perlfunc

araraloren發表於2019-02-16

About

-    Perl 6 document
-    翻譯

Translation

原文

從 Perl 5到 Perl 6

函式

描述

一個全面的(希望如此)Perl 5內建函式在 Perl 6中的等價物列表,並在必要時記錄他們的差異。

注意

我將不會詳細的解釋函式,本文件只是嘗試引導你從 Perl 5 的 perlfunc 文件過渡到他們在 Perl 6的等價物,如果想了解 Perl 6函式的完整文件,請參閱 Perl 6文件。
一個一般意見是:Perl 6比 Perl 5 更加物件導向,在 Perl 6中,所有東西都是物件,然而如果你不想這麼做的話,語言足夠靈活到不強制你工作在物件導向風格。意思就是,不管怎樣,有很多函式呼叫由function(@args)風格變為了現在的@args.function風格(罕見情況下,僅有方法呼叫),這在下面的正文中會很顯然,不過這可以讓更快的進入意境。
還有,除非另有說明,“function”一詞意思就是一個func(@args)風格的函式,同時“method”一詞代表一個@args.func風格的函式。

原始碼

我的資訊來自https://doc.perl6.org/設計文件用做補充,並由irc.freenode.org #perl6 頻道中的成員負責輸入(??)。

字母順序的 Perl 函式

檔案測試

  • -X FILEHANDLE(檔案控制程式碼)

  • -X EXPR(表示式)

  • -X DIRHANDLE(目錄控制程式碼)

  • -X

對於檔案測試 Perl 6給了你兩種選擇,你可以使用智慧匹配(~~)或者呼叫對應的方法。
在 Perl 6中進行檔案測試,你不必像傳統方式一樣需要開啟一個檔案控制程式碼(當然你仍然可以使用檔案控制程式碼),簡單的向檔名字後面追加.IO即可。下面是使用智慧匹配檢測一個檔案是否可讀的示例:

`/path/to/file`.IO ~~ :r

你仍然可以利用一個已經開啟的檔案控制程式碼完成測試,現在我們有一個檔案控制程式碼$fh,使用方法呼叫語法完成可讀性檔案測試如下:

$fh.r

大多數之前的檔案測試都有和智慧匹配一起使用的帶冒號的版本:

:e Exists
:d Directory
:f File
:l Symbolic link
:r Readable
:w Writeable
:x Executable
:s Size
:z Zero size

所有這些測試也都可以作為方法使用(不加冒號)。
下面的三種測試只有方法呼叫版本:

$fh.modified;    # -M $fh
$fh.accessed;    # -A $fh
$fh.changed;    # -C $fh

Perl 5中其它的檔案測試操作在還未在 Perl 6中實現。
關於檔案測試的文件可以在這裡找到。
這裡有更多的關於讀寫檔案的資訊,還有下面的open()小節對你也會有幫助。

abs

  • abs VALUE(值)

可以是一個函式(abs(x)),也可以是一個方法。然而有一個問題,方法繫結的優先順序大於-(負號),所以,-15.abs將作為-(15.abs)求值,結果是-15,在這種情況下,你可能需要做類似與(-15).abs的處理。
在缺少一個值的時候,abs可以工作在$_上面,但是不是一個函式,而是一個方法,你需要用.abs替換比較簡單的abs來呼叫它。

accept

  • accept NEWSOCKET, GENERICSOCKET

accept是一個你可以在伺服器端使用的方法,例如$server.accept(),作為原來封裝的地址返回值替代,它返回一個socket,最有可能是一個IO::Socket物件。

alarm

  • alarm SECONDS

[需要進一步研究]已經沒有alarm()了,有人建議用新的併發功能取代它,比如Promise.in,但是為了真正模擬它可能需要一些“挖掘”。

atan2

  • atan2 Y, X

即可以作為函式又可以作為方法使用,下面的兩種方式是等價的:

atan2(100);
100.atan2;

bind

  • bind SOCKET, NAME

[需要進一步研究]在 Perl 6沒有和 socket 相關函式bind()簽名一致的函式,作為一個猜想,socket 繫結在建立一個新的 socket 物件的時候完成。

binmode

  • binmode FILEHANDLE

作為替代手段,你可以在開啟檔案的時候使用:bin檔案模式,比如 my $fh = open(`/path/to/file`, :bin);

bless

  • bless REF, CLASSNAME

因為 Perl 6中類的建立發生了改變,可能會比 Perl 5中更少被用到,現在它是一個方法也是一個函式。Perl 6文件中說,它可以建立一個和 invocant 型別一樣的新的物件,使用命名引數初始化屬性,然後返回建立的物件。如果你正在移植一個 Perl 5的模組到 Perl 6,很有可能你想使用new來建立物件,而不是bless,雖然有些情況下,後者也會有用。

break

  • break

在 Perl 6中被移除,如果你想跳出given塊結構,你可能需要看一下proceedsucceed,地址是這裡

caller

  • caller EXPR

[需要進一步研究]在 Perl 5中caller已經被callframe取代,一個簡單的callframe呼叫不會有很大的用處,它不返回有用的資訊,而是一個 CallFrame 物件。在 Perl 5中,檔名字和檔案行數作為caller的第二、三個返回值返回,它們現在在callframe.annotations裡面,你可以使用callframe().annotations.<file line>獲取他們,或者使用callframe().annotations.<file>以及callframe().annotations.<line>分別獲取。[??]然而,如果沒有callframe,這並不是一個獲取包名的簡單方式。

chdir

  • chdir EXPR

似乎和 Perl 5中一樣。

chmod

  • chmod LIST

和 Perl 5中一樣是函式,只是8進位制數的表示有些不大一樣(是0o755而不是0755),你也可以把它作為方法使用,比如$fh.chmod(0o755)

chomp

  • chomp VARIABLE

chomp的行為和 Perl 5中有些不同,它對目標不產生影響,而是返回一個去除邏輯換行符的新的目標,也就是$x = "howdyn"; $y = chomp($x);,結果是$x包含“howdyn”以及$y包含“howdy”。同樣可以作為方法使用,也就是$y = $x.chomp

chop

  • chop VARIABLE

chomp一樣,在 Perl 6中,它返回被短切以後的字串,而不是直接短切替換,也就是$x = "howdy"; $y = chop($x);,結果是$x包含“howdy”以及$y包含“howd”。同樣可以作為方法使用:$y = $x.chop

chown

  • chown LIST

Perl 6中沒有chown

chr

  • chr NUMBER

和 Perl 5的版本相似,把目標強制轉換成整數,然後作為一個 Unicode code point 並返回相關的字元,可以作為函式或者方法使用:

chr(65);    # 輸出 A
65.chr;        # 輸出 A

chroot

  • chroot FILENAME

似乎在 Perl 6中不存在。

close

  • close FILEHANDLE

像 Perl 5中那樣,關閉一個檔案控制程式碼,返回一個邏輯值。close $fh或者$fh.close將會同時提供。

closedir

  • closedir DIRHANDLE

現在, Perl 6中並沒有closedir函式,當它被實現的時候,它可能是IO::Dir的一個方法。

connect

  • connect SOCKET, NAME

文件中沒有描述清楚,但是似乎connect將會是IO::Socket類的方法。

continue

  • continue BLOCK

  • continue

作為continue塊使用方法的替代,你可以使用NEXT塊,更接近 Perl 5中continue用法的是proceed/succeed

cos

  • cos EXPR

和 Perl 5中一樣,但是還可以作為方法使用,也就是(1 / 60000).cos

crypt

  • crypt PLAINTEXT, SALT

在 Perl 6中似乎沒有實現。

dbm function

  • dbmclose HASH

  • dbmopen HASH, DBNAME, MASK

這些函式在 Perl 5中很大程度上被取代了,不太可能出現在 Perl 6中(儘管 Perl 6的資料庫實現可能是不成熟的)。

defined

  • defined EXPR

它可能像你期望的那樣工作,但是從技術上講對於型別物件它返回False,其它情況返回True。它使得當你沒有為一個東西賦值時$num.perl會返回Any或者當你賦值了返回當前值更有意義。當然,你也可以作為一個方法使用它:$num.defined

delete

  • delete EXPR

Perl 6使用新的通過指定:deleet副詞的副詞語法取代了它,比如my $delete_value = %hash{$key}:delete;my $delete_value = @array[$i]:delete;

die

  • die LIST

和 Perl 5版本的功能相似,但是 Perl 6的異常機制比 Perl 5更強大,更靈活。參見exceptions。如果你想忽略堆疊蹤跡和位置,就像 Perl 5中的die "...n",可以這樣:

note "...
";
exit 1;

do

  • do BLOCK

    和 Perl 5版本的功能相似,不過注意`do`和`BLOCK`之間必須有一個空白。
  • do EXPR

    被 Perl 6中的`EVALFILE`取代。
    

dump

  • dump LABEL

根據S29描述,dump已經被廢棄了。

each

  • each HASH

沒有完全等效的函式,不過你可以使用%hash.kv,它會返回一個鍵值列表,比如:for %hash.kv -> $k, $v { say "$k:$v" }
順便,我們這裡提到的->被叫做箭頭語句塊,雖然文件中有很多這種例子,但是並沒有一個關於它是如何運作的清晰的解釋。s04#The_for_statement對你可能有些幫助,還有設計文件的S06#Pointy_blocks,另外這裡也有一些資訊。

eof

  • eof FILEHANDLE

在 Perl 6,可能沒有這樣的一個函式了,而是作為一個方法,也就是$filehandle.eof,如果檔案已經到達末尾它會返回True

eval

  • eval EXPR

EVAL替代,注意的是EVAL不進行任何異常處理。

evalbytes

  • evalbytes EXPR

在 Perl 6中似乎不存在。

exec

  • exec LIST

Perl 6中沒有函式跟 Perl 5中的exec相同,shellrun類似於 Perl 5中的system,但是exec在執行了系統命令之後不再返回的特性需要用類似shell($command);exit();或者exit shell($command)的東西來模擬。

exists

  • exists EXPR

在 Perl 6中不是一個函式,而是一個副詞:

%hash{$key}:exists;
@array[$i]:exists;

exit

  • exit EXPR

看起來和 Perl 5中一樣。

exp

  • exp EXPR

和 Perl 5中一樣,但是也可以作為方法使用: 5.exp

fc

  • fc EXPR

看起來和 Perl 5中一樣。

fcntl

  • fcntl FILEHANDLE, FUNCTION, SCALAR

似乎在 Perl 6中不存在。

__FILE__

  • __FILE__

$?FILE取代。

fileno

  • fileno FILEHANDLE

S32 表明會作為方法提供,但是似乎現在並未實現。

flock

  • flock FILEHANDLE, OPERATION

目前並未實現。

fork

  • fork

並未作為內建函式實現,但是可以通過Native Call介面使用,例如:use NativeCall; sub fork returns win32 is native { * }; say fork;

formats

  • format

  • fromline PICTURE, LIST

Perl 6沒有內建的formats。

getc

  • getc FILEHANDLE

和 Perl 5一樣從輸入流中讀取一個字元,現在也可以作為一個方法使用:$filehandle.getc

getlogin

  • getlogin

S29列出了它,但是好像還沒有實現。

getpeername

  • getpeername SOCKET

S29列出了它,但是實現似乎並不清楚,或者就此而言,(並未?)實現(?原文意思看不懂,for that matter, implemented.)。

getpgrp

  • getpgrp PID

看起來沒有實現。

getpriority

  • getpriority WHICH, WHO

看起來沒有實現。

get and set function

  • getpwnam NAME

  • getgrnam NAME

  • gethosybyname NAME

  • getnetbyname NAME

  • getprotobyname NAME

  • getpwuid UID

  • getgrgid GID

  • getservbyname NAME, PROTO

  • gethostbyaddr ADDR, ADDRTYPE

  • getnetbyaddr ADDR, ADDRTYPE

  • getprotobynumber NUMBER

  • getservbyport PORT, PROTO

  • getpwent

  • getgrent

  • gethostent

  • getnetent

  • getprotoent

  • getservent

  • setpwent

  • setgrent

  • sethostent STAYOPEN

  • setnetent STAYOPEN

  • setprotoent STAYOPEN

  • setservent STAYOPEN

  • endpwent

  • endgrent

  • endhostent

  • endnetent

  • endprotoent

  • endservent

[需要進一步研究]似乎這個列表中的函式可以被一些 Roles 比如 User, Group 等處理。

getsock*

  • getsockname SOCKET

  • getsocketopt SOCKET, LEVEL, OPTNAME

[需要進一步研究]現在看起來可能被實現成某種 IO::Socket 物件,但是具體細節不詳。

glob

  • glob EXPR

在S32中一個例子使用過,但是似乎沒有實現。

gmtime

  • gmtime EXPR

localtimegmtime的各種功能似乎在DateTime物件裡,比如獲取一個 UTC 格式的當前時間的DateTime物件,可以這麼用:my $gmtime = DateTime.now.utc

goto

  • goto LABEL

  • goto EXPR

  • goto &NAME

[需要進一步研究]在 S04中有所描述,但是並不完善。

grep

  • grep BLOCK LIST

  • grep EXPR, LIST

在 Perl 6依然存在,不過需要注意的是程式碼塊之後需要一個逗號,即@foo = grep {$_ == "bars"}, @baz,也可以作為一個方法使用:@foo = @bar.grep(/^f/)

hex

  • hex EXPR

被副詞形式:16取代,例如:16("aF")返回 175。
另外,可以使用.base方法得到同樣的結果:0xaF.base(10)
碰巧.Str預設顯示的是 10 進位制,所以如果你只是say 0xaF,它依然會列印 175,但這樣不是很直觀,所以可能不是最好的方式。

import

  • import LIST

首先在 Perl 5 中它從來不是一個函式,在 Perl 6中,通常,函式可以宣告為匯出或者不匯出,所有可匯出的函式一起匯出,然而,可選擇的匯出也是可能的,但是這超出了本文件的範圍,詳見這裡

index

  • index STR, SUBSTR, POSITION

和 Perl 5中一樣,也可以作為一個方法使用: "howdy!".index("how"); # 返回值 0

int

  • int EXPR

在 Perl 6裡面它是和 Perl 5中一樣 的truncate(截斷)函式(也作為方法提供),你可能直接使用它作為 Perl 5程式碼的移植版本,但是在 Perl 6中,你可以對一個數字方便的直接呼叫 .Int方法。3.9.Int; # 返回值 3以及3.9.truncate是一樣的。

ioctl

  • ioctl FILEHANDLE, FUNCTION, SCALAR

目前在 Perl 6中並未實現。

join

  • join EXPR, LIST

和 Perl 5中一樣,亦可以作為方法使用:@x.join(`,`)

keys

  • keys HASH

和 Perl 5中一樣,也可以作為方法使用:%hash.keys

kill

  • kill SIGNAL, LIST

  • kill SIGNAL

現在是Proc::ASync類的一部分,但是看起來和 Perl 5中一樣工作。

last

  • last LABEL

  • last EXPR

  • last

和 Perl 5中一樣。

lc

  • lc EXPR

和 Perl 5中一樣,還可以作為方法使用:"UGH".lc

lcfirst

  • lcfirst EXPR

在 Perl 6中不存在。

length

  • length EXPR

chars取代,通常作為一個方法使用($string.chars),但是也可以作為函式使用。

__LINE__

  • __LINE__

$?LINE取代。

link

  • link OLDFILE, NEWFILE

在 Perl 6裡面屬於IO::Path類的一部分,和 Perl 5中唯一的區別就是引數的順序變了,現在是link($original, $linked_file)

listen

  • listen SOCKET, QUEUESIZE

文件中沒有明確的描述,但是看起來listen會作為IO::Socket的一個方法。

local

  • local EXPR

Perl 6中對等的是temp

localtime

  • localtime EXPR

localtime的大部分的功能都可以在DateTime中找到,localtime特定的部分如下:

my $d = DateTime.now;

$sec    = $d.second;        # 可能是分鐘秒
$min    = $d.minute;        #
$hour   = $d.hour;          #
$mday   = $d.day-of-month;  # 或者 $d.day; 1 .. 31
$mon    = $d.month;         # 1 .. 12
$year   = $d.year;          #
$wday   = $d.day-of-week;   # 1 => Monday, 2 => Tuesday, ect.
$yday   = $d.day-of-year;   # 1 .. 366

注意在 Perl 6中的範圍並不是基於0的,就像上面的例子那樣。
好像沒有一種明確的方式可以得到 Perl 5中的$isdst對應的值, Perl 5中提供的scalar(localtime)已經不可用了,$d.Str會返回類似“2015-06-29T12:49:31-04:00”的東西。

lock

  • lock THING

在 Perl 6裡面,是Lock類的一個方法。

log

  • log EXPR

在 Perl 6中可用,亦可以作為方法使用,也就是log(2)2.log效果一樣。

lstat

  • lstat FILEHANDLE

  • lstat EXPR

  • lstat DIRHANDLE

  • lstat

可能在 Perl 6中的IO類的某處實現了,現在並不是很清楚在哪裡。

m//

  • m//

正規表示式在 Perl 6中有點不一樣,但是匹配操作依然存在,如果你想重寫 Perl 5的程式碼,最重要的區別就是=~被智慧匹配運算子~~取代,同樣,!~!~~取代,正則操作的設定都是副詞並且複雜,如想了解細節,參見Adverbs

map

  • map BLOCK LIST

  • map EXPR, LIST

作為一個函式,和 Perl 5中不同的地方是如果你需要一個程式碼塊,程式碼塊後面必須跟著一個逗號,也可以作為一個方法使用:@new = @old.map: { $_ * 2 }

mkdir

  • mkdir FILENAME, MASK

  • mkdir FILENAME

和 Perl 5中一樣。

  • mkdir

無引數的版本(隱式變數$_)在 Perl 6中沒有實現。

msg*

  • msgctl ID, CMD, ARG

  • msgget KEY, FLAGS

  • msgrcv ID, VAR, SIZE, TYPE, FLAGS

  • msgsnd ID, MSG, FLAGS

在 Perl 6不在內建支援,可能會出現在某些擴充套件模組中。

my

  • my VARLIST

  • my TYPE VARLIST

  • my VARLIST: ATTRS

  • my TYPE VARLIST: ATTRS

和 Perl 5中一樣。

next

  • next LABEL

  • next EXPR

  • next

Perl 6中也是一樣。

no

  • no MODULE VERSION

  • no MODULE LIST

  • no MODULE

  • no VERSION

在 Perl 6中,它是類似於strict一樣的編譯指示,但是作用物件不是模組,並不清楚它是否有版本功能,因為目前有些東西有爭議,我覺得沒有。

oct

  • oct

被副詞格式:8取代,比如::8("100") 返回 64。

open

  • open FILEHANDLE, EXPR

  • open FILEHANDLE, MODE, EXPR

  • open FILEHANDLE, MODE, EXPR, LIST

  • open FILEHANDLE, MODE, REFERENCE

  • open FILEHANDLE

相對於 Perl 5最明顯的改變就是檔案模式的語法,以只讀方式開啟一個檔案, 你需要使用open("file", :r);,以只寫、讀寫以及追加的方式開啟需要分別使用:w:rw以及:a,另外還有一些關於編碼以及如何處理換行的選項,具體參見open

opendir

  • opendir DIRHANDLE, EXPR

在 Perl 6裡面不是一個內建的函式,你需要使用IO::Path類:

my $dir = IO::Path.new("directory");

my $dir = "directory".IO; # 跟上面的效果一樣,更直接

ord

  • ord EXPR

和 Perl 5中一樣,也可以作為方法使用:"howdy!".ord; # 輸出 104

our

  • our VARLIST

  • our TYPE VARLIST

  • our VARLIST : ATTRS

  • our TYPE VARLIST : ATTRS

在 Perl 6中同樣可以使用。

pack

  • pack TEMPLATE, LIST

在 Perl 6中依然可用,模板的選項相對 Perl 5現在更加的嚴格,當前的文件可以參見unpack

package

  • package NAMESPACE

  • package NAMESPACE VERSION

  • package NAMESPACE BLOCK

  • package NAMESPACE VERSION BLOCK

S10 表明package在 Perl 6中是可用的,但是隻適用於程式碼塊,也就是:package Foo { ... }表示後面的程式碼塊是屬於 package Foo 的,當使用package Foo;宣告格式時有一種特殊情況,當它作為檔案的第一條語句時表明檔案中剩餘的程式碼都是 Perl 5的程式碼,但是它的有效性目前尚不清楚。實際上,因為模組和類的宣告需要不同的關鍵字(比如class),你不大可能會在 Perl 6中直接使用package

__PACKAGE__

  • __PACKAGE__

$?PACKAGE取代。

pipe

  • pipe READHANDLE, WRITEHANDLE

可能會被IO::Pipe類中的某些東西取代,但是現在並沒有明確的文件說明。

pop

  • pop ARRAY

在 Perl 6中同樣工作,也可以作為方法使用,即:my $x = pop @a;my $x = @a.pop; 是等價的。

pos

  • pos SCALAR

在 Perl 6中不可用,和它最具等價功能的是:c副詞,如果$/為真,它預設的值是$/.to,否則是0。更多的資訊在Continue可以找到。

print

  • print FILEHANDLE LIST

  • print FILEHANDLE

  • print LIST

  • print

print在 Perl 6中可以作為一個函式使用,預設輸出到標準輸出。作為函式使用print並且使用檔案控制程式碼替代標準輸出,你需要在檔案控制程式碼後加一個冒號,即:print $fh:"Howdy!",使用冒號作為“呼叫者標記”的用法討論在這裡可以找到,另外你也可以使用方法呼叫:$fh.print("Howdy!")

printf

  • printf FILEHANDLE

  • print FORMAT, LIST

  • printf

在 Perl 6中依然工作,對於格式,參見sprintf的文件。

prototype

  • prototype FUNCTION

在 Perl 6中不可用,功能最接近的是.signature,例如:say &sprintf.signature,結果是(Cool $format, *@args)

push

  • push ARRAY, LIST

在 Perl 6 中依然可以使用,而且可以作為方法使用:@a.push("foo"),注意,flattening 的行為和 Perl 5中不同:@b.push: @a將會把@a作為單個元素壓入到@b中,你還可以參考append method

qutoing

  • q/STRING/

  • qq/STRING/

  • qw/STRING/

  • qx/STRING/

這些用法過渡到 Perl 6 的一些建議:

q/.../  # 依然等價與使用單引號
qq/.../ # 依然等價與使用雙引號
qw/.../ # 更多的類似與 Perl 6中的C<< <...> >>

qutoing介紹了一些新增加的引號構造和他們的等價用法。

  • qr/STRING/

rx/.../取代。

  • quotemate EXPR

沒有直接的等價用法,換句話說,沒有直接返回字串中所有ASCII非單詞轉義字元的操作。然而,在 regexes 中使用$foo會被視為字串字面量,使用<$foo>會將$foo的內容作為正則程式碼直接內插到表示式中,注意尖括號和它在正規表示式外部的行為有點不同。要了解更多請參考這裡

rand

  • rand EXPR

rand和 Perl 5中一樣能工作,但是你可以不再給它提供引數了。把它作為一個方法使用就會是這樣的效果,即 Perl 5中的rand(100)等價於 Perl 6中的100.rand。另外,你還可以通過(^100).pick獲取一個隨機的整數,想了解這麼做的理由,可以參考 ^操作符 以及 pick

read

  • read FILEHANDLE, SCALAR, LENGTH, OFFSET

read函式現在在 Perl 6 中的IO::Handle以及IO::Socket中,它從關聯的控制程式碼或者套接字讀取指定數量的位元組(而不是字元),關於 Perl 5中的偏移目前的文件中還沒說明。

readdir

  • readdir DIRHANDLE

不再是內建函式。遍歷一個目錄的內容,請參考dir

readline

  • readline

在 Perl 6 中不再可用,某種程度上你最可能想使用.lines方法,想了解讀取檔案的更詳細的資訊,參閱io

readlink

  • readlink EXPR

看起來從 Perl 6 中移除了。

readpipe

  • readpipe EXPR

  • readpipe

看起來在 Perl 6 中並不可用,但是qx//的功能豐富,所以它可能在某些類中不明顯的使用。

recv

  • recv SOCKET, SCALAR, LENGTH, FLAGS

出現在IO::Socket類中,但現在沒有明確的文件化。

redo

  • redo LABEL

  • redo EXPR

  • redo

在 Perl 6 中沒有發生變化。

ref

  • ref EXPR

被移除,例如 S29中有“如果你真的想得到型別名字,你可以使用$var.WHAT.perl,如果你真的想使用 P5 的 ref 機制,使用Perl5::p5ref”,只不過目前Perl5::p5ref並不存在。

rename

  • rename OLDNAME, NEWNAME

在 Perl 6中依然可用。

requires

  • require VERSION

看起來require在 Perl 6的模組中可用,不過不清楚能否和版本號一起工作。

reset

  • reset EXPR

沒有證據顯示在 Perl 6中有這個函式,實際上, S29 中有它是否有良好的應用場景的疑問,我猜它已經被移除了。

return

  • return EXPR

雖然沒有明確的文件化,但是在 Perl 6中可用。

reverse

  • reverse LIST

在 Perl 6中,你只可以使用reverse(@a)或者@a.reverse反轉一個列表,要反轉一個字串,請使用.flip方法。

rewinddir

  • rewinddir DIRHANDLE

[需要更多研究]目前沒有一個明顯的直接等價的函式,可能在IO::Path的一些方法會提供類似的功能,但是目前不清楚是什麼樣子。

rindex

  • rindex STR, SUBSTR, POSITION

和 Perl 5中一樣能工作,還可以作為方法使用,比如:$x = "babaganush"; say $x.rindex("a"); say $x.rindex("a", 3); # 輸出 5 3

rmdir

  • rmdir FILENAME

和 Perl 5中一樣能工作,還可以作為方法使用。rmdir "Foo";"Foo".IO.rmdir是等價的。

s///

  • s///

在 Perl 6中,正規表示式的語法有一些不同,但是置換操作是存在的。如果你想重寫一些 Perl 5的程式碼,最重要的區別就是=~被智慧匹配操作符~~取代,同樣的,!~!~~取代。正則操作的選項都變成了副詞並且複雜度增加,詳見Adverbs page

say

  • say FILEHANDLE

  • say LIST

  • say

say可以作為一個函式使用,預設輸出到標準輸出。使用檔案控制程式碼替代標準輸出,需要在檔案控制程式碼後加一個冒號,也就是say $fh:"Howdy!"。冒號是作為“呼叫者標記”來使用的,關於它的討論見https://design.perl6.org/S03.html#line_4019。你也可以使用一個方法呼叫$fh.say("Howdy!")

scalar

  • scalar EXPR

顯然,移除了。

seek

  • seek FILEHANDLE, POSITION, WHENCE

沒有被文件記錄,不過它列在IO::Handle類下。

seekdir

  • seekdir DIRHANDLE, POS

目前沒有文件化,但是將會在關於IO的類中實現,比如IO::Path

select

  • select FILEHANDLE

“[S]elect 作為一個全域性的概念已經沒了”,當我問到select時,我被告知$*OUT以及類似的變數在動態作用域內是可重寫的,還有模組IO::Capture::Simple也可以用
來做和select功能相同的事情。

sem*

  • semctl ID, SEMNUM, CMD, ARG

  • semget KEY, NSEMS, FLAGS

  • semop KEY, OPSTRING

從核心中移處了,也許會在其它模組中找到。

send

  • send SOCKET, MSG, FLAGS, TO

可以在IO::Socket類中找到。

setpgrp

  • setpgrp PID, PGRP

不在屬於核心模組,可能會在POSIX模組中找到。

setpriority

  • setpriority WHICH, WHO, PRIORITY

不在屬於核心模組,可能會在POSIX模組中找到。

setsocket

  • setsocket SOCKET, LEVEL, OPTNAME, OPTVAL

沒有文件化,但是可能隱藏在IO相關的模組中。

shift

  • shift ARRAY

  • shift EXPR

  • shift

即可以作為函式使用,又可以作為方法使用,shift @a@a.shift 是等價的。

shm*

  • shmctl ID, CMD, ARG

  • shmget KEY, SIZE, FLAGS

  • shmread ID, VAR, POS, SIZE

  • shmwrite ID, STRING, POS, SIZE

從核心中移處了,也許會在其它模組中找到。

shutdown

  • shutdown SOCKET, HOW

沒有文件化,但看起來被移到了IO::Socket模組下。

sin

  • sin EXPR

即可以作為函式使用,又可以作為方法使用,sin(2)2.sin 是等價的。

sleep

  • sleep EXPR

和 Perl 5 中一樣可以工作,在寫本文件的時候,可以作為一個方法,但已經被廢棄並在將來的移除掉。

sockets

  • socket SOCKET, DOMAIN, TYPE, PROTOCOL

  • socketpair SOCKET1, SOCKET2, DIMAIN, TYPE, PROTOCOL

沒有文件化,但可能在IO::Socket類中。

sort

  • sort SUBNAME LIST

sort在 Perl 6中依然存在,不過有一些不同。$a$b不再是特殊變數(見5to6-perlvar),還有比較例程不在返回正數,負數,或者 0,而是Order::IncreaseOrder::Decrease以及Order::Same物件,詳見sortsort也可以作為一個方法使用,換句話說,sort(@a)等價於@a.sort

splice

  • splice ARRAY, OFFSET, LENGTH

  • splice ARRAY, OFFSET

  • splice ARRAY

  • splice EXPR, OFFSET, LENGTH, LIST

  • splice EXPR, OFFSET, LENGTH

  • splice EXPR, OFFSET

  • splice EXPR

在 Perl 6中可用,也可以作為一個方法使用,splice(@foo, 2, 3, <M N O P>);等價於@foo.splice(2, 3, <M N O P);

split

  • split /PATTERN/, EXPR, LIMIT

  • split /PATTERN/, EXPR

  • split /PATTERN/

跟 Perl 5中大致相同。不過,有一些例外,要達到使用空字串的特殊行為,你必須真正的使用空的字串 – 即//的特殊情況不再視為空的字串。如果你向split傳遞了一個正規表示式,它會使用這個正規表示式,同樣字面量會作為字面量對待。如果你像結果中包含分隔的字元,你需要指定命名引數:all,像這樣:split(`;`, "a;b;c", :all); # a ; b ; c。分隔出的空的塊不會像 Perl 5那樣被移除,需要這個功能請查閱combsplit的詳細說明在here。現在,split自然也可以作為方法使用:"a;b;c".split(`;`)

  • split

像上面描述的那樣,零引數版本比如配合明確的空字串呼叫,比如$_ = "a;b;c"; .split("").say(); # .split.say不正確

sprintf

  • sprintf FORMAT, LIST

像 Perl 5一樣可以工作,格式化字元現在支援這些:

%    %字面量
c    給定程式碼點代表的字元
s    字串
d    有符號整數,十進位制
u    無符號整數,十進位制
o    無符號整數,八進位制
x    無符號整數,十六進位制
e    浮點數,科學計演算法表示
f    浮點數,固定精度表示
g    浮點數,使用%e或者%f表示
X    類似x,但是使用大寫字母
E    類似e,但是使用大寫E
G    類似g,但是使用大寫E(如果適用)

相容以下字元:

i    %d的同義詞
D    %ld的同義詞
U    %lu的同義詞
O    %lo的同義詞
F    %f的同義詞

Perl 5(非)相容:

n    產生一個執行異常
p    產生一個執行異常

以下用來修飾整數,他們不需要運算元,語義並不是固定的:

h    把整數理解為本地“short”     型別(通常是int16)
l    把整數理解為本地“long”      型別(通常是int32或者int64)
ll   把整數理解為本地“long long” 型別(通常是int64)
L    把整數理解為本地“long long” 型別(通常是int64)
q    把整數理解為本地“quads”     型別(通常是int64或者更大)

sqrt

  • sqrt EXPR

可以作為方法和函式使用,sqrt(4)以及4.sqrt()是等價的。

srand

  • srand EXPR

在 Perl 6中可用。

stat

  • stat EXPR

  • stat DIRHANDLE

  • stat

好像在IO下實現了,但是目前還不是很明確。

state

  • state VARLIST

  • state TYPE VARLIST

  • state VARLIST : ATTRS

  • state TYPE VARLIST : ATTRS

在 Perl 6中可用,見state

study

  • study SCALAR

  • study

study已經不再可用了。

sub

  • sub NAME BLOCK

  • sub NAME(PROTO) BLOCK

  • sub NAME : ATTRS BLOCK

  • sub NAME(PROTO) : ATTRS BLOCK

毫無意外的,我們依然可以使用例程。你的例程還擁有一個簽名,這允許你指定引數,不過,在缺少簽名的情況下(並且只在缺少簽名的情況下),@_仍然包含當前傳遞給函式的引數。所以,從理論上講,如果從 Perl 5移植到 Perl 6你不用改變函式的樣子(不過你應該考慮使用簽名這一選擇)。對於所有的資訊詳見functions

__SUB__

  • __SUB__

&?ROUTINE取代。

substr

  • substr EXPR, OFFSET, LENGTH, REPLACEMENT

  • substr EXPR, OFFSET, LENGTH

  • substr EXPR, OFFSET

即可以作為函式使用,又可以作為方法使用。substr("hola!", 1, 3)"hola!".substr(1, 3)都返回“ola”。

symlink

  • symlink OLDFILE, NEWFILE

現在屬於IO::Path的一部分。現在和 Perl 5中唯一不同是引數的順序變了,現在是link($original, $linked_file)

syscall

  • syscall NUMBER, LIST

Perl 6中不再內建此函式。很可能在某個模組當中,不過現在不明確。

sys*

  • sysopen FILEHANDLE, FILENAME, MODE

  • sysopen FILEHANDLE, FILENAME, MODE, PERMS

  • sysread FILEHANDLE, SCALAR, LENGTH, OFFSET

  • sysread FILEHANDLE, SCALAR, LENGTH

  • sysseek FILEHANDLE, POSITION, WHENCE

和非系統版本的函式一樣,有可能在IO類中。

system

  • system LIST

  • system PROGRAM LIST

要實現相同的功能,你可能想使用(run)和(shell routine)。

syswrite

  • syswrite FILEHANDLE, SCALAR, LENGTH, OFFSET

  • syswrite FILEHANDLE, SCALAR, LENGTH

  • syswrite FILEHANDLE, SCALAR

sysopen以及其他函式一樣,被移動到了IO模組。

tell

  • tell FILEHANDLE

IO::Handle裡,不過現在除了提到並沒有文件化。

telldir

  • telldir DIRHANDLE

可能在IO::Path裡,不過沒有文件化。

tie

  • tie VARIABLE, CLASSNAME, LIST

  • tie VARIABLE

[需要更多探究] S29表明變數型別已經被容器型別替代,不幸運的是,這意味著實際上沒有此函式描述。

time

  • time

“返回當前時間的Int型別的表示”,雖然目前文件中沒有說明它如何表示當前時間,不過看起來依然是像 Perl 5從某個特定時間開始的秒數。

times

  • times

不再可用。

tr///

  • tr///

和 Perl 5的工作模式很像,唯一的警告就是範圍指定時不同了。你必須使用“a..z“替代“a-z”,換句話說使用 Perl的範圍操作符。在 Perl 6中,tr///有一個文件完善的方法版本,叫做.trans.trans接受一系列的對組:$x.trans([`a` .. `c`] => [`A` .. `C`], [`d` .. `q`] => [`D` .. `Q`], [`r` .. `z`] => [`R` .. `Z`]);。關於.trans的使用更詳細的描述可以在here找到。等價的y///已經被去掉了。

truncate

  • truncate FILEHANDLE, LENGTH

  • truncate EXPR, LENGTH

很大可能在IO模組中,不過沒有文件化。

uc

  • uc EXPR

即可作為函式使用又可作為方法使用,uc("ha")"ha".uc都返回”HA”。

ucfirst

  • ucfirst EXPR

  • ucfirst

Perl 6已經廢棄了ucfirst,現在首字元大寫函式tc可以完成你想做的事情。

umask

  • umask EXPR

現在是IO的一個方法,IO.umask返回當前的umask

undef

  • undef EXPR

Perl 6中已經沒有undef了,你不可以反定義一個函式,功能最接近的一個值是Nil,但你可能不會喜歡使用它。在 Perl 6中,如果你使用類似(undef, $file, $line) = caller;的語句,你將會直接得到檔名字以及行數而不是忽略caller的第一個結果(??If you were using something like (undef, $file, $line) = caller;, you would just get the filename and line number directly in Perl 6 instead of discarding the first result of caller.)。caller已經被callframe取代了,所以等價的語句即是($file, $line) = callframe.annotations<file line>;

unlink

  • unlink LIST

依然可用,可以作為方法使用:"filename".IO.unlink

  • unlink

零引數(隱式引數$_)版本在 Perl 6中不可用。

unpack

  • unpack TEMPLATE, EXPR

  • unpack TEMPLATE

在 Perl 6中可用,模板設定部分比起 Perl 5中限制更多了,目前的文件可以在這裡找到。

unshift

  • unshift ARRAY, LIST

  • unshift EXPR, LIST

在 Perl 6中可用,可以作為方法使用。unshift(@a, "blah")等價於@a.unshift("blah")

untie

  • untie VARIABLE

[需要更多探究] 根據S29,方法中對變數用來繫結的操作貌似被容器型別取代了,這變的不是很明確所以我寫下了tie這一小節。

use

  • use Module VERSION LIST

  • use Module VERSION

  • use Module LIST

  • use Module

  • use VERSION

在 Perl 5中,指令碼的執行可能需要一個最低的 Perl 執行檔案版本。在 Perl 6中,可以指定被不同 Perl 6可執行檔案遵循的規範的版本(比如6.c)。

utime

  • utime LIST

根據S32來看已經移除了,並且建議你參考Path.times。不幸運的是,並沒有Path.times這個方法,可能以後IO::Path中會有等價的方法,不過現在確實沒有。

values

  • values HASH

  • values ARRAY

  • values EXPR

在 Perl 6中可用,也可以作為方法使用,values %hash等價於%hash.values

vec

  • vec EXPR, OFFSET, BITS

S29說,應該使用宣告bituint2uint4等等的buffer/array來取代vec,雖然並不明確,不過確實開始實現這功能了。

wait

  • wait

[需要更多探究] 目前尚不明確被誰取代了,在Supply中有一個方法waitChannel以及Promise中有一個方法await,對這些函式跟 Perl 5中的wait關聯並不明確。

waitpid

  • waitpid PID, FLAGS

wait一樣,這個函式的安排並不明確。

wantarray

  • wantarray

因為這些原因, Perl 6中m沒有wantarray
這裡有幾種簡單的方式填補許多需要用到wantarray的地方。
首先,因為 Perl 6並不需要特殊的引用語法把List或者Array包裝成Scalar,簡單的返回一個列表只需要:

sub listofstuff {
    return 1, 2, 3;
}
my $a = listofstuff();
print $a;                       # 列印 "123"
print join(`<`, listofstuff()); # 列印 "1<2<3"

一個普遍的應用就是提供一個行或者元素的陣列,簡單的列印陣列輸出一個優美的字串。你可以混入一個.Str方法來達到這個目的:

sub prettylist(*@origlist) {
    @origlist but role {
        method Str { self.join("<")  }
    }
}
print prettylist(1, 2, 3);             # 列印 "1<2<3"
print join(">", prettylist(1, 2, 3));   # 列印 "1>2>3"

在上面的例子中,返回的列表可能是惰性的,.Str方法將不會被呼叫直到字串化,所以並不會有額外的工作產生沒有請求到的東西。
另一種情況就是需要建立一個可以在空上下文使用,但是賦值時會拷貝的調整器(?? Another use case is to create methods which are mutators when called in void context but produce copies during assignment.)。通常情況下在 Perl 6中不要這樣做,因為你可以通過使用.=運算子快速的完成產生拷貝(copy-producing)的方法到調整器的轉換:

my $a = "foo
";
$a.ords.say;        # 列印 "(102, 111, 111, 10)"
$a.=chomp;
$a.ords.say;        # 列印 "(102, 111, 111)"

但是如果你想在兩種操作下使用同一個函式名稱,大多數情況下你可以混入一個在結果發現自己處於空上下文的時會自動呼叫的.sink方法來完成。然而,這有需要警告你,並不建議這麼做:

multi sub increment($b is rw) {
    ($b + 1) does role { method sink { $b++ }) }
}
multi sub increment($b) {
    ($b + 1)
}
my $a = 1;
increment($a);
say $a;                 # 列印 "2"
my $b = increment($a);
say $a, $b;             # 列印 "23"
# 使用者將會意識到這之後他們不應該意外sink一個儲存的值,儘管這需要一些功夫
sub identity($c is rw) { $c };
$a = 1;
$b = increment($a);
identity($b);
$a.say;                  # 列印 "2" #!!!!

warn

  • warn LIST

warn丟擲一個異常。簡單的將資訊列印到$*ERR中,你可以使用note函式。檢視更多的異常,請見Exceptions

write

  • write FILEHANDLE

  • write EXPR

  • write

格式化輸出以及移除了,所以函式在Perl 6中不再可用。

y///

  • y///

tr///的同義詞已經移除了,對於此功能請參考tr///

相關文章