Skip to content

tied variable in void context doesn't call FETCH #20

@fglock

Description

@fglock

Summary

When accessing a tied hash/array element in void context, PerlOnJava incorrectly optimizes out the variable access, preventing the tied object's FETCH method from being called. This breaks the expected Perl semantics where tied variable access should always trigger the appropriate tie methods regardless of context.

Expected Behavior

In standard Perl, accessing a tied variable should always call the corresponding tie method (FETCH, STORE, etc.), even when the result is not used (void context). This is because tied variables are designed to have side effects, and these side effects are part of the intended behavior.

Actual Behavior

PerlOnJava optimizes out the variable access when it detects the result isn't being used, preventing the FETCH method from being called entirely.

Reproduction Case

package BrokenTiedHash;
sub TIEHASH { bless {}, shift }
sub FETCH { die "FETCH died" }
sub STORE { die "STORE died" }
sub EXISTS { die "EXISTS died" }

package main;
my %hash;
tie %hash, 'BrokenTiedHash';

# This should call FETCH and die with "FETCH died"
# but gets optimized out in PerlOnJava
eval { $hash{key}; };

Impact

This optimization breaks:

  1. Side effects: Tied variables often perform logging, caching, database operations, or other side effects in their FETCH methods
  2. Error handling: Code that expects exceptions from tie methods won't see them
  3. Perl compatibility: Code that works correctly in standard Perl fails silently in PerlOnJava
  4. Debugging: Developers may not realize their tied object methods aren't being called

Technical Details

The issue appears to be in PerlOnJava's optimizer which incorrectly assumes that variable access in void context has no side effects. However, tied variables are specifically designed to have side effects through their tie methods, making this optimization semantically incorrect.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions