Schrift
Wiki:Tipp zum Debugging: use Data::Dumper; local $Data::Dumper::Useqq = 1; print Dumper \@var;
[thread]12902[/thread]

private/public subs in modules

Leser: 1


<< |< 1 2 >| >> 15 Einträge, 2 Seiten
burnersk
 2008-12-13 16:01
#117163 #117163
User since
2008-03-25
83 Artikel
BenutzerIn
[default_avatar]
Hallo,

ab besten ich zeige was ich möchte :P
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package Test;

sub new
{
  my $invocant = shift;
  my $class = ref($invocant) || $invocant;
  my $self = {};
  bless($self, $class);
  return ($self);
}

sub test1()
{
  my $self = shift;
  return ('Ich will privat sein');
}

sub test2()
{
  my $self = shift;
  return ('Ich will oeffnetlich sein');
}


Code (perl): (dl )
1
2
use Test;
my $testhandle = Test->new();


Für Test::test1() kann ich ja den Exporter mit leerem @EXPORT verwenden.
Was ich jetzt möchte ist, dass man via $testhandle nur auf die Funktion test2() und nicht auf die Funktion test1() zugreifen kann.
Antworten mit Zitat
LanX-
 2008-12-13 16:22
#117164 #117164
User since
2008-07-15
1000 Artikel
BenutzerIn

user image
du meinst Methoden nicht Subs, schließlich sind deine Beispiele OOP.

Wenn du 100%ig ausschließen willst das Test::test2 aufrufbar ist musst du sie als lexikalische variablen derefrenzieren.

Code (perl): (dl )
1
2
3
my $coderef=sub {}; # defintion
$coderef->(); # aufruf1
&$coderef();  # aufruf2


wenn dir der Syntax zu hässlich ist, kööntest du mit autoload tricksen, und bei jedem Methoden-Aufruf abchecken, ob der Aufruf weitergeleitet wird. Was dann aber die Geschwindigkeit herabsetzt...

NACHTRAG: es gibt dermaßen viele OOP-Erweiterungsmodule die das erlauben, schätzungsweise auch Moose...
Antworten mit Zitat
Linuxer
 2008-12-13 16:27
#117165 #117165
User since
2006-01-27
3869 Artikel
HausmeisterIn

user image
Hi,

Methoden, deren Name mit _ beginnt, sind privat.
Es gibt da quasi eine "Absprache", dass solche Methoden nicht von ausserhalb aufgerufen werden.
Diese Benennung hindert den User aber nicht daran, trotzdem $testhandle->_private() aufzurufen. Wenn er das aber tut, ist er selber schuld und benutzt das Modul nicht so, wie es benutzt werden sollte.


Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package foo;

sub new {
 # ...
}

sub public {
  my ( $self ) = @_;
  $self->_private();
}

sub _private {
  my ( $self ) = @_;
  $self->_other_private_stuff();
}

# ...



In "Programming Perl, 3rd Edition, Chapter 12.5" findet sich eine Beschreibung, wie man private Methoden realisieren kann, die nicht von aussen direkt angesprochen werden können.
I.d.R. ist diese Art und Weise aber zuviel des Guten.

edit: Link nach Hinweis von LanX- entfernt.
meine Beiträge: I.d.R. alle Angaben ohne Gewähr und auf Linux abgestimmt!
Die Sprache heisst Perl, nicht PERL. - Bitte Crossposts als solche kenntlich machen!
Antworten mit Zitat
burnersk
 2008-12-13 16:38
#117166 #117166
User since
2008-03-25
83 Artikel
BenutzerIn
[default_avatar]
Danke euch beiden...

ich werde dann mal das einfache mit den Unterstrichen verwenden^^
Antworten mit Zitat
LanX-
 2008-12-13 16:59
#117167 #117167
User since
2008-07-15
1000 Artikel
BenutzerIn

user image
@Linuxer: Wie wärs mit der "Absprache" keine illegalen Webseiten zu verlinken? ; )

BTW: die dort beschriebene Methode ist identisch zu meiner! Und &$sub() braucht gerade ein Zeichen mehr als _sub()
Antworten mit Zitat
Linuxer
 2008-12-13 17:09
#117168 #117168
User since
2006-01-27
3869 Artikel
HausmeisterIn

user image
LanX-+2008-12-13 15:59:58--
@Linuxer: Wie wärs mit der "Absprache" keine illegalen Webseiten zu verlinken? ; )


