diff --git a/src/main/java/org/perlonjava/core/Configuration.java b/src/main/java/org/perlonjava/core/Configuration.java index 3b20f5ed9..4412a9eb9 100644 --- a/src/main/java/org/perlonjava/core/Configuration.java +++ b/src/main/java/org/perlonjava/core/Configuration.java @@ -33,7 +33,7 @@ public final class Configuration { * Automatically populated by Gradle/Maven during build. * DO NOT EDIT MANUALLY - this value is replaced at build time. */ - public static final String gitCommitId = "f8e0a8fc1"; + public static final String gitCommitId = "ef6eaab61"; /** * Git commit date of the build (ISO format: YYYY-MM-DD). @@ -48,7 +48,7 @@ public final class Configuration { * Parsed by App::perlbrew and other tools via: perl -V | grep "Compiled at" * DO NOT EDIT MANUALLY - this value is replaced at build time. */ - public static final String buildTimestamp = "Apr 21 2026 11:24:02"; + public static final String buildTimestamp = "Apr 21 2026 11:56:14"; // Prevent instantiation private Configuration() { diff --git a/src/main/java/org/perlonjava/runtime/perlmodule/FilterUtilCall.java b/src/main/java/org/perlonjava/runtime/perlmodule/FilterUtilCall.java index 4db2f5fb5..a21fc7b44 100644 --- a/src/main/java/org/perlonjava/runtime/perlmodule/FilterUtilCall.java +++ b/src/main/java/org/perlonjava/runtime/perlmodule/FilterUtilCall.java @@ -179,11 +179,8 @@ public static RuntimeList filter_read(RuntimeArray args, int ctx) { block.append(line); bytesRead += line.length(); context.currentLine++; - - // Check if line ends with newline to stop - if (line.endsWith("\n")) { - break; - } + // In block mode, keep reading until we hit blockSize or EOF. + // Do NOT stop on newlines — that's line mode. } else { // Partial line read int remaining = blockSize - bytesRead; @@ -332,11 +329,43 @@ public static String applyFilters(String sourceCode) { GlobalVariable.getGlobalVariable("main::_").set(""); } } else { - // Method filter: call the filter() method on the object - // String filterMethod = packageName.toString() + "::filter"; - // TODO: Implement method filter calling - // For now, just return the original source - return sourceCode; + // Method filter: call the "filter" method on the blessed filter object + // repeatedly until it returns a non-positive status. + String pkg = packageName.toString(); + RuntimeScalar method = org.perlonjava.runtime.mro.InheritanceResolver + .findMethodInHierarchy("filter", pkg, null, 0); + if (method == null || method.type != org.perlonjava.runtime.runtimetypes.RuntimeScalarType.CODE) { + if (debug) { + System.err.println("[FILTER] No filter() method found in " + pkg + + "; returning source unchanged"); + } + return sourceCode; + } + RuntimeCode code = (RuntimeCode) method.value; + boolean continueFiltering = true; + while (continueFiltering) { + // Call $obj->filter (pass $self as first arg) + RuntimeArray callArgs = new RuntimeArray(); + callArgs.push(filterObj); + RuntimeBase result = code.apply(callArgs, RuntimeContextType.SCALAR); + + String chunk = GlobalVariable.getGlobalVariable("main::_").toString(); + if (!chunk.isEmpty()) { + filteredCode.append(chunk); + if (debug) { + System.err.println("[FILTER] Method filter chunk: " + chunk); + } + } + + int status = result.scalar().getInt(); + if (debug) { + System.err.println("[FILTER] Method filter status: " + status); + } + if (status <= 0) { + continueFiltering = false; + } + GlobalVariable.getGlobalVariable("main::_").set(""); + } } }