如何在Squeak(Smalltalk)中用正则表达式检查方法参数数量?
Got it, let's break this down for your compile:where: method. In Squeak, working with regular expressions to count those parameter colon patterns (like first:) is straightforward once you know the right tools—here's a step-by-step solution tailored to your needs:
1. Squeak正则表达式基础
Squeak uses its own regex engine, centered around the RxParser class. For your use case, we'll compile a regex pattern that matches parameter names followed by a colon, then count how many times it appears in your input string.
2. 实现参数数量统计与验证
First, let's write the code to count the parameters and check if their count matches the argTypeCollection size. Here's how to integrate this into your method:
compile: stringCode where: argTypeCollection | paramPattern signaturePart matches paramCount | "Compile the regex pattern to match parameter names (e.g., first:, second:)" paramPattern := RxParser parse: '[a-zA-Z][a-zA-Z0-9]*:'. "Extract only the method signature part (before the first |) to avoid matching method body patterns" signaturePart := stringCode copyUpTo: $|. "Find all matches of the parameter pattern in the signature" matches := paramPattern matchesIn: signaturePart. paramCount := matches size. "Validate parameter count matches the type collection size" paramCount = argTypeCollection size ifFalse: [ self error: ('Parameter count mismatch: expected {1}, got {2}' format: {argTypeCollection size. paramCount}) ]. "Add your further analysis/compilation logic here..."
关键细节说明:
- Regex Pattern:
[a-zA-Z][a-zA-Z0-9]*:matches any sequence starting with a letter, followed by any combination of letters/numbers, ending with a colon—exactly the format of your method parameters. - Signature Extraction: By using
copyUpTo: $|, we only check the part of the string before the first vertical bar, which ensures we don't accidentally match similar patterns in the method's local variables or body. - Counting Matches:
matchesIn:returns a collection of all matching substrings, somatches sizegives us the exact number of parameters.
3. 测试你的示例
Using your sample input:
C compile: 'first: i second: any third: n | local | local := i + n. ^(local*local)' where: #(Integer nil Number)
The code will extract 'first: i second: any third: n ' as the signature part, find 3 matches (first:, second:, third:), and confirm this matches the size of #(Integer nil Number) (3), so it proceeds without error.
内容的提问来源于stack exchange,提问作者Guy Sadoun

