Perl自定义后缀或自定义后缀运算符的语法

前端之家收集整理的这篇文章主要介绍了Perl自定义后缀或自定义后缀运算符的语法前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我想知道如何运行这样的操作

$T = 25 C;
@specs = (273.15 K,23 bar,2.0 mol/s);

并让他们编译.我不会挑剔他们的结果是什么,或者它是如何实现的.我的目标是让传统后缀单元注释的物理量表达式编译为这些单元的perl表达式.

我想我需要使用自定义解析技术,但我更喜欢使用任何现有功能或解析模块,而不仅仅是将regex过滤器应用于我的原始源.

Parse::Keyword似乎很有希望,但我看不出它是否可以解析后缀操作,并声称它已被弃用.

编辑:我想尽可能避免使用源过滤器,因为我不想为Perl的语法极端情况编写正则表达式(例如“25(J / K)”).

Perl在这里产生的错误告诉我:

perl -E "25 C"
Bareword found where operator expected at -e line 1,near "25 C"
(Missing operator before C?)

看起来我需要挂钩Perl在数字文字之后检测运算符的地方.

Devel::Declare可以添加后缀运算符吗?如果是这样,怎么样?

解决方法

你可以滥用重载来获得你想要的东西.

#!/usr/bin/perl

use strict;
use warnings;
use 5.010;

use Data::Dumper;
use MyUnits;

my $T = '25 C';

say Dumper $T;

my @specs = ('273.15 K','23 bar','2.0 mol/s');

say Dumper \@specs;

正如您将看到的,您可以使用“value”和“type”属性返回对象.

MyUnits.pm看起来像这样:

package MyUnits;

use strict;
use warnings;

use overload
  '""' => \&to_string;

my %_const_handlers = (
  q => \&string_parser,);

sub string_parser {
  my $c = eval { __PACKAGE__->new($_[0]) };
  return $_[1] if $@;
  return $c;
}

sub import {
  overload::constant %_const_handlers;
}

sub new {
  my $class = shift;

  # ->new(type => ...,value => ...)
  if (@_ == 4) {
    return bless { @_ },$class;
  }
  # ->new({ type => ...,value => ...)
  if (@_ == 1 and ref $_[0] eq 'HASH') {
    return bless $_[0],$class;
  }
  # -> new('999xxx')
  if (@_ == 1 and ! ref $_[0]) {
    my ($val,$type) = $_[0] =~ /(\d+\.?\d*)\s*(.+)/;
    return bless({
      value => $val,type => $type,});
  }
}

sub to_string {
  return "$_[0]->{value}$_[0]->{type}";
}

1;

您需要添加更多方法以使其能够执行有用的操作.

在大多数情况下,与源过滤器相比,重载并不比派对技巧少得多.它几乎肯定会使你的程序慢得多.

猜你在找的Perl相关文章