LINUX.ORG.RU

расширить модуль перегрузив операторы

 


0

1

Всем привет! Есть модуль-прагма, в котором только одна процедура import. Прагме можно передать большие числа для вычислений, но в самом модуле bignum не используется.

Как расширить этот модуль? Дописать «use bignum;» не предлагайте)

Deleted

Ответ на: комментарий от Olegymous

Перегрузку операций для работы с большими числами (bigint).

Deleted
()
Ответ на: комментарий от Olegymous

Например, есть модуль-прагма, которая принимает три аргумента и суммирует их (в функции import).

Как подключая этот модуль

use module qw( x y z );
перегрузить операции (в модуле, в функции import) вычисления для больших чисел? Изменить сам модуль, дописав в него
use bignum
не хочется. Можно его расширить, переопределить, или сделать как-то еще?

Deleted
()
Ответ на: комментарий от arto

use base qw( bigint ).

это куда?

а для чего всё это надо?

практического смысла наверное нету. В качестве интереса, лисапедю модуль-прагму enum, с iota-идентификатором (как в Го). Так вот, в обычной ситуации, перечисляемым типам не нужны большие числа, но иногда, как в примере, нужны:

const (
    _           = iota
    KB ByteSize = 1 << (10 * iota)
    MB
    GB
    TB
    PB
    EB
    ZB
    YB
)

Как вариант решения - можно передавать в прагму опцию bignum

use enum 'use:bignum', qw(
    KB
    KB=1<<(10*iota) # redefine first value
    MB
    GB
);
Но хочется узнать как делается первое. Чтоб выбрать.

Deleted
()
Последнее исправление: Deleted (всего исправлений: 3)
Ответ на: комментарий от Deleted

можно взглянуть на модуль enum:

# perl -Mbigint -Menum="TosiPaljon=Math::BigInt->new(2128506)**10" -le 'print "Type: ", ref TosiPaljon, " value ", TosiPaljon'
Type: Math::BigInt value 1908748845499640629635849984724723887514051727967524072139826176
arto ★★
()
Ответ на: комментарий от Deleted

в функции import() вы получаете список строк. как их унтерпретировать — на ваше усмотрение. например, если есть аргумент «use:bigint» приводите их к Math::BigInt, например.

дальше:

# perl -le '$iota=0; foreach (@ARGV) { eval( m#=# ? s#(\w+)=(.+)#\$$1=$2#r =~ s#iota#$iota#gre : s#(\w+)#\$$1=$iota#r); $iota++ } print $KB; print $MB' KB "KB=1<<(10*iota)" "MB" "GB"
1024
2
arto ★★
()
Ответ на: комментарий от arto

в функции import() вы получаете список строк. как их унтерпретировать — на ваше усмотрение. например, если есть аргумент «use:bigint» приводите их к Math::BigInt, например.

Это третий вариант, о котором подумал. Второй - включить в модуле прагму bignum, независимо от того, нужно или нет в ряду случаев. А хотелось бы первый вариант как-то решить. Думаю он «правильнее». Расширить модуль, сделать словно в нём «use bigint», но не меняя сорцы.

Deleted
()
Ответ на: комментарий от beastie

Пример взял из википедии. Не знал что он два раза дергается. Это не просто идентификатор индекса?

P.S. Логические выражения с iota возможны?

Deleted
()
Последнее исправление: Deleted (всего исправлений: 1)
Ответ на: комментарий от beastie

bitmask :D


use enum qw(
    $_ = iota % 2 ? (1 << iota/2) : -(1 << (iota-1)/2)

    MINIMIZED         #  1
    UNMINIMIZED       # -1

    MINIMIZING        #  2
    UNMINIMIZING      # -2

    MAXIMIZED         #  4
    UNMAXIMIZED       # -4

    MAXIMIZING        #  8
    UNMAXIMIZING      # -8
);

но можно придумать что-нибудь еще, мне пока не приходит в голову :)

Deleted
()
Последнее исправление: Deleted (всего исправлений: 1)
Ответ на: комментарий от beastie

смог бы придумать случай, или метод, в котором бы вычисления по условию пригодились?)) а то чёт, ты убедил меня что это не нужно.

Deleted
()
Ответ на: комментарий от Deleted

Если это можно вывести алгебраически, см. выше. Но проще, конечно не парить себе мозги и разбить на блоки.

Если это заумные и разные константы — их проще вбить руками, чем усложнять всё дело без надобности.

Если и это лень, то всегда есть go generate и куча других способов. ;)

Т.ч. честно признаться, не вижу в этом особой надобности и профита. В конце концов, это просто хитрый enum.

beastie ★★★★★
()
Ответ на: комментарий от Deleted
if ($arg == "use:bignum") {
  require "bignum";
}

всё равно не понял идею

Расширить модуль, сделать словно в нём «use bigint», но не меняя сорцы

arto ★★
()
Ответ на: комментарий от Olegymous

пилять. git, как так? похерил данные...

Deleted
()
Ответ на: назад в будущее) от Deleted

Так подойдёт? :)

diff --git a/example.pl b/example.pl
index fe4d464..81a44f5 100644
--- a/example.pl
+++ b/example.pl
@@ -1,7 +1,6 @@
 use strict;
 use warnings;
 
-BEGIN { use bigint }
 #BEGIN { $enum::DEBUG++ }
 
 use lib './lib';
@@ -41,12 +40,12 @@ print join ' ', Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday,
 use enum q(
     'ZERO=( $_ << 1 )'  TWO  FOUR SIX  EIGHT 'FIVE = $_'
 );
-print join ' ', ZERO, TWO, FOUR, SIX, EIGHT, FIVE;
+print join ' ', ZERO, TWO, FOUR, SIX, EIGHT, FIVE, "\n";
 # 0 2 4 6 8 9
 ###############################################################################
 use enum q(
     KB
-    'KB = 1 << (10 * $_)'
+    'KB = use bigint; 1 << (10 * $_)'
     MB
     GB
     TB
@@ -56,4 +55,4 @@ use enum q(
     YB
 );
 
-print join ' ', KB, MB, GB, TB, PB;
+print join ' ', KB, MB, GB, TB, PB, "\n";
diff --git a/lib/enum.pm b/lib/enum.pm
index d519a11..5d918b2 100644
--- a/lib/enum.pm
+++ b/lib/enum.pm
@@ -48,6 +48,7 @@ use vars qw( $VERSION $DEBUG );
 
 use v5.3;
 use Text::ParseWords;
+use Text::Trim;
 
 $VERSION = '0.03';
 $DEBUG   = 0 unless defined $DEBUG;
@@ -88,7 +89,6 @@ sub import {
 
     for my $sym (@enums) {
         next unless length $sym;
-        $sym =~ s/ //g; # remove spaces
 
         my $value;
 
@@ -96,8 +96,8 @@ sub import {
             if $sym =~ /^=|=$/;
 
         if ($sym =~ /^([^=]+)=(.+)$/) {
-            $sym = $1;
-            my $i= $2;
+            $sym = trim $1;
+            my $i= trim $2;
 
             if ($i =~ /$iotavar/) {
                 $iota = $i;

Olegymous ★★★
()
Ответ на: комментарий от Olegymous

'KB = use bigint; 1 << (10 * $_)'

читер :-P

Так подойдёт? :)

Канеш, спасибо большое)

Deleted
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.