Mojo::Util

Mojo::Util为Mojo框架提供了便携实用的工具函数。

b64_decode

my $bytes = b64_decode $b64;

## ab仵士杰
$bytes = b64_decode("YWLku7Xlo6vmnbA=");

提供Base64解码功能。

b64_encode

my $b64 = b64_encode $bytes;
my $b64 = b64_encode $bytes, "\n";

## YWLku7Xlo6vmnbA=
$bytes = b64_encode("ab仵士杰");

提供Base64编码功能,默认分隔符为换行符。

camelize

my $camelcase = camelize $snakecase;

把 snake_case 格式的字符串转换为 CamelCase 格式并用 :: 替换-

# "FooBar"
camelize 'foo_bar';

# "FooBar::Baz"
camelize 'foo_bar-baz';

# "FooBar::Baz"
camelize 'FooBar::Baz';

decamelize

my $snakecase = decamelize $camelcase;

此方法是 camelize 的逆方法,它把CamelCase格式的字符串转换为snake_case格式,并用-替换::

# "foo_bar"
decamelize 'FooBar';

# "foo_bar-baz"
decamelize 'FooBar::Baz';

# "foo_bar-baz"
decamelize 'foo_bar-baz';

class_to_file

my $file = class_to_file 'Foo::Bar';

将类名转换为文件,实现代码如下:

sub class_to_file {
  my $class = shift;
  $class =~ s/::|'//g;
  $class =~ s/([A-Z])([A-Z]*)/$1 . lc $2/ge;
  return decamelize($class);
}

示例如下:

# "foo_bar"
class_to_file 'Foo::Bar';

# "foobar"
class_to_file 'FOO::Bar';

# "foo_bar"
class_to_file 'FooBar';

# "foobar"
class_to_file 'FOOBar';

class_to_path

my $path = class_to_path 'Foo::Bar';

把类名转换为路径,配合%INC完成类名到文件路径的转换。

# "Foo/Bar.pm"
class_to_path 'Foo::Bar';

# "FooBar.pm"
class_to_path 'FooBar';

encode

my $bytes = encode 'UTF-8', $chars;

字符编码,与Encode 中的 encode 函数工作原理相同。

decode

my $chars = decode 'UTF-8', $bytes;

对字符串进行解码,如果解码失败则返回undef。与Encode包中的decode函数工作原理相同。

deprecated

deprecated 'foo is DEPRECATED in favor of bar';

警告调用者这是一个已弃用的功能。您还可以设置MOJO_FATAL_DEPRECATIONS环境变量,这样调用这个函数就不仅仅是警告,而是会执行出错,并退出程序。

dumper

my $perl = dumper {some => 'data'};

使用 Data::Dumper 转储Perl的数据结构。

extract_usage

my $usage = extract_usage;
my $usage = extract_usage '/home/sri/foo.pod';

从包含POD的文件中提取SYNOPSIS段的信息,默认是从调用这个方法的文件中提取。

# "Usage: APPLICATION test [OPTIONS]\n"
extract_usage;

=head1 SYNOPSIS

  Usage: APPLICATION test [OPTIONS]

=cut

getopt

getopt
  'H|headers=s' => \my @headers,
  't|timeout=i' => \my $timeout,
  'v|verbose'   => \my $verbose;
getopt $array,
  'H|headers=s' => \my @headers,
  't|timeout=i' => \my $timeout,
  'v|verbose'   => \my $verbose;
getopt $array, ['pass_through'],
  'H|headers=s' => \my @headers,
  't|timeout=i' => \my $timeout,
  'v|verbose'   => \my $verbose;

使用Getopt :: Long从数组引用中提取选项,但不更改其全局配置,默认为使用@ARGV。配置选项no_auto_abbrev,no_ignore_case默认情况下被启用。

# Extract "charset" option
getopt ['--charset', 'UTF-8'], 'charset=s' => \my $charset;
say $charset;

hmac_sha1_sum

my $checksum = hmac_sha1_sum $bytes, 'passw0rd';

为字节生成HMAC-SHA1校验和。

# "11cedfd5ec11adc0ec234466d8a0f2a83736aa68"
hmac_sha1_sum 'foo', 'passw0rd';

html_attr_unescape

my $str = html_attr_unescape $escaped;

与 html_unescape 方法相同,但这里的方法 html_attr_unescape 是专门用于处理html属性的。

# "foo=bar&ltest=baz"
html_attr_unescape 'foo=bar&ltest=baz';

# "foo=bar<est=baz"
html_attr_unescape 'foo=bar<est=baz';

html_unescape

my $str = html_unescape $escaped;

翻译字符串中的所有HTML实体。

# "<div>"
html_unescape '<div>';

md5_bytes

my $checksum = md5_bytes $bytes;

为字节数据生成二进制的MD5校验和。

md5_sum

my $checksum = md5_sum $bytes;

为字节数据生成十六进制编码后字符串形式的MD5检验和。

# "acbd18db4cc2f85cedef654fccc4a4d8"
md5_sum 'foo';

monkey_patch

monkey_patch $package, foo => sub {...};
monkey_patch $package, foo => sub {...}, bar => sub {...};

功能包装器,可以动态的为一个“包”添加新函数。是一个打补丁的工具。

monkey_patch 'MyApp',
  one   => sub { say 'One!' },
  two   => sub { say 'Two!' },
  three => sub { say 'Three!' };

punycode_decode

my $str = punycode_decode $punycode;

Punycode解码字符串,如RFC 3492所述

# "bücher"
punycode_decode 'bcher-kva';

punycode_encode

my $punycode = punycode_encode $str;

Punycode编码字符串,如RFC 3492所述

