Changeset 11640 for src/Pugs/Eval

Show
Ignore:
Timestamp:
07/20/06 08:28:59 (2 years ago)
Author:
audreyt
Message:

* Resolved the method-chaining bug reported by cdpruden++:

(1 => (2 => 3)).value.value

should return 3, not "method value not found in Scalar".

It did not work because the invocant, like the rest of
arguments, were not evaluated until the multi-dispatch
finishes, which means the dispatcher only has access to
the inferred type (ScalaR) instead of the runtime type
(Pair) for the return value of the first .value call.

Now we mandate the invocant to always be evaluated in
full, and use its actual value to participate in method
lookup, as well as the possibly-multi subsequent dispatch.


However, this scheme falls crumbling down if, during
the method-fallback-to-sub step, the subroutine demands
a slurpy-context to the first positional argument
(i.e. the invocant):

sub moose (*@_) { @_ }
=$fh.moose; # reads a line; fallback to &moose;

# oops, too late to read all lines!

This issue is at this moment unresolved; currently I
choose to re-evaluate and flatten the expression if
it's a simple lookup like @foo; if it's a dynamic
evaluation (i.e. an App or Syn node), then we're
forced to reuse the item-context invocant value
(the single line read by =$fh in the example above)
as the argument to &moose.


Better suggestions welcome...

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • src/Pugs/Eval/Var.hs

    r11289 r11640  
    155155            typ     <- evalInvType $ unwrap exp 
    156156            if typ == mkType "Scalar::Perl5" then fmap (err $ NoSuchMethod $ show typ) (runPerl5Sub name) else do 
    157             findTypedSub typ name 
    158         _ | [exp] <- args -> do 
    159             typ     <- evalInvType $ unwrap exp 
    160157            findTypedSub typ name 
    161158        _ -> findBuiltinSub NoSuchSub name