@@ -214,8 +214,7 @@ impl<'ctx> Evaluator<'ctx> {
214214 let msg = format ! ( "pkgpath {} is not found" , current_pkgpath) ;
215215 let scopes = pkg_scopes. get_mut ( & current_pkgpath) . expect ( & msg) ;
216216 if let Some ( last) = scopes. last_mut ( ) {
217- let variables = & mut last. variables ;
218- variables. insert ( name. to_string ( ) , pointer) ;
217+ last. variables . insert ( name. to_string ( ) , pointer) ;
219218 }
220219 }
221220
@@ -349,6 +348,7 @@ impl<'ctx> Evaluator<'ctx> {
349348 /// Get the variable value named `name` from the scope, return Err when not found
350349 pub fn get_variable ( & self , name : & str ) -> ValueRef {
351350 let current_pkgpath = self . current_pkgpath ( ) ;
351+ // Use a more obvious debug marker
352352 self . get_variable_in_pkgpath ( name, & current_pkgpath)
353353 }
354354
@@ -519,10 +519,28 @@ impl<'ctx> Evaluator<'ctx> {
519519 } else {
520520 false
521521 } ;
522- if index >= last_lambda_scope && !ignore {
523- var. clone ( )
522+ // Determine if we should use the current scope value or closure value
523+ // The logic differs for schema methods vs regular lambdas:
524+ // - Schema methods: lambda level may be > execution level, need special handling
525+ // - Regular lambdas: use original logic
526+ let is_schema_method = self . current_method_receiver . borrow ( ) . is_some ( ) ;
527+ if is_schema_method {
528+ // Schema method: prefer current value if variable is in current scope
529+ // (even if it's also in the closure from previous execution)
530+ if index >= INNER_LEVEL && !ignore {
531+ // Variable is in current execution scope, use current value
532+ var. clone ( )
533+ } else {
534+ // Variable from outer scope or builtin/global, check closure
535+ lambda_ctx. closure . get ( name) . unwrap_or ( var) . clone ( )
536+ }
524537 } else {
525- lambda_ctx. closure . get ( name) . unwrap_or ( var) . clone ( )
538+ // Regular lambda: use original logic
539+ if index >= last_lambda_scope && !ignore {
540+ var. clone ( )
541+ } else {
542+ lambda_ctx. closure . get ( name) . unwrap_or ( var) . clone ( )
543+ }
526544 }
527545 } else {
528546 // Not in the lambda, maybe a local variable.
@@ -547,7 +565,9 @@ impl<'ctx> Evaluator<'ctx> {
547565 . as_ref ( )
548566 . map ( |ctx| ctx. closure . clone ( ) )
549567 . unwrap_or_default ( ) ;
550- // Get variable map including schema in the current scope.
568+
569+ // Capture all variables from scopes >= INNER_LEVEL
570+ // This is the original simple logic that works correctly for nested lambdas
551571 for i in INNER_LEVEL ..scopes. len ( ) {
552572 let variables = & scopes
553573 . get ( i)
@@ -574,12 +594,25 @@ impl<'ctx> Evaluator<'ctx> {
574594 } else {
575595 self . undefined_value ( )
576596 } ;
597+ // Track the receiver for schema method calls
598+ let mut receiver = value. clone ( ) ;
577599 for i in 0 ..names. len ( ) - 1 {
578600 let attr = names[ i + 1 ] ;
579601 if i == 0 && !pkgpath. is_empty ( ) {
580602 value = self . get_variable_in_pkgpath ( attr, pkgpath) ;
603+ receiver = value. clone ( ) ;
581604 } else {
582- value = value. load_attr ( attr)
605+ value = value. load_attr ( attr) ;
606+ // Fix: If we're loading a lambda method from a schema instance,
607+ // store the receiver so it can be used when the lambda is called
608+ // Check if this is a schema/dict method call
609+ if ( receiver. is_schema ( ) || receiver. is_dict ( ) )
610+ && value. is_func ( )
611+ && let Some ( _proxy) = value. try_get_proxy ( )
612+ {
613+ // Store the receiver for use when the lambda is called
614+ * self . current_method_receiver . borrow_mut ( ) = Some ( receiver. clone ( ) ) ;
615+ }
583616 }
584617 }
585618 value
@@ -614,11 +647,9 @@ impl<'ctx> Evaluator<'ctx> {
614647
615648 /// Load global or local value from name.
616649 pub fn load_name ( & self , name : & str ) -> ValueRef {
617- match (
618- self . is_in_schema ( ) ,
619- self . is_in_lambda ( ) ,
620- self . is_local_var ( name) ,
621- ) {
650+ let is_local = self . is_local_var ( name) ;
651+
652+ match ( self . is_in_schema ( ) , self . is_in_lambda ( ) , is_local) {
622653 // Get variable from the global lazy scope.
623654 ( false , _, false ) => {
624655 let variable = self . get_variable ( name) ;
0 commit comments