Perl PHP'nin katsayısına benzer bir şey () var mı?

7 Cevap php

Ben perldoc ve O'Reilly kitaplar aracılığıyla bazı kazı yapmış ama bunu yapmak için herhangi bir yol bulmuş değil. I Readonly gibi bir şey kullanarak küme muyum?

UPDATE:

Ben Readonly karşı hiçbir şeyim yok. Ben sadece PHP sabiti () gibi bir şey yapmak mümkün istedim.

Perl sabit vardı Örnek if ():

use constant {
  FIELD_EXAMPLE_O => 345,
  FIELD_EXAMPLE_L => 25
};

my $var = 'EXAMPLE';
my $c = 'FIELD_' . $var . '_L';
my $value = constant($c);

# $value is 25

Okunabiir bunu yapmak için en iyi yolu ise, o zaman bunu kullanmak zorundadır.

7 Cevap

Ne Readonly nesi var?

Çok yavaş ise, Readonly:XS . But if you don't like Readonly , there's always the older constant ile tamamlayabilir.

use constant PI => 3.14159265;

Sadece hatırlıyorum

  1. Onlar subs gibi çalışır, bu yüzden iş olmadan sokmak yok.
  2. Tek bir deyimde birden sabitler oluşturmak istiyorsanız, bir karma başvuru geçmesi gerekir.

    use constant { PI => 3.14159265
                 , E  => 2.71828183
                 };
    


From Your Example:

Sizin örnekte bakılırsa, bir salt okunur hash aynı şeyi yapamadık hiçbir neden yok.

Readonly::Hash my %field_example => { L => 25, O => 345 };

Sonra sabit Arnavut kaldırımı isterdim hiçbir yerde kullanabilirsiniz:

print "The example is $field_example{$var}\n";

Ya da bunu bu şekilde yapabiliriz:

Readonly::Hash my %field 
    => { example => { L => 25,     O => 345 }
       , name    => { L => 'Lion', O => 'ocelot' }
       };

Ve bu şekilde arayın:

$field{$var}{L};

Eğer bir dil, başka bir şekilde yapmak için daha iyi bir destek var ne yapmak çalışmıyorum yaklaşık kilometre bir sürü alabilirsiniz.

Cognate to PHP constant

Eğer bu şekilde yapmak istiyorsanız Ancak, o zaman benim önerim aşağıdaki alt aynı yapmanın bir yoludur (ve kaçınan bir eval) olduğunu:

sub read_constant { 
    use Symbol qw<qualify_to_ref>;
    my $name = join( '', @_ ); # no need to concatenate before passing
    my $constant;
    # use the first that works: calling package and then "" (main)
    for my $pkg ( scalar( caller ), "" ) { 
        # get symbol reference
        my $symb_ref = qualify_to_ref( $name, $pkg );
        # get the code slot
        $constant    = *{$symb_ref}{CODE};
        last if $constant;
    }
    return unless $constant;
    # call the sub named
    return $constant->();
}

Böyle derim:

$value = read_constant( 'FIELD_', $var, 'L' );

Son bir şey, hatta sadece bir bütün kap dize olduğundan emin olmak için önünde bir testi koymak olmasıdır:

Carp::croak "Invalid constant name '$name'" if $name =~ /[^\p{UpperCase}_]/;

İşte aradığınız constant fonksiyonu bulunuyor:

sub constant
{
  no strict 'refs';
  shift->();                    # Call the supplied function by name
} # end constant

Sadece söz kodu eklemek ve sizin için ne sordu yapacağız. constant pragma tarafından oluşturulan sabitler sadece altyordamlar vardır ve bu isimde bir alt yordam çağırmak kolaydır.

Burada yine farklı bir paketten diyorlar bile çalışır bir daha gelişmiş biri:

sub constant
{
  my $constant = shift;
  $constant = caller() . "::$constant" unless $constant =~ /::/;
  no strict 'refs';
  $constant->();                # Call function by name
} # end constant

Sen pragma "sürekli kullanabilirsiniz" kullanabilirsiniz, ancak bu şekilde tanımlanan sabitler, normal değişkenler gibi referans değildir. Onlar olsa, size sabitler olan performans artışı olsun. Eğer bir sabit kullanarak derleme zamanı iyileştirmeleri değil arıyorsanız, en iyi yaklaşım, kod yazma ve tahsis edilmemelidir değişkenlere atama zaman değil, sadece disiplin kullanarak muhtemelen. :)

Deftere örnek kod baktığımızda, ben seni Hash::Util::lock_hash ve arkadaşlar arıyor olabilir anlamda olsun:

#!/usr/bin/perl

use strict;
use warnings;

use Hash::Util qw(lock_hash);

my %constant = (
    FIELD_EXAMPLE_O => 345,
    FIELD_EXAMPLE_L => 25,
);

lock_hash %constant;

my $var = 'EXAMPLE';

print $constant{"FIELD_${var}_L"}, "\n";

Çıktı:

C:\Temp> xuk
25

Bu formatı kullanın:

use constant DFLT_MIN_LENGTH_PWD => 6;