Portál AbcLinuxu, 11. května 2025 23:38

Dotaz: Nelogicke chovani v perlu

27.11.2009 23:48 Mr.S1lent.cz
Nelogicke chovani v perlu
Přečteno: 220×
Odpovědět | Admin
Zdravim, mam tu jeden zahadny problem, nad kterym dumam uz asi cely den...

Zde je cast DB modulu: http://www.pastebin.cz/27127 a zde priklad volani metody _view: http://www.pastebin.cz/27128

a ted problem - do terminalu mi to vypise hodnotu pouze u test1, avsak test2 - 4 zustavaji empty, vypisy z Dumperu jsou konstantni, vedel by nekdo, kde muze byt chyba? Me absolutne nic nenapada, nechapu, jak se to takhle vubec muze chovat....

Řešení dotazu:


Nástroje: Začni sledovat (0) ?Zašle upozornění na váš email při vložení nového komentáře.

Odpovědi

28.11.2009 00:54 buff | skóre: 10 | blog: buff
Rozbalit Rozbalit vše Re: Nelogicke chovani v perlu
Odpovědět | | Sbalit | Link | Blokovat | Admin
Problém je IMHO v tom whilu. Ten první while to projede nakonec a ty další už vrací false v první iteraci. Potřeboval bys vyresetovat ten prstíček, co ukazuje na aktuální řádek.
28.11.2009 00:57 buff | skóre: 10 | blog: buff
Rozbalit Rozbalit vše Re: Nelogicke chovani v perlu
Snad seek? Hope it helps. Zkus, mně se to zkoušet nechce ;-)
28.11.2009 07:32 pht | skóre: 48 | blog: pht
Rozbalit Rozbalit vše Re: Nelogicke chovani v perlu
Odpovědět | | Sbalit | Link | Blokovat | Admin
Doporučuju ty věci dávát dohromady s dotazem a ne na pastebin. Za 2 roky až někdo na tohle náhodou narazí, tak už nepochopí co se řešilo.

Takže:
sub new {
    my ( $pkg, $db ) = @_;
    my $self = bless {}, $pkg;
    $self->{_db} = "db/$db.db";
    open( $self->{_dbhandler}, $self->{_db} ) or die "DB $db.db not open\n";
    return $self;
}
sub _view {
    my ( $self, $arg ) = @_;
    my $dbhandler = $self->{_dbhandler};
    while ( my $line = <$dbhandler> ) {
        if ( $line =~ /( *)$arg( *)\=( *)'(.*?)';( *)/ ) {
            return $4;
        }
    }
    return undef;
}
$self->{_db} = new TAI::DB( 'status' );
print Dumper( $self->{_db} );
print "test1: " . $self->{_db}->_view( 'task' ) . "\n";
print Dumper( $self->{_db} );
print "test2: " . $self->{_db}->_view( 'task' ) . "\n";
print Dumper( $self->{_db} );
print "test3: " . $self->{_db}->_view( 'task' ) . "\n";
print "test4: " . $self->{_db}->_view( 'task' ) . "\n";
No a k tomu dotazu, myslím si to co ostatní: soubor projíždíte po řádkách, takže nebude vracet v každém volání totéž. Dá se to řešit různě, ale myslím, že děláte tu celou věc trochu přes ruku, co přesně má být účelem toho kódu?
In Ada the typical infinite loop would normally be terminated by detonation.
28.11.2009 17:14 Mr.S1lent.cz
Rozbalit Rozbalit vše Re: Nelogicke chovani v perlu
Ucelem toho kodu - modulu - je vytvorit takovy obsluhovac souborů, ktere mi slouzi jako text/plan uloziste - datazabaze pouzivam jen tehdy, pokud je to nevyhnutelne nutne, tudiz to resim takhle. Podle vasich reakci usuzuju, ze si ten filehandler "pamatujue", kde naposledy skoncil a pote projizdeni souboru po radku pokracuje prave od toho mista, je to tak? :-) Jinak uz jdu na study toho seek, moc dekuji, verim, ze mi to pomuze vyresit problem :-))
28.11.2009 17:30 Mr.S1lent.cz
Rozbalit Rozbalit vše Re: Nelogicke chovani v perlu
Tak, problem je vyresen, seek mi opravdu pomohl :-) Moc dekuji - tady neslo o to, ze bych nevedel, kde hledat, ale ja nevedel, co hledat, jeste jednou diky :-))
28.11.2009 18:03 Nick
Rozbalit Rozbalit vše Re: Nelogicke chovani v perlu
No vidíš. A příště nenadávej na Perl a hledej nejdřív problém mezi klávesnicí a židlí :-)
29.11.2009 20:13 pht | skóre: 48 | blog: pht
Rozbalit Rozbalit vše Re: Nelogicke chovani v perlu
No, možností jak tohle udělat je hodně a upřímně seek je jeden z těch méně šťastných.

Nejjednodušší je dát open/close do rutiny _view, čili pokaždé soubor otevřít, najít řádek a potom ho zavřít. Je to stejně efektivní jako seek, ale čistější a robustnější vůči přepisu/smazání souboru.

Další možnost je v konstruktoru soubor kompletně přečíst a uložit si páry klíč=hodnota (pokud chápu dobře, tak ten soubor má takovou strukturu) do hashe a ve _view pouze vracet hodnoty z hashe. Případně dodělat něco jako reload, kterej to načte na požádání znova. Tento přístup je nesporně efektivnější co se týče počtu čtení souboru.

Třetí možnost je se porozhlédnout po CPANu, co například Config::Tiny a další?

Jinak, databáze není nevyhnutelně špatná věc.

Ještě pár postřehů k tomu kódu:
if ( $line =~ /( *)$arg( *)\=( *)'(.*?)';( *)/ ) {
            return $4;
        }
je lépe zapsat jako
if ( $line =~ /\A\s*\Q$arg\E\s*\=\s*'(.*?)';\s*\Z/ ) {
            return $1;
        }
(použití \s pro prázdné znaky, \A ... \Z pro ohraničení a \Q ... \E pro quotování proměnné. BTW regexp pro načtení celého souboru by mohl vypadat asi takto nějak
my %config;
open (my $soubor, '<', 'soubor.txt');
{
    unset $/;
    %config = (<$soubor> =~ /^\s*(\Q$arg\E)\s*\=\s*'(.*?)';\s*?/xmsg);
}
Místo return undef; je kratší (a správnější) použít jen return;.

Místo open...or die je modernější metoda use autodie.
In Ada the typical infinite loop would normally be terminated by detonation.

Založit nové vláknoNahoru

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.