2
#!/usr/bin/perl

my $obj = bless do { \( my $scalar = 123; ) }, 'Some::Class';

How can I get the $scalar value using $obj?

I had tried it in many ways, but no success.

toolic
  • 57,801
  • 17
  • 75
  • 117

3 Answers3

6

This isn't a blessed block of code. It's a blessed reference to a scalar.

You can get the value '123' using:

$$obj
tobyink
  • 13,478
  • 1
  • 23
  • 35
3

@tobyink already gave you the answer with $$obj. There is also an alternative $obj->$* with newer Perl versions.

But these are hacks circumventing privacy, you should first look into Some::Class if it provides some ->getter method.

Explanation to this "unusual" syntax:

my $obj = bless do { \( my $scalar = 123) }, 'Some::Class';

Perl can bless all kinds of references, like {...} or [...].

One normally sees (IMHO in 99% of the cases) blessed hashes, like

my $obj = bless { key => val, ... }, 'Some::Class';

But there is no anonymous constructor syntax for scalar refs, that's especially cumbersome when serializing objects.

Now do { \( my $dummy = 123 ; ) } does the trick to return a ref to a mutable scalar and the temporary symbol $dummy is in the lexical scope of do and can't pollute the namespaces.

The \(...) is just a shorter syntax, one could also write do { my $d = 123; \$d }

NB: Yes, one could also just use \123 directly but this would be immutable because literals are constant, and rarely of use in objects.

LanX
  • 478
  • 3
  • 10
3

Dereferencing a scalar can be done using the $BLOCK syntax or the EXPR->$* syntax.

my $val = ${ $obj };

my $val = $$obj;       # Curlies can be omitted in this case.

my $val = $obj->$*;

See Perl Dereferencing Syntax.

ikegami
  • 367,544
  • 15
  • 269
  • 518