Mi duda, quizá como la gran mayoría de todas las que hice, es un tanto filosófica.
Me estaba preguntando que diferencia hay entre hacer ésto:
procedure ProcedimientoA; procedure SubProcedimientoB; begin .... end; .... begin ... // llamamos a SubProcedimientoB SubProcedimientoB; ... end;
Y esto otro:
procedure ProcedimientoA; begin ... // llamamos a SubProcedimientoB SubProcedimientoB; ... end; procedure SubProcedimientoB; begin ... end;
Es bien conocido que en la primera opción el subprocedimiento sólo es visible desde el procedimiento padre y por tanto es una buena opción cuando queremos "ocultar" parte de un proceso a los demás.
Pero por el otro lado esto no aporta demasiada claridad puesto que se pierde de vista cuando comienza y termina los subprocedimientos (sobre todo cuando son muchos y largos).
En la segunda alternativa se consigue una mejor claridad y se gana cierta independencia. Ahora bien, si se desea ocultar a este subprocedimiento nos queda la opción de sólo declararlo en la sección implementation y no darle alcance público, pero claro eso no quita que internamente dentro de la unidad se tenga alcance.
Por ello yo me pregunto, fuera de los pros y contras que he enumerado (tratando de ser lo más breve y simple posible), ¿que otras ventajas o diferencias hay entre estas opciones? ¿Afecta en algo el rendimiento de una u otra alternativa?
Podríamos discutir el tema basándonos en una muestra... Un ejemplo "claro" lo podemos ver en el método ParseSQL de la clase TParams:
function TParams.ParseSQL(SQL: String; DoCreate: Boolean): String; const Literals = ['''', '"', '`']; var Value, CurPos, StartPos: PChar; CurChar: Char; Literal: Boolean; EmbeddedLiteral: Boolean; Name: string; function NameDelimiter: Boolean; begin Result := CurChar in [' ', ',', ';', ')', #13, #10]; end; function IsLiteral: Boolean; begin Result := CurChar in Literals; end; function StripLiterals(Buffer: PChar): string; var Len: Word; TempBuf: PChar; procedure StripChar; begin if TempBuf^ in Literals then StrMove(TempBuf, TempBuf + 1, Len - 1); if TempBuf[StrLen(TempBuf) - 1] in Literals then TempBuf[StrLen(TempBuf) - 1] := #0; end; begin Len := StrLen(Buffer) + 1; TempBuf := AllocMem(Len); try StrCopy(TempBuf, Buffer); StripChar; Result := StrPas(TempBuf); finally FreeMem(TempBuf, Len); end; end; begin Result := SQL; Value := PChar(Result); if DoCreate then Clear; CurPos := Value; Literal := False; EmbeddedLiteral := False; repeat while (CurPos^ in LeadBytes) do Inc(CurPos, 2); CurChar := CurPos^; if (CurChar = ':') and not Literal and ((CurPos + 1)^ <> ':') then begin StartPos := CurPos; while (CurChar <> #0) and (Literal or not NameDelimiter) do begin Inc(CurPos); while (CurPos^ in LeadBytes) do Inc(CurPos, 2); CurChar := CurPos^; if IsLiteral then begin Literal := Literal xor True; if CurPos = StartPos + 1 then EmbeddedLiteral := True; end; end; CurPos^ := #0; if EmbeddedLiteral then begin Name := StripLiterals(StartPos + 1); EmbeddedLiteral := False; end else Name := StrPas(StartPos + 1); if DoCreate then TParam(Add).Name := Name; CurPos^ := CurChar; StartPos^ := '?'; Inc(StartPos); StrMove(StartPos, CurPos, StrLen(CurPos) + 1); CurPos := StartPos; end else if (CurChar = ':') and not Literal and ((CurPos + 1)^ = ':') then StrMove(CurPos, CurPos + 1, StrLen(CurPos) + 1) else if IsLiteral then Literal := Literal xor True; Inc(CurPos); until CurChar = #0; end;
¿No creen que las subfunciones estarían mejor como métodos privados fuera de este método?
¿Que opinan?
Saludos,