{
    "content": [
        {
            "type": "text",
            "text": "# POE::Session (perldoc)\n\n## NAME\n\nPOE::Session - a generic event-driven task\n\n## SYNOPSIS\n\nuse POE; # auto-includes POE::Kernel and POE::Session\nPOE::Session->create(\ninlinestates => {\nstart => sub { $[KERNEL]->yield(\"next\") },\nnext   => sub {\nprint \"tick...\\n\";\n$[KERNEL]->delay(next => 1);\n},\n},\n);\nPOE::Kernel->run();\nexit;\nPOE::Session can also dispatch to object and class methods through \"objectstates\" and\n\"packagestates\" callbacks.\n\n## DESCRIPTION\n\nPOE::Session and its subclasses translate events from POE::Kernel's generic dispatcher into the\nparticular calling conventions suitable for application code. In design pattern parlance,\nPOE::Session classes are adapters between POE::Kernel and application code.\n\n## Sections\n\n- **NAME**\n- **SYNOPSIS**\n- **DESCRIPTION** (1 subsections)\n- **PUBLIC METHODS** (2 subsections)\n- **SEE ALSO**\n- **BUGS** (1 subsections)\n\nUse structuredContent.sections for detailed options, examples, and full documentation.\n"
        }
    ],
    "structuredContent": {
        "command": "POE::Session",
        "section": "",
        "mode": "perldoc",
        "summary": "POE::Session - a generic event-driven task",
        "synopsis": "use POE; # auto-includes POE::Kernel and POE::Session\nPOE::Session->create(\ninlinestates => {\nstart => sub { $[KERNEL]->yield(\"next\") },\nnext   => sub {\nprint \"tick...\\n\";\n$[KERNEL]->delay(next => 1);\n},\n},\n);\nPOE::Kernel->run();\nexit;\nPOE::Session can also dispatch to object and class methods through \"objectstates\" and\n\"packagestates\" callbacks.",
        "tldr_summary": null,
        "tldr_examples": [],
        "tldr_source": null,
        "flags": [],
        "examples": [],
        "see_also": [],
        "section_outline": [
            {
                "name": "NAME",
                "lines": 2,
                "subsections": []
            },
            {
                "name": "SYNOPSIS",
                "lines": 18,
                "subsections": []
            },
            {
                "name": "DESCRIPTION",
                "lines": 219,
                "subsections": [
                    {
                        "name": "Using POE::Session With Objects",
                        "lines": 47
                    }
                ]
            },
            {
                "name": "PUBLIC METHODS",
                "lines": 281,
                "subsections": [
                    {
                        "name": "callback",
                        "lines": 2
                    },
                    {
                        "name": "callback",
                        "lines": 135
                    }
                ]
            },
            {
                "name": "SEE ALSO",
                "lines": 4,
                "subsections": []
            },
            {
                "name": "BUGS",
                "lines": 3,
                "subsections": [
                    {
                        "name": "Beware circular references",
                        "lines": 99
                    }
                ]
            }
        ],
        "sections": {
            "NAME": {
                "content": "POE::Session - a generic event-driven task\n",
                "subsections": []
            },
            "SYNOPSIS": {
                "content": "use POE; # auto-includes POE::Kernel and POE::Session\n\nPOE::Session->create(\ninlinestates => {\nstart => sub { $[KERNEL]->yield(\"next\") },\nnext   => sub {\nprint \"tick...\\n\";\n$[KERNEL]->delay(next => 1);\n},\n},\n);\n\nPOE::Kernel->run();\nexit;\n\nPOE::Session can also dispatch to object and class methods through \"objectstates\" and\n\"packagestates\" callbacks.\n",
                "subsections": []
            },
            "DESCRIPTION": {
                "content": "POE::Session and its subclasses translate events from POE::Kernel's generic dispatcher into the\nparticular calling conventions suitable for application code. In design pattern parlance,\nPOE::Session classes are adapters between POE::Kernel and application code.\n\nThe sessions that POE::Kernel manages are more like generic task structures. Unfortunately these\ntwo disparate concepts have virtually identical names.\n\nA note on nomenclature\nThis documentation will refer to event handlers as \"states\" in certain unavoidable situations.\nSessions were originally meant to be event-driven state machines, but their purposes evolved\nover time. Some of the legacy vocabulary lives on in the API for backward compatibility,\nhowever.\n\nConfusingly, POE::NFA is a class for implementing actual event-driven state machines. Its\ndocumentation uses \"state\" in the proper sense.\n\nUSING POE::Session\nPOE::Session has two main purposes. First, it maps event names to the code that will handle\nthem. Second, it maps a consistent event dispatch interface to those handlers.\n\nConsider the \"SYNOPSIS\" for example. A POE::Session instance is created with two\n\"inlinestates\", each mapping an event name (\"start\" and \"next\") to an inline subroutine.\nPOE::Session ensures that \"$[KERNEL]\" and so on are meaningful within an event handler.\n\nEvent handlers may also be object or class methods, using \"objectstates\" and \"packagestates\"\nrespectively. The create() syntax is different than for \"inlinestates\", but the calling\nconvention is nearly identical.\n\nNotice that the created POE::Session object has not been saved to a variable. The new\nPOE::Session object gives itself to POE::Kernel, which then manages it and all the resources it\nuses.\n\nIt's possible to keep references to new POE::Session objects, but it's not usually necessary. If\nan application is not careful about cleaning up these references you will create circular\nreferences, which will leak memory when POE::Kernel would normally destroy the POE::Session\nobject. It is recommended that you keep the session's ID instead.\n\nPOE::Session's Calling Convention\nThe biggest syntactical hurdle most people have with POE is POE::Session's unconventional\ncalling convention. For example:\n\nsub handleevent {\nmy ($kernel, $heap, $parameter) = @[KERNEL, HEAP, ARG0];\n...;\n}\n\nOr the use of $[KERNEL], $[HEAP] and $[ARG0] inline, as is done in most examples.\n\nWhat's going on here is rather basic. Perl passes parameters into subroutines or methods using\nthe @ array. \"KERNEL\", \"HEAP\", \"ARG0\" and others are constants exported by POE::Session (which\nis included for free when a program uses POE).\n\nSo $[KERNEL] is an event handler's KERNELth parameter. @[HEAP, ARG0] is a slice of @\ncontaining the HEAPth and ARG0th parameters.\n\nWhile this looks odd, it's perfectly plain and legal Perl syntax. POE uses it for a few reasons:\n\n1   In the common case, passing parameters in @ is faster than passing hash or array references\nand then dereferencing them in the handler.\n\n2   Typos in hash-based parameter lists are either subtle run-time errors or requires constant\nrun-time checking. Constants are either known at compile time, or are clear compile-time\nerrors.\n\n3   Referencing @ offsets by constants allows parameters to move in the future without breaking\napplication code.\n\n4   Most event handlers don't need all of @. Slices allow handlers to use only the parameters\nthey're interested in.\n\nPOE::Session Parameters\nEvent handlers receive most of their run-time context in up to nine callback parameters.\nPOE::Kernel provides many of them.\n\n$[OBJECT]\n$[OBJECT] is $self for event handlers that are an object method. It is the class (package) name\nfor class-based event handlers. It is undef for plain coderef callbacks, which have no special\n$self-ish value.\n\n\"OBJECT\" is always zero, since $[0] is always $self or $class in object and class methods.\nCoderef handlers are called with an \"undef\" placeholder in $[0] so that the other offsets\nremain valid.\n\nIt's often useful for method-based event handlers to call other methods in the same object.\n$[OBJECT] helps this happen.\n\nsub uiupdateeverything {\nmy $self = $[OBJECT];\n$self->updatemenu();\n$self->updatemainwindow();\n$self->updatestatusline();\n}\n\nYou may also use method inheritance. Here we invoke $self->amethod(@). Since Perl's \"->\"\noperator unshifts $self onto the beginning of @, we must first shift a copy off to maintain\nPOE's parameter offsets:\n\nsub amethod {\nmy $self = shift;\n$self->SUPER::amethod( @ );\n# ... more work ...\n}\n\n$[SESSION]\n$[SESSION] is a reference to the current session object. This lets event handlers access their\nsession's methods. Programs may also compare $[SESSION] to $[SENDER] to verify that\nintra-session events did not come from other sessions.\n\n$[SESSION] may also be used as the destination for intra-session post() and call(). yield() is\nmarginally more convenient and efficient than \"post($[SESSION], ...)\" however.\n\nIt is bad form to access another session directly. The recommended approach is to manipulate a\nsession through an event handler.\n\nsub enabletrace {\nmy $previoustrace = $[SESSION]->option( trace => 1 );\nmy $id = $[SESSION]->ID;\nif ($previoustrace) {\nprint \"Session $id: dispatch trace is still on.\\n\";\n}\nelse {\nprint \"Session $id: dispatch trace has been enabled.\\n\";\n}\n}\n\n$[KERNEL]\nThe KERNELth parameter is always a reference to the application's singleton POE::Kernel\ninstance. It is most often used to call POE::Kernel methods from event handlers.\n\n# Set a 10-second timer.\n$[KERNEL]->delay( timeisup => 10 );\n\n$[HEAP]\nEvery POE::Session object contains its own variable namespace known as the session's \"HEAP\". It\nis modeled and named after process memory heaps (not priority heaps). Heaps are by default\nanonymous hash references, but they may be initialized in create() to be almost anything.\nPOE::Session itself never uses $[HEAP], although some POE components do.\n\nHeaps do not overlap between sessions, although create()'s \"heap\" parameter can be used to make\nthis happen.\n\nThese two handlers time the lifespan of a session:\n\nsub starthandler {\n$[HEAP]{tsstart} = time();\n}\n\nsub stophandler {\nmy $timeelapsed = time() - $[HEAP]{tsstart};\nprint \"Session \", $[SESSION]->ID, \" elapsed seconds: $elapsed\\n\";\n}\n\n$[STATE]\nThe STATEth handler parameter contains the name of the event being dispatched in the current\ncallback. This can be important since the event and handler names may significantly differ.\nAlso, a single handler may be assigned to more than one event.\n\nPOE::Session->create(\ninlinestates => {\none => \\&somehandler,\ntwo => \\&somehandler,\nsix => \\&somehandler,\nten => \\&somehandler,\nstart => sub {\n$[KERNEL]->yield($) for qw(one two six ten);\n}\n}\n);\n\nsub somehandler {\nprint(\n\"Session \", $[SESSION]->ID,\n\": somehandler() handled event $[STATE]\\n\"\n);\n}\n\nIt should be noted however that having event names and handlers names match will make your code\neasier to navigate.\n\n$[SENDER]\nEvents must come from somewhere. $[SENDER] contains the currently dispatched event's source.\n\n$[SENDER] is commonly used as a return address for responses. It may also be compared against\n$[KERNEL] to verify that timers and other POE::Kernel-generated events were not spoofed.\n\nThis \"echohandler()\" responds to the sender with an \"echo\" event that contains all the\nparameters it received. It avoids a feedback loop by ensuring the sender session and event\n(STATE) are not identical to the current ones.\n\nsub echohandler {\nreturn if $[SENDER] == $[SESSION] and $[STATE] eq \"echo\";\n$[KERNEL]->post( $[SENDER], \"echo\", @[ARG0..$#] );\n}\n\n$[CALLERFILE], $[CALLERLINE] and $[CALLERSTATE]\nThese parameters are a form of caller(), but they describe where the currently dispatched event\noriginated. CALLERFILE and CALLERLINE are fairly plain. CALLERSTATE contains the name of the\nevent that was being handled when the event was created, or when the event watcher that\nultimately created the event was registered.\n\n@[ARG0..ARG9] or @[ARG0..$#]\nParameters $[ARG0] through the end of @ contain parameters provided by application code, event\nwatchers, or higher-level libraries. These parameters are guaranteed to be at the end of @ so\nthat @[ARG0..$#] will always catch them all.\n\n$# is the index of the last value in @. Blame Perl if it looks odd. It's merely the $#array\nsyntax where the array name is an underscore.\n\nConsider\n\n$[KERNEL]->yield( evwhatever => qw( zero one two three ) );\n\nThe handler for evwhatever will be called with \"zero\" in $[ARG0], \"one\" in $[ARG1], and so\non. @[ARG0..$#] will contain all four words.\n\nsub evwhatever {\n$[OBJECT]->whatever( @[ARG0..$#] );\n}\n",
                "subsections": [
                    {
                        "name": "Using POE::Session With Objects",
                        "content": "One session may handle events across many objects. Or looking at it the other way, multiple\nobjects can be combined into one session. And what the heck---go ahead and mix in some inline\ncode as well.\n\nPOE::Session->create(\nobjectstates => [\n$object1 => { event1a => \"method1a\" },\n$object2 => { event2a => \"method2a\" },\n],\ninlinestates => {\nevent3 => \\&pieceofcode,\n},\n);\n\nHowever only one handler may be assigned to a given event name. Duplicates will overwrite\nearlier ones.\n\nevent1a is handled by calling \"$object1->method1a(...)\". $[OBJECT] is $object1 in this\ncase. $[HEAP] belongs to the session, which means anything stored there will be available to\nany other event handler regardless of the object.\n\nevent2a is handled by calling \"$object2->method2a(...)\". In this case $[OBJECT] is\n$object2. $[HEAP] is the same anonymous hashref that was passed to the event1a handler,\nthough. The methods are resolved when the event is handled (late-binding).\n\nevent3 is handled by calling \"pieceofcode(...)\". $[OBJECT] is \"undef\" here because there's\nno object. And once again, $[HEAP] is the same shared hashref that the handlers for event1a\nand event2a saw.\n\nInterestingly, there's no technical reason that a single object can't handle events from more\nthan one session:\n\nfor (1..2) {\nPOE::Session->create(\nobjectstates => [\n$object4 => { event4 => \"method4\" },\n]\n);\n}\n\nNow \"$object4->method4(...)\" may be called to handle events from one of two sessions. In both\ncases, $[OBJECT] will be $object4, but $[HEAP] will hold data for a particular session.\n\nThe same goes for inline states. One subroutine may handle events from many sessions.\n$[SESSION] and $[HEAP] can be used within the handler to easily access the context of the\nsession in which the event is being handled.\n"
                    }
                ]
            },
            "PUBLIC METHODS": {
                "content": "POE::Session has just a few public methods.\n\ncreate LOTSOFSTUFF\n\"create()\" starts a new session running. It returns a new POE::Session object upon success, but\nmost applications won't need to save it.\n\n\"create()\" invokes the newly started session's start event handler before returning.\n\n\"create()\" also passes the new POE::Session object to POE::Kernel. POE's kernel holds onto the\nobject in order to dispatch events to it. POE::Kernel will release the object when it detects\nthe object has become moribund. This should cause Perl to destroy the object if application code\nhas not saved a copy of it.\n\n\"create()\" accepts several named parameters, most of which are optional. Note however that the\nparameters are not part of a hashref.\n\nargs => ARRAYREF\nThe \"args\" parameter accepts a reference to a list of parameters that will be passed to the\nsession's start event handler in @ positions \"ARG0\" through $# (the end of @).\n\nThis example would print \"arg0 arg1 etc.\":\n\nPOE::Session->create(\ninlinestates => {\nstart => sub {\nprint \"Session started with arguments: @[ARG0..$#]\\n\";\n},\n},\nargs => [ 'arg0', 'arg1', 'etc.' ],\n);\n\nheap => ANYTHING\nThe \"heap\" parameter allows a session's heap to be initialized differently at instantiation\ntime. Heaps are usually anonymous hashrefs, but \"heap\" may set them to be array references or\neven objects.\n\nThis example prints \"tree\":\n\nPOE::Session->create(\ninlinestates => {\nstart => sub {\nprint \"Slot 0 = $[HEAP][0]\\n\";\n},\n},\nheap => [ 'tree', 'bear' ],\n);\n\nBe careful when initializing the heap to be something that doesn't behave like a hashref. Some\nlibraries assume hashref heap semantics, and they will fail if the heap doesn't work that way.\n\ninlinestates => HASHREF\n\"inlinestates\" maps events names to the subroutines that will handle them. Its value is a\nhashref that maps event names to the coderefs of their corresponding handlers:\n\nPOE::Session->create(\ninlinestates => {\nstart => sub {\nprint \"arg0=$[ARG0], arg1=$[ARG1], etc.=$[ARG2]\\n\";\n},\nstop  => \\&stophandler,\n},\nargs => [qw( arg0 arg1 etc. )],\n);\n\nThe term \"inline\" comes from the fact that coderefs can be inlined anonymous subroutines.\n\nBe very careful with closures, however. \"Beware circular references\".\n\nobjectstates => ARRAYREF\n\"objectstates\" associates one or more objects to a session and maps event names to the object\nmethods that will handle them. It's value is an \"ARRAYREF\"; \"HASHREFs\" would stringify the\nobjects, ruining them for method invocation.\n\nHere start is handled by \"$object->sessionstart()\" and stop triggers\n\"$object->sessionstop()\":\n\nPOE::Session->create(\nobjectstates => [\n$object => {\nstart => 'sessionstart',\nstop  => 'sessionstop',\n}\n]\n);\n\nPOE::Session also supports a short form where the event and method names are identical. Here\nstart invokes $object->start(), and stop triggers $object->stop():\n\nPOE::Session->create(\nobjectstates => [\n$object => [ 'start', 'stop' ],\n]\n);\n\nMethods are verified when the session is created, but also resolved when the handler is called\n(late binding). Most of the time, a method won't change. But in some circumstance, such as\ndynamic inheritance, a method could resolve to a different subroutine.\n\noptions => HASHREF\nPOE::Session sessions support a small number of options, which may be initially set with the\n\"option\" constructor parameter and changed at run time with the \"option()|/option\" method.\n\n\"option\" takes a hashref with option => value pairs:\n\nPOE::Session->create(\n... set up handlers ...,\noptions => { trace => 1, debug => 1 },\n);\n\nThis is equivalent to the previous example:\n\nPOE::Session->create(\n... set up handlers ...,\n)->option( trace => 1, debug => 1 );\n\nThe supported options and values are documented with the \"option()|/option\" method.\n\npackagestates => ARRAYREF\n\"packagestates\" associates one or more classes to a session and maps event names to the class\nmethods that will handle them. Its function is analogous to \"objectstates\", but package names\nare specified rather than objects.\n\nIn fact, the following documentation is a copy of the \"objectstates\" description with some word\nsubstitutions.\n\nThe value for \"packagestates\" is an ARRAYREF to be consistent with \"objectstates\", even though\nclass names (also known as package names) are already strings, so it's not necessary to avoid\nstringifying them.\n\nHere start is handled by \"$classname->sessionstart()\" and stop triggers\n\"$classname->sessionstop()\":\n\nPOE::Session->create(\npackagestates => [\n$classname => {\nstart => 'sessionstart',\nstop  => 'sessionstop',\n}\n]\n);\n\nPOE::Session also supports a short form where the event and method names are identical. Here\nstart invokes \"$classname->start()\", and stop triggers \"$classname->stop()\":\n\nPOE::Session->create(\npackagestates => [\n$classname => [ 'start', 'stop' ],\n]\n);\n\nID\n\"ID()\" returns the session instance's unique identifier. This is an integer that starts at 1 and\ncounts up forever, or until the number wraps around.\n\nIt's theoretically possible that a session ID will not be unique, but this requires at least\n4.29 billion sessions to be created within a program's lifespan. POE guarantees that no two\nsessions will have the same ID at the same time, however; your computer doesn't have enough\nmemory to store 4.29 billion session objects.\n\nA session's ID is unique within a running process, but multiple processes are likely to have the\nsame session IDs. If a global ID is required, it will need to include both \"$[KERNEL]->ID\" and\n\"$[SESSION]->ID\".\n\noption OPTIONNAME [, OPTIONVALUE [, OPTIONNAME, OPTIONVALUE]... ]\n\"option()\" sets and/or retrieves the values of various session options. The options in question\nare implemented by POE::Session and do not have any special meaning anywhere else.\n\nIt may be called with a single OPTIONNAME to retrieve the value of that option.\n\nmy $tracevalue = $[SESSION]->option('trace');\n\n\"option()\" sets an option's value when called with a single OPTIONNAME, OPTIONVALUE pair. In\nthis case, \"option()\" returns the option's previous value.\n\nmy $previoustrace = $[SESSION]->option(trace => 1);\n\n\"option()\" may also be used to set the values of multiple options at once. In this case,\n\"option()\" returns all the specified options' previous values in an anonymous hashref:\n\nmy $previousvalues = $[SESSION]->option(\ntrace => 1,\ndebug => 1,\n);\n\nprint \"Previous option values:\\n\";\nwhile (my ($option, $oldvalue) = each %$previousvalues) {\nprint \"  $option = $oldvalue\\n\";\n}\n\nPOE::Session currently supports three options:\n\nThe \"debug\" option.\nThe \"debug\" option is intended to enable additional warnings when strange things are afoot\nwithin POE::Session. At this time, there is only one additional warning:\n\n*   Redefining an event handler does not usually cause a warning, but it will when the \"debug\"\noption is set.\n\nThe \"default\" option.\nEnabling the \"default\" option causes unknown events to become warnings, if there is no default\nhandler to catch them.\n\nThe class-level \"POE::Session::ASSERTSTATES\" flag is implemented by enabling the \"default\"\noption on all new sessions.\n\nThe \"trace\" option.\nTurn on the \"trace\" option to dump a log of all the events dispatched to a particular session.\nThis is a session-specific trace option that allows individual sessions to be debugged.\n\nSession-level tracing also indicates when events are redirected to default. This can be used to\ndiscover event naming errors.\n\nUser-defined options.\n\"option()\" does not verify whether OPTIONNAMEs are known, so \"option()\" may be used to store\nand retrieve user-defined information.\n\nChoose option names with caution. There is no established convention to avoid namespace\ncollisions between user-defined options and future internal options.\n\npostback EVENTNAME, EVENTPARAMETERS\n\"postback()\" manufactures callbacks that post POE events. It returns an anonymous code reference\nthat will post EVENTNAME to the target session, with optional EVENTPARAMETERS in an array\nreference in ARG0. Parameters passed to the callback will be sent in an array reference in ARG1.\n\nIn other words, ARG0 allows the postback's creator to pass context through the postback. ARG1\nallows the caller to return information.\n\nThis example creates a coderef that when called posts \"okbutton\" to $somesession with ARG0\ncontaining \"[ 8, 6, 7 ]\".\n\nmy $postback = $somesession->postback( \"okbutton\", 8, 6, 7 );\n\nHere's an example event handler for \"okbutton\".\n\nsub handleokbutton {\nmy ($creationargs, $calledargs) = @[ARG0, ARG1];\nprint \"Postback created with (@$creationargs).\\n\";\nprint \"Postback called with (@$calledargs).\\n\";\n}\n\nCalling $postback->(5, 3, 0, 9) would perform the equivalent of...\n\n$poekernel->post(\n$somesession, \"okbutton\",\n[ 8, 6, 7 ],\n[ 5, 3, 0, 9 ]\n);\n\nThis would be displayed when \"okbutton\" was dispatched to handleokbutton():\n\nPostback created with (8 6 7).\nPostback called with (5 3 0 9).\n\nPostbacks hold references to their target sessions. Therefore sessions with outstanding\npostbacks will remain active. Under every event loop except Tk, postbacks are blessed so that\nDESTROY may be called when their users are done. This triggers a decrement on their reference\ncounts, allowing sessions to stop.\n\nPostbacks have one method, weaken(), which may be used to reduce their reference counts upon\ndemand. weaken() returns the postback, so you can do:\n\nmy $postback = $session->postback(\"foo\")->weaken();\n\nPostbacks were created as a thin adapter between callback libraries and POE. The problem at hand\nwas how to turn callbacks from the Tk graphical toolkit's widgets into POE events without\nsubclassing several Tk classes. The solution was to provide Tk with plain old callbacks that\nposted POE events.\n\nSince \"postback()\" and \"callback()\" are Session methods, they may be called on $[SESSION] or\n$[SENDER], depending on particular needs. There are usually better ways to interact between\nsessions than abusing postbacks, however.\n\nHere's a brief example of attaching a Gtk2 button to a POE event handler:\n\nmy $btn = Gtk2::Button->new(\"Clear\");\n$btn->signalconnect( \"clicked\", $[SESSION]->postback(\"evclear\") );\n\nPoints to remember: The session will remain alive as long as $btn exists and holds a copy of\n$[SESSION]'s postback. Any parameters passed by the Gtk2 button will be in ARG1.\n\ncallback EVENTNAME, EVENTPARAMETERS",
                "subsections": [
                    {
                        "name": "callback",
                        "content": "than \"$poekernel->post()\". It is identical to \"postback()\" in every other respect.\n"
                    },
                    {
                        "name": "callback",
                        "content": "callbacks will execute synchronously. File::Find is an obvious (but not necessarily appropriate)\nexample. It provides a lot of information in local variables that stop being valid after the\ncallback. The information would be unavailable by the time a post()ed event was dispatched.\n\ngetheap\n\"getheap()\" returns a reference to a session's heap. This is the same value as $[HEAP] for the\ntarget session. \"getheap()\" is intended to be used with $poekernel and POE::Kernel's\n\"getactivesession()\" so that libraries do not need these three common values explicitly passed\nto them.\n\nThat is, it prevents the need for:\n\nsub somehelperfunction {\nmy ($kernel, $session, $heap, @specificparameters) = @;\n...;\n}\n\nRather, helper functions may use:\n\nuse POE::Kernel; # exports $poekernel\nsub somehelperfunction {\nmy (@specificparameters) = @;\nmy $session = $poekernel->getactivesession();\nmy $heap = $session->getheap();\n}\n\nThis isn't very convenient for people writing libraries, but it makes the libraries much more\nconvenient to use.\n\nUsing \"getheap()\" to break another session's encapsulation is strongly discouraged.\n\ninstantiate CREATEPARAMETERS\n\"instantiate()\" creates and returns an empty POE::Session object. It is called with the\nCREATEPARAMETERS in a hash reference just before \"create()\" processes them. Modifications to\nthe CREATEPARAMETERS will affect how \"create()\" initializes the new session.\n\nSubclasses may override \"instantiate()\" to alter the underlying session's structure. They may\nextend \"instantiate()\" to add new parameters to \"create()\".\n\nAny parameters not recognized by \"create()\" must be removed from the CREATEPARAMETERS before\n\"instantiate()\" returns. \"create()\" will croak if it discovers unknown parameters.\n\nBe sure to return $self from instantiate.\n\nsub instantiate {\nmy ($class, $createparams) = @;\n\n# Have the base class instantiate the new session.\nmy $self = $class->SUPER::instantiate($createparameters);\n\n# Extend the parameters recognized by create().\nmy $newoption = delete $createparameters->{newoption};\nif (defined $newoption) {\n# ... customize $self here ...\n}\n\nreturn $self;\n}\n\ntryalloc STARTARGS\n\"tryalloc()\" calls POE::Kernel's \"sessionalloc()\" to allocate a session structure and begin\nmanaging the session within POE's kernel. It is called at the end of POE::Session's \"create()\".\nIt returns $self.\n\nIt is a subclassing hook for late session customization prior to \"create()\" returning. It may\nalso affect the contents of @[ARG0..$#] that are passed to the session's start handler.\n\nsub tryalloc {\nmy ($self, @startargs) = @;\n\n# Perform late initialization.\n# ...\n\n# Give $self to POE::Kernel.\nreturn $self->SUPER::tryalloc(@args);\n}\n\nPOE::Session's EVENTS\nPlease do not define new events that begin with a leading underscore. POE claims /^/ events as\nits own.\n\nPOE::Session only generates one event, default. All other internal POE events are generated by\n(and documented in) POE::Kernel.\n\ndefault\ndefault is the \"AUTOLOAD\" of event handlers. If POE::Session can't find a handler at dispatch\ntime, it attempts to redirect the event to default's handler instead.\n\nIf there's no default handler, POE::Session will silently drop the event unless the \"default\"\noption is set.\n\nTo preserve the original information, the original event is slightly changed before being\nredirected to the default handler: The original event parameters are moved to an array\nreference in ARG1, and the original event name is passed to default in ARG0.\n\nsub handledefault {\nmy ($event, $args) = @[ARG0, ARG1];\nprint(\n\"Session \", $[SESSION]->ID,\n\" caught unhandled event $event with (@$args).\\n\"\n);\n}\n\ndefault is quite flexible. It may be used for debugging, or to handle dynamically generated\nevent names without pre-defining their handlers. In the latter sense, default performs\nanalogously to Perl's \"AUTOLOAD\".\n\ndefault may also be used as the default or \"otherwise\" clause of a switch statement. Consider\nan input handler that throws events based on a command name:\n\nsub parsecommand {\nmy ($command, @parameters) = split /\\s+/, $[ARG0];\n$[KERNEL]->post( \"cmd$command\", @parameters );\n}\n\nA default handler may be used to emit errors for unknown commands:\n\nsub handledefault {\nmy $event = $[ARG0];\nreturn unless $event =~ /^cmd(\\S+)/;\nwarn \"Unknown command: $1\\n\";\n}\n\nThe default behavior is implemented in POE::Session, so it may be different for other session\ntypes.\n\nPOE::Session's Debugging Features\nPOE::Session contains one debugging assertion, for now.\n\nASSERTSTATES\nSetting ASSERTSTATES to true causes every Session to warn when they are asked to handle unknown\nevents. Session.pm implements the guts of ASSERTSTATES by defaulting the \"default\" option to\ntrue instead of false. See the option() method earlier in this document for details about the\n\"default\" option.\n"
                    }
                ]
            },
            "SEE ALSO": {
                "content": "POE::Kernel.\n\nThe SEE ALSO section in POE contains a table of contents covering the entire POE distribution.\n",
                "subsections": []
            },
            "BUGS": {
                "content": "There is a chance that session IDs may collide after Perl's integer value wraps. This can occur\nafter as *few* as 4.29 billion sessions.\n",
                "subsections": [
                    {
                        "name": "Beware circular references",
                        "content": "As you're probably aware, a circular reference is when a variable is part of a reference chain\nthat eventually refers back to itself. Perl will not reclaim the memory involved in such a\nreference chain until the chain is manually broken.\n\nHere a POE::Session is created that refers to itself via an external scalar. The event handlers\nimport $session via closures which are in turn stored within $session. Even if this session\nstops, the circular references will remain.\n\nmy $session;\n$session = POE::Session->create(\ninlinestates => {\nstart => sub {\n$[HEAP]->{todo} = [ qw( step1 step2 step2a ) ],\n$[KERNEL]->post( $session, 'next' );\n},\nnext => sub {\nmy $next = shift @{ $[HEAP]->{todo} };\nreturn unless $next;\n$[KERNEL]->post( $session, $next );\n}\n# ....\n}\n);\n\nReduced to its essence:\n\nmy %eventhandlers;\n$eventhandler{start} = sub { \\%eventhandlers };\n\nNote also that an anonymous sub creates a closure on all lexical variables in the scope it was\ndefined in, even if it doesn't reference them. $session is still being held in a circular\nreference here:\n\nmy $self = $package->new;\nmy $session;\n$session = POE::Session->create(\ninlinestate => {\nstart => sub { $self->start( @[ARG0..$#] ) }\n}\n);\n\nTo avoid this, a session may set an alias for itself. Other parts of the program may then refer\nto it by alias. In this case, one needn't keep track of the session themselves (POE::Kernel will\ndo it anyway).\n\nPOE::Session->create(\ninlinestates => {\nstart => sub {\n$[HEAP]->{todo} = [ qw( step1 step2 step2a ) ],\n$[KERNEL]->aliasset('stepdoer');\n$[KERNEL]->post( 'stepdoer', 'next' );\n},\nnext => sub {\nmy $next = shift @{ $[HEAP]->{todo} };\nreturn unless $next;\n$[KERNEL]->post( 'stepdoer', $next );\n}\n# ....\n}\n);\n\nAliases aren't even needed in the previous example because the session refers to itself. One\ncould instead use POE::Kernel's yield() method to post the event back to the current session:\n\nnext => sub {\nmy $next = shift @{ $[HEAP]->{todo} };\nreturn unless $next;\n$[KERNEL]->yield( $next );\n}\n\nOr the \"$[SESSION]\" parameter passed to every event handler, but yield() is more efficient.\n\nnext => sub {\nmy $next = shift @{ $[HEAP]->{todo} };\nreturn unless $next;\n$[KERNEL]->post( $[SESSION], $next );\n}\n\nAlong the same lines as \"$[SESSION]\", a session can respond back to the sender of an event by\nposting to \"$[SENDER]\". This is great for responding to requests.\n\nIf a program must hold onto some kind of dynamic session reference, it's recommended to use the\nsession's numeric ID rather than the object itself. A session ID may be converted back into its\nobject, but post() accepts session IDs as well as objects and aliases:\n\nmy $sessionid;\n$sessionid = POE::Session->create(\ninlinestates => {\nstart => sub {\n$[HEAP]->{todo} = [ qw( step1 step2 step2a ) ],\n$[KERNEL]->post( $sessionid, 'next' );\n},\n# ....\n}\n)->ID;\n\nAUTHORS & COPYRIGHTS\nPlease see POE for more information about authors and contributors.\n"
                    }
                ]
            }
        }
    }
}