Though, if you need this functionality over multiple namespaces
I'd suggest to use a Language Extension:
#1 an .inc for the the code definition in namespace %SYS
 

ROUTINE ZZFIX [Type=INC]
/// fix length string + padding + l/r-adjustment
ZZFIX(%val, len , pad = "", right = 0)
        if right quit $e($tr($j("",len)," ",$e(pad_" "))_%val,*+1-len,*)
        quit $e(%val_$tr($j("",len)," ",$E(pad_" ")),1,len)

#2 add this line to %ZLANGF00.mac

#include ZZFIX 

after compiling it you may run a test in any namespace

USER>set test="213abc"
USER>write $ZZFIX(test,10,"*")
213abc****
USER>write $ZZFIX(test,10,"*",1)
****213abc
USER>write $zzfix(test,5,"*",1)
13abc
USER>write $zzfix(test,15,"$")
213abc$$$$$$$$$
USER>write $zzfix(test,15,"$",1)
$$$$$$$$$213abc
USER>

If available this could of course also replace the
ClassMethod in the DataType definition.
It's a matter of taste.

Thank you @Jeffrey Drumm !

Yet another idea:
Sometimes you may want a static non-blank padding character.
e.g. ****123 or 345~~~~
this is included as Parameter PADCHAR as %String =" "  ;  default= blank

/// padding other than " " might be useful in some cases
Class rcc.GetFixSqlPad Extends %Library.String
{

Parameter LENGTH As %String = 10;

Parameter ALIGN As %String = "LEFT";

Parameter PADCHAR As %String = "";

Method Get() As %String [ CodeMode = generator, ServerOnly = 1 ]
{
    set code=+%parameter("LENGTH")_","""_$E(%parameter("PADCHAR")_" ",1)_""""
    set code=code_","_("RIGHT"=$zcvt(%parameter("ALIGN"),"U"))_")"
        
    $$$GENERATE(" quit ##class(rcc.GetFixSqlPad).Fix(%val,"_code )
    QUIT $$$OK
}

ClassMethod StorageToLogical(%val As %String) As %String [ CodeMode = generator, ServerOnly = 1 ]
{
    set code=+%parameter("LENGTH")_","""_$E(%parameter("PADCHAR")_" ",1)_""""
    set code=code_","_("RIGHT"=$zcvt(%parameter("ALIGN"),"U"))_")"
        
    $$$GENERATE(" quit ##class(rcc.GetFixSqlPad).Fix(%val,"_code )
    QUIT $$$OK
}

/// PADCHAR=" "; LEFT=0, RIGHT=1 
ClassMethod Fix(%val, rcc, rccp = "", rccal = 0) As %String
{
    if rccal{
        set %val=$e($tr($j("",rcc)," ",$e(rccp_" "))_%val,*+1-rcc,*)
        }
    else {
        set %val=$e(%val_$tr($j("",rcc)," ",$e(rccp_" ")),1,rcc)
        }	
    quit %val
}

}

This doesn't work for SQL - Therefore a new version
 

Class rcc.GetFixSql Extends %Library.String
{

Parameter LENGTH As %String = 10;
Parameter ALIGN As %String = "LEFT";
Method Get() As %String [ CodeMode = generator, ServerOnly = 1 ]
{
    set code=+%parameter("LENGTH")_","_("RIGHT"=$zcvt(%parameter("ALIGN"),"U"))_")"
    $$$GENERATE(" quit ##class(rcc.GetFixSql).Fix(%val,"_code )
    QUIT $$$OK
}

ClassMethod LogicalToDisplay(%val As %String) As %String [ CodeMode = generator, ServerOnly = 0 ]
{
    set code=+%parameter("LENGTH")_","_("RIGHT"=$zcvt(%parameter("ALIGN"),"U"))_")"
    $$$GENERATE(" quit ##class(rcc.GetFixSql).Fix(%val,"_code )
    QUIT $$$OK
}

ClassMethod LogicalToOdbc(%val As %String) As %String [ CodeMode = generator, ServerOnly = 1 ]
{
    set code=+%parameter("LENGTH")_","_("RIGHT"=$zcvt(%parameter("ALIGN"),"U"))_")"
    $$$GENERATE(" quit ##class(rcc.GetFixSql).Fix(%val,"_code )
    QUIT $$$OK
}

// only required for SQL Display Logical mode !
ClassMethod StorageToLogical(%val As %String) As %String [ CodeMode = generator, ServerOnly = 1 ]
{
    set code=+%parameter("LENGTH")_","_("RIGHT"=$zcvt(%parameter("ALIGN"),"U"))_")"
    $$$GENERATE(" quit ##class(rcc.GetFixSql).Fix(%val,"_code )
    QUIT $$$OK
}

/// LEFT=0, RIGHT=1 
ClassMethod Fix(%val, rcc, rccal = 0) As %String
{
    if rccal{
        set %val=$e($j(%val,rcc),*+1-rcc,*)
        }
    else {
        set %val=$e(%val_$j("",rcc),1,rcc)
        }	
    quit %val
}

}

A more compact data type with LENGTH and ALIGN
For RIGHT alignment I cut off oversized data by LENGHT counted from the end.
 

Class rcc.GetFixAligned Extends %Library.String
{
Parameter LENGTH As %String = 10;
Parameter ALIGN As %String = "LEFT";

Method Get() As %String [ CodeMode = generator, ServerOnly = 1 ]
{
    set rcc=+%parameter("LENGTH")
    if "RIGHT"=$zcvt(%parameter("ALIGN"),"U") {
        set code="$e($j(%val,"_rcc_"),*+1-"_rcc_",*)"
        }
    else {
        set code="$e(%val_$j("""","_rcc_"),1,"_rcc_")"
        }	
    $$$GENERATE(" Quit "_code)
    QUIT $$$OK
}
}