Hm, danke für den Hinweis; das hat man davon wenn man Googles ersten Suchtreffer verwendet... :(
meine Beiträge: I.d.R. alle Angaben ohne Gewähr und auf Linux abgestimmt!
Die Sprache heisst Perl, nicht PERL. - Bitte Crossposts als solche kenntlich machen!
Antworten mit Zitat
Linuxer
 2008-12-13 17:10
#117169 #117169
User since
2006-01-27
3869 Artikel
HausmeisterIn

user image
LanX-+2008-12-13 15:59:58--
BTW: die dort beschriebene Methode ist identisch zu meiner! Und &$sub() braucht gerade ein Zeichen mehr als _sub()


BTW: Es soll ja schon mal vorkommen, dass zwei User gleichzeitig eine Antwort tippen und dass sogar beide sehr ähnlichen Inhalt haben!
meine Beiträge: I.d.R. alle Angaben ohne Gewähr und auf Linux abgestimmt!
Die Sprache heisst Perl, nicht PERL. - Bitte Crossposts als solche kenntlich machen!
Antworten mit Zitat
LanX-
 2008-12-13 17:17
#117172 #117172
User since
2008-07-15
1000 Artikel
BenutzerIn

user image
Linuxer+2008-12-13 16:10:39--
BTW: Soll es schon mal vorkommen, dass zwei User gleichzeitig eine Antwort tippen und dass sogar beide sehr ähnlichen Inhalt haben!

das war nur zur erläuterung gedacht, außerdem nehme ichs zurück, den Code verstehe ich nicht 100%

den folgenden Text hab ich NATÜRLICH aus dem Buch abgetippt ... ; )
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# An intriguing aspect of this behavior is that it can be used to implement private method calls. 
# If you put your class in a module, you can make use of the file's lexical scope for privacy. 
# First, store an anonymous subroutine in a file-scoped lexical:

    # declare private method
    my $secret_door = sub {
        my $self = shift;
        ...
    };

# Later on in the file, you can use that variable as though it held a method name. The closure 
# will be called directly, without regard to inheritance. As with any other method, the invocant is 
# passed as an extra argument.

    sub knock {
        my $self = shift;
        if ($self->{knocked}++ > 5) {
            $self->$secret_door();
        }
    }


mit welcher Magie $self->$secret_door(); funzt soll mir bitte jmd erklären. Mein (kopf-)schmerzendes Hirn kann nur vermutungen über AUTOLOAD anstellen... oder haben wir hier ein mir unbekanntes Feature von -> ?
Antworten mit Zitat
topeg
 2008-12-13 17:58
#117182 #117182
User since
2006-07-10
2611 Artikel
BenutzerIn

user image
Ansich ist das recht simpel.
Variablen, die in einem Block mit "my" definiert werden, sind ja außerhalb des Blockes nicht zu erreichen. Wenn ein Package in einer Datei oder Block definiert wird, dann ist innerhalb des Package als privat definierten Variablen außerhalb unsichtbar. Wird Das Package als Klasse verwendet wird damit die Klassenvariable unsichtbar und alles was in ihr steht. Nur innerhalb der Klasse (oder dem daraus erzeugten Objekt, selber Namespace) ist die Variable sichtbar.
Antworten mit Zitat
LanX-
 2008-12-13 18:13
#117184 #117184
User since
2008-07-15
1000 Artikel
BenutzerIn

user image
Das die Variable $secret_door außerhalb des Scopes nicht erreichbar ist ist klar!

Aber ich verstehe immer noch nicht dieser Aufruf funktioniert. was in $self->$secret_door(); übergeben wird?

$secret_door ist ein Coderef statt eines Namens! D.H. im zu $self geblessten Package wird nach einem Sub gesucht, das sowas wie "CODE[ABCDEF]" heißt?

UPDATE: man lernt nie aus perlop

Otherwise, the right side is a method name or a simple scalar variable containing
either the method name or a subroutine reference, and the left side must be
either an object (a blessed reference) or a class name (that is, a package name).
See perlobj.


AFAIS lässt sich perlobj aber nicht mehr darüber aus was passiert wenn die rechte Seite ein coderef ist... obscur sehr obscur ...
Antworten mit Zitat
<< |< 1 2 >| >> 15 Einträge, 2 Seiten



View all threads created 2008-12-13 16:01.