Can I instantiate an object in Dancer to return a value to display?
Asked Answered
G

1

6

I have the following code in my Dancer app module:

package Deadlands;
use Dancer ':syntax';
use Dice;

our $VERSION = '0.1';

get '/' => sub {
    my ($dieQty, $dieType);
    $dieQty = param('dieQty');
    $dieType = param('dieType');
    if (defined $dieQty && defined $dieType) {
        return Dice->new(dieType => $dieType, dieQty => $dieQty)->getStandardResult();
    }
    template 'index';
};

true;

I have a Moops class called Dice.pm that works just fine if I test it with a .pl file, but when I try to access it through the web browser, I get the following error: Can't locate object method "new" via package "Dice" (perhaps you forgot to load "Dice"?).

Can I do this with Dancer?

Here is the pertinent code from Dice.pm:

use 5.14.3;
use Moops;

class Dice 1.0 {
    has dieType => (is => 'rw', isa => Int, required => 1);
    has dieQty => (is => 'rw', isa => Int, required => 1);
    has finalResult => (is => 'rw', isa => Int, required => 0);

    method getStandardResult() {
        $self->finalResult(int(rand($self->dieType()) + 1));
        return $self->finalResult();
    }
}
Gastritis answered 11/12, 2013 at 17:48 Comment(7)
I assume you use Dice;?Rorrys
@Rorrys The error message suggests that they dont have use Dice;Whiteheaded
Use Dice is indeed at the top of the script. I updated the code to show the whole script.Gastritis
Is Dice a module that you have created? or one from CPAN?Whiteheaded
Dice.pm is a module I wrote.Gastritis
You might want to post the [relevant] code from Dice.pm.Rorrys
I have edited to show Dice.pm.Gastritis
S
3

I was going to say you forgot the package Dice in your Dice.pm, but after reading up on Moops I am confused about the namespaces.

Let's take a look at the documentation for Moops.

If you use Moops within a package other than main, then package names used within the declaration are "qualified" by that outer package, unless they contain "::". So for example:

package Quux;
use Moops;

class Foo { }       # declares Quux::Foo

class Xyzzy::Foo    # declares Xyzzy::Foo
   extends Foo { }  # ... extending Quux::Foo

class ::Baz { }     # declares Baz

If the class Dice is in Dice.pm it will actually become Dice::Dice if I read this correctly. So you would have to use Dice and create your object with Dice::Dice->new.

In order to make the package Dice within Dice.pm using Moops, I believe you need to declare the class like this:

class ::Dice 1.0 {
    #  ^------------- there are two colons here!

    has dieType => (is => 'rw', isa => Int, required => 1);
    has dieQty => (is => 'rw', isa => Int, required => 1);
    has finalResult => (is => 'rw', isa => Int, required => 0);

    method getStandardResult() {
        $self->finalResult(int(rand($self->dieType()) + 1));
        return $self->finalResult();
    }
}

You can then do:

use Dice;
Dice->new;
Spyglass answered 11/12, 2013 at 22:19 Comment(4)
I must say find this behavior a little bit strange.Spyglass
I implemented your suggestions, but alas I get the same error. Thanks for the detailed response!Gastritis
I changed your implementation, and it works! I declared the class with the double colons, but instantiated like this: Dice->newGastritis
That's what I meant you ought to do. Sorry if that was not clear. ;)Spyglass

© 2022 - 2024 — McMap. All rights reserved.