by extending %RegisteredObject you lost the basic data type
and all other parameters of %String
this should do it:

Class rcc.FixStr Extends (%Library.String, rcc.FixStr.Props)
{
/// Fill value according to LENGTH parameter
Method Get() As %String [ CodeMode = generator, ServerOnly = 1 ]
{
	set tCode="$e(%val_"""_$j("",+%parameter("LENGTH"))
	set tCode=tCode_""",1,"_+%parameter("LENGTH")_")"
	$$$GENERATE( "  Quit "_tCode)
	QUIT $$$OK
}
}

Big THANK YOU @Jani Hurskainen for sharing your story.
I'm impressed by the progress you made on ObjectScript
after only 1,5 years maybe 30% of working time,

AoC examples are definitely different from the target cases ObjectScript was designed for.
Its top target is the underlaying database, string manipulation and less math functionality.

My best wishes for Health and Success  for the New Year
Robert

Thank you @Evgeny Shvarov !
I'd like to underline especially the use of  Docker.

My hundreds reviews in OEX wouldn't be possible without it with my limited test environment.
It's not only the option to run various  versions in parallel to my personal setup,
but much more the possibility to clean out all traces and specific settings just with a click.

If you ever tried to remove COMPLETELY an IRIS installation with all traces
from Windows you may understand me.

And with the available templates it is a really easy exercise to compose
your personal customized package with almost no effort and
test it over and over from scratch.


​​​​​​

Suggestion:
you crate your own stored procedure to decide during SELECT
example:

/// Return NEW for first occurance of item 
/// otherwise return OLD
Class User.ItemStat Extends %RegisteredObject
{
ClassMethod NewOld(item As %String = "") As %String [ SqlProc ]
{
    if item="" quit "?"
    if $d(^||list(item)) quit "OLD"
    if $i(^||list(item)) quit "NEW"
}
}

How to use it:

SELECT *, ItemStat_NewOld(item) as Status
FROM items order by 2

Result:

ID	date	  item	Status
1	09/13/1932	A	NEW
2	04/06/1933	D	NEW
10	06/15/1940	A	OLD
4	11/26/1940	A	OLD
6	02/19/1956	B	NEW
8	04/22/1957	D	OLD
7	05/01/1959	D	OLD
9	06/29/1961		?
3	07/04/1992	B	OLD
5	12/08/2020	D	OLD