# "bcher-kva"
punycode_encode 'bücher';

quote

my $quoted = quote $str;

包装字符串,并对字符串中的特殊字符进行转义。

unquote

my $str = unquote $quoted;

quote 函数的逆操作。

secure_compare

my $bool = secure_compare $str1, $str2;

恒定时间比较算法,防止定时攻击。

sha1_bytes

my $checksum = sha1_bytes $bytes;

为字节数据生成二进制SHA1校验和。

sha1_sum

my $checksum = sha1_sum $bytes;

为字节数据生成十六进制编码的字符串形式的SHA1校验和。

# "0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33"
sha1_sum 'foo';

slugify

my $slug = slugify $string;
my $slug = slugify $string, $bool;

返回从输入字符串生成的URL段。删除非URL单词的字符,字符串被修剪和缩小,空格字符被短划线替换。默认情况下,非ASCII字符被标准化为ASCII字符替换或删除,但如果作为第二个参数传递真值,则所有字符都将根据unicode语义被允许在结果中。

# "joel-is-a-slug"
slugify 'Joel is a slug';

# "this-is-my-resume"
slugify 'This is: my - résumé! ☃ ';

# "this-is-my-résumé"
slugify 'This is: my - résumé! ☃ ', 1;

split_cookie_header

my $tree = split_cookie_header 'a=b; expires=Thu, 07 Aug 2008 07:07:59 GMT';

与split_header基本相同,唯一不同的是使用RFC 6265的中的规定处理expires的值。

split_header

my $tree = split_header 'foo="bar baz"; test=123, yada';

将HTTP标头值分解为键/值对,每个逗号分隔的部分都会被转换为数组引用,如果key没有value相对应,则会给其赋值为undef。

# "one"
split_header('one; two="three four", five=six')->[0][0];

# "two"
split_header('one; two="three four", five=six')->[0][2];

# "three four"
split_header('one; two="three four", five=six')->[0][3];

# "five"
split_header('one; two="three four", five=six')->[1][0];

# "six"
split_header('one; two="three four", five=six')->[1][1];

steady_time(不理解)

my $time = steady_time;

从过去任意一个固定点开始的高分辨率时间,如果通过Time :: HiRes可以获得单调时钟,则时间跳转有弹性。

tablify

my $table = tablify [['foo', 'bar'], ['baz', 'yada']];

用于文本形式表格的行生成器。

# "foo   bar\nyada  yada\nbaz   yada\n"
tablify [['foo', 'bar'], ['yada', 'yada'], ['baz', 'yada']];

term_escape

my $escaped = term_escape $str;

对除换行符(\n)之外的所有POSIX控制字符进行转义。

trim

my $trimmed = trim $str;

去除字符串两端的空格字符。

# "foo bar"
trim '  foo bar  ';

unindent

my $unindented = unindent $str;

对多行文本进行修剪,对每行文本起始位置删除固定长度的空白。

# "foo\nbar\nbaz\n"
unindent "  foo\n  bar\n  baz\n";

url_escape

my $escaped = url_escape $str;
my $escaped = url_escape $str, '^A-Za-z0-9\-._~';

根据要求用百分号编码字符串中所有不安全的字符,如RFC 3986中所述。所有使用的默认模式为:^A-Za-z0-9\-._~

# "foo%3Bbar"
url_escape 'foo;bar';

url_unescape

my $str = url_unescape $escaped;

此函数为 url_escape 的逆操作。

# "foo;bar"
url_unescape 'foo%3Bbar';

xml_escape

my $escaped = xml_escape $str;

过滤xml格式的字符串中所有不安全的字符 ,包括&, <, >, "',如果字符以Mojo::ByteStream对象的形式出现,则不进行过滤。

# "<div>"
xml_escape '<div>';

# "<div>"
use [Mojo::ByteStream](https://metacpan.org/pod/Mojo::ByteStream)  'b';
xml_escape b( '<div>');

xor_encode

my $encoded = xor_encode $str, $key;

用XOR算法编码具有可变长度的字符串。

_stash

这个方法没有导出,想要使用必须使用完全限定名。

  1. 这个方法在接收两个参数时,第一个参数被当成属性名$attrName,第二个参数作为对象$obj。返回对象对应属性的值$obj->{$attrName}。
  2. 这个方法在接收三个参数并且第三个参数不为引用的情意下,前两个参数的含义不变与(1)中相同,第三个参数会作为$key。对象对应属性值$obj->{$attrName}会被当成一个HASHREF类型的数据,返回其键名为$key的$value值。也就是返回$obj->{$attrName}->{$key}的值。
  3. 当参数多于三个或第三个参数为引用时,前两个参数的含义不变与(1)中相同。如果第三个参数为引用,则会被当成hashref类型;如果参数多于三个,则后面的参数必定为偶数个,并且把后面的参数放到一起作为一个hash处理。然后把这个hash或hashref中的内容合并到$obj->{$attrName}中,如果$obj->{$attrName}中已经存在了某些键,则会被新的值覆盖。最后返回$obj。

方法的实现代码如下:

sub _stash {
  my ($name, $object) = (shift, shift);

  # Hash
  return $object->{$name} ||= {} unless @_;

  # Get
  return $object->{$name}{$_[0]} unless @_ > 1 || ref $_[0];

  # Set
  my $values = ref $_[0] ? $_[0] : {@_};
  @{$object->{$name}}{keys %$values} = values %$values;

  return $object;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,423评论 6 491
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,147评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,019评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,443评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,535评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,798评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,941评论 3 407
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,704评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,152评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,494评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,629评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,295评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,901评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,742评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,978评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,333评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,499评论 2 348

推荐阅读更多精彩内容