@@ -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,7 +348,9 @@ 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 ( ) ;
352- self . get_variable_in_pkgpath ( name, & current_pkgpath)
351+ // Use a more obvious debug marker
352+ let result = self . get_variable_in_pkgpath ( name, & current_pkgpath) ;
353+ result
353354 }
354355
355356 /// Get the variable value named `name` from the scope, return Err when not found
@@ -519,10 +520,28 @@ impl<'ctx> Evaluator<'ctx> {
519520 } else {
520521 false
521522 } ;
522- if index >= last_lambda_scope && !ignore {
523- var. clone ( )
523+ // Determine if we should use the current scope value or closure value
524+ // The logic differs for schema methods vs regular lambdas:
525+ // - Schema methods: lambda level may be > execution level, need special handling
526+ // - Regular lambdas: use original logic
527+ let is_schema_method = self . current_method_receiver . borrow ( ) . is_some ( ) ;
528+ if is_schema_method {
529+ // Schema method: prefer current value if variable is in current scope
530+ // (even if it's also in the closure from previous execution)
531+ if index >= INNER_LEVEL && !ignore {
532+ // Variable is in current execution scope, use current value
533+ var. clone ( )
534+ } else {
535+ // Variable from outer scope or builtin/global, check closure
536+ lambda_ctx. closure . get ( name) . unwrap_or ( var) . clone ( )
537+ }
524538 } else {
525- lambda_ctx. closure . get ( name) . unwrap_or ( var) . clone ( )
539+ // Regular lambda: use original logic
540+ if index >= last_lambda_scope && !ignore {
541+ var. clone ( )
542+ } else {
543+ lambda_ctx. closure . get ( name) . unwrap_or ( var) . clone ( )
544+ }
526545 }
527546 } else {
528547 // Not in the lambda, maybe a local variable.
@@ -547,7 +566,9 @@ impl<'ctx> Evaluator<'ctx> {
547566 . as_ref ( )
548567 . map ( |ctx| ctx. closure . clone ( ) )
549568 . unwrap_or_default ( ) ;
550- // Get variable map including schema in the current scope.
569+
570+ // Capture all variables from scopes >= INNER_LEVEL
571+ // This is the original simple logic that works correctly for nested lambdas
551572 for i in INNER_LEVEL ..scopes. len ( ) {
552573 let variables = & scopes
553574 . get ( i)
@@ -574,12 +595,26 @@ impl<'ctx> Evaluator<'ctx> {
574595 } else {
575596 self . undefined_value ( )
576597 } ;
598+ // Track the receiver for schema method calls
599+ let mut receiver = value. clone ( ) ;
577600 for i in 0 ..names. len ( ) - 1 {
578601 let attr = names[ i + 1 ] ;
579602 if i == 0 && !pkgpath. is_empty ( ) {
580603 value = self . get_variable_in_pkgpath ( attr, pkgpath) ;
604+ receiver = value. clone ( ) ;
581605 } else {
582- value = value. load_attr ( attr)
606+ value = value. load_attr ( attr) ;
607+ // Fix: If we're loading a lambda method from a schema instance,
608+ // store the receiver so it can be used when the lambda is called
609+ if true {
610+ // Check if this is a schema/dict method call
611+ if ( receiver. is_schema ( ) || receiver. is_dict ( ) ) && value. is_func ( ) {
612+ if let Some ( _proxy) = value. try_get_proxy ( ) {
613+ // Store the receiver for use when the lambda is called
614+ * self . current_method_receiver . borrow_mut ( ) = Some ( receiver. clone ( ) ) ;
615+ }
616+ }
617+ }
583618 }
584619 }
585620 value
@@ -614,11 +649,8 @@ impl<'ctx> Evaluator<'ctx> {
614649
615650 /// Load global or local value from name.
616651 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- ) {
652+ let is_local = self . is_local_var ( name) ;
653+ let result = match ( self . is_in_schema ( ) , self . is_in_lambda ( ) , is_local) {
622654 // Get variable from the global lazy scope.
623655 ( false , _, false ) => {
624656 let variable = self . get_variable ( name) ;
@@ -689,7 +721,9 @@ impl<'ctx> Evaluator<'ctx> {
689721 _ => self . get_variable_in_schema_or_rule ( name) ,
690722 }
691723 }
692- }
724+ } ;
725+
726+ result
693727 }
694728
695729 /// Load assignment target value.
0 commit comments