Cursing my objects?

E

Eduardo

Hello, I want to have a subclass of Class::DBI which can manage its
own HTML editing form.
I would create an instance from this class and have it yield its form
with default values. This is probably a mess among data
storage/presentation, which is the proper way to go about it?
The examples in FormBuilder's docs always show the values coming from
queries, or from other objects (typically an $sth result), but I want
something like:

my $t = MyApp::MyTable->retrieve(something); # a Class::DBI
descendant
my $form = $t->form;
print $form->render(values => $t);

However, the values() method as applied by render() seems to require
'a hashref or an object'. I am evidently getting something wrong on
the object side, as I need to access the blessed data inside $t
instead of $t proper. This seems rather quirky. Should I be getting
the values hashref from $t before the call to render? How? I've seen
an ACME::Damn module, is this pure nonsense? What's the recommended
approach?
Thanks in advance!

--Very confused
 
B

Ben Morrow

Hello, I want to have a subclass of Class::DBI which can manage its
own HTML editing form.
I would create an instance from this class and have it yield its form
with default values. This is probably a mess among data
storage/presentation, which is the proper way to go about it?
The examples in FormBuilder's docs always show the values coming from
queries, or from other objects (typically an $sth result), but I want
something like:

my $t = MyApp::MyTable->retrieve(something); # a Class::DBI
descendant
my $form = $t->form;
print $form->render(values => $t);

However, the values() method as applied by render() seems to require
'a hashref or an object'. I am evidently getting something wrong on
the object side, as I need to access the blessed data inside $t
instead of $t proper. This seems rather quirky. Should I be getting
the values hashref from $t before the call to render? How? I've seen
an ACME::Damn module, is this pure nonsense? What's the recommended
approach?

The OO-recommended approach is to give $t a method, say as_hashref,
that returns an unblessed copy of the data like this:

sub as_hashref {
my $s = shift;
return { %$s };
}

and then use

print $form->render(values => $t->as_hashref);

Then you can redo as_hashref if your implementation changes. If you
aren't bothered about breaking OO encapsulation (essentially, if you
don't mind making the fact that $t is a ref to a blessed hash part of
the published interface) then you can simply use

print $form->render(values => { %$t });

..

Ben
 
E

Eduardo

The OO-recommended approach is to give $t a method, say as_hashref,
that returns an unblessed copy of the data like this:

sub as_hashref {
my $s = shift;
return { %$s };
}
G R E A T ! ! ! ! ! !
For the life of me, I couldn't get that syntax. I had tried
$form->render(%$t), but omitted the curly brackets. By the way, I
still don't catch why I need them.
I owe you 5 terathanks anyway!
 
B

Ben Morrow

For the life of me, I couldn't get that syntax. I had tried
$form->render(%$t), but omitted the curly brackets. By the way, I
still don't catch why I need them.

$t is a reference to a blessed hash.

my %h = (k => "v");
my $t = bless \%h, "My::pack";

%$t derefs that ref, which in list context will return a list of
interleaved keys and values. So %$t, in list context, is

("k", "v")

.. Now, $form->render takes a list of parameters, and the value for the
'values' parameter should be a hashref. What you want to acheive is

$form->render(values => \%h);
or $form->render("values", \%h);
or $form->render("values", { "k", "v" });

Remember that {} is the anonymous hasref constructor. If you write
$form->render(%$t), this will give you $form->render("k", "v"), which
is quite wrong; if you write $form->render(values => $t) you get

$form->render( bless { k => "v" }, "My::pack" );

which is also wrong. $form->render(values => { %$t }), though, derefs
$t and returns the list, and then creates a new anonymous unblessed
hashref out of that list. That is what I meant when I said 'an
unblessed copy of the data'.

Clearer now? :)

Ben
 
A

Anno Siegel

Ben Morrow said:
(e-mail address removed) (Eduardo) wrote:

[how to access a blessed hashref as a hash]
The OO-recommended approach is to give $t a method, say as_hashref,
that returns an unblessed copy of the data like this:

sub as_hashref {
my $s = shift;
return { %$s };
}

and then use

print $form->render(values => $t->as_hashref);

Then you can redo as_hashref if your implementation changes. If you
aren't bothered about breaking OO encapsulation (essentially, if you
don't mind making the fact that $t is a ref to a blessed hash part of
the published interface) then you can simply use

print $form->render(values => { %$t });

This doesn't break encapsulation as badly as it seems to. If the
implementation changes and object isn't a hashref anymore, you can
always overload "%{}" to restore the behavior of "%$t". It gets
cumbersome when the object remains a hashref, but the contents change
so that "%$t" isn't usable in the old way any longer, but that can be
worked around too.

Anno
 
E

Eduardo

This doesn't break encapsulation as badly as it seems to. If the
implementation changes and object isn't a hashref anymore, you can
always overload "%{}" to restore the behavior of "%$t". It gets
cumbersome when the object remains a hashref, but the contents change
so that "%$t" isn't usable in the old way any longer, but that can be
worked around too.
Thank you! I am really amazed at your explanations, people. How would
I go about overloading %{}?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,145
Messages
2,570,826
Members
47,372
Latest member
LucretiaFo

Latest Threads

Top