2015-06-15 3 views
3

В моем объекте Moose необходимо управлять атрибутом разрешения файла. Было бы неплохо принять, любой вариант, например:Ложное принуждение к октальному значению разрешения файла

my $obj = My::Obj->new(); # should assign default 0444 
my $obj = My::Obj->new(perm => '1666'); #as string 
my $obj = My::Obj->new(perm => 0555); #as octal 

также проверяет значение, когда он установлен на аксессору, как:

$obj->perm('0666'); 
#etc 

Так, в поисках чего-то

has 'perm' => (is => 'rw', isa => Perm, coerce => 1, default => sub { oct('0444') }); 

например хотите сохранить разрешение в виде числа (что можно использовать в файловых операциях).

, но не имеют ни малейшего представления о том, как создать Perm типа, какие

  • умирает на неправильные значения
  • принуждают от действительной строки в восьмеричное
  • принимает действительное восьмеричное значение

например пытался что-то вроде

subtype 'Perm', 
    as 'Str', #but i want store a number 
    where { $_ =~ /\A[01246]?[0-7]{3}\z/ }; #but i know the validation for strings only 

Но выше проверяет его как Str и я хочу сохранить значение octal, так что я потерял ..;? (

Может кто-нибудь помочь

EDIT

Продолжается борьба с этим.

package Some; 
use 5.018; 
use warnings; 
use namespace::sweep; 
use Moose; 
use Moose::Util::TypeConstraints; 

subtype 'Perm', as 'Int', where { $_ >= 0 and $_ <= 06777 }, message { 'octal perm out of range' }; 
subtype 'PermStr', as 'Str', where { $_ =~ /\A[01246]?[0-7]{3}\z/ }, message { 'bad string-perm' }; 
coerce 'Perm', from 'PermStr', via { oct("$_") }; 

has 'perm' => (is => 'rw', isa => 'Perm', coerce => 1, default => 0444,); 
no Moose::Util::TypeConstraints; 

package main; 
my($p,$q); 
$p = '0333' ; $q = Some->new(perm => $p); printf("dec:%d oct:%o\n", $q->perm, $q->perm); 
$p = '0383' ; $q = Some->new(perm => $p); printf("dec:%d oct:%o\n", $q->perm, $q->perm); 
$p = 0333 ; $q = Some->new(perm => $p); printf("dec:%d oct:%o\n", $q->perm, $q->perm); 
$p = 033333 ; $q = Some->new(perm => $p); printf("dec:%d oct:%o\n", $q->perm, $q->perm); 

вышеприведенные отпечатки:

dec:333 oct:515 
dec:383 oct:577 
dec:219 oct:333 
Attribute (perm) does not pass the type constraint because: octal perm out of range at .... 

E.g. Пермское вошел в восьмеричную работе (и обнаруживает вне диапазона), но из строки

  • не проверяет матча
  • и он не выполняет преобразование восьмеричного.
+1

'default => sub {oct ('0444')}' overkill. 'default => 0444' будет делать то же самое с меньшими накладными расходами. – cjm

ответ

2

попробовать что-то вроде этого:

subtype 'Perm', 
    as 'Int', 
    where { $_ >= 0 and $_ <= 06777 }; 

subtype 'PermStr', 
    as 'Str', 
    where { $_ =~ /\A[01246]?[0-7]{3}\z/ }; 

coerce 'Perm', 
    from 'PermStr', 
    via { oct($_) }; 

Не забудьте объявить свои атрибуты с coerce => 1.

Примечание: пункт where, который я дал для Perm, является менее ограничительным, чем тот, который вы указали для PermStr. Изменение его для запрета 03000 – 03777 и 05000 – 05777 - упражнение, оставленное читателю.

+0

Почему так легко понять необходимость двух разных типов (когда кто-то другой решает проблему)? Большое спасибо. – kobame

+0

Действительно ли это работает надежно? Определенные строки и целые числа не являются типами на основном уровне? –

+0

мог бы еще раз проверить мой вопрос?Где-то я делаю что-то неправильно. – kobame

 Смежные вопросы

  • Нет связанных вопросов^_^