Re: 클래스 정의 내에서 "this"에 메시지 전달기본적으로 JMP는 유사 네임스페이스(window, this, box 등)를 직접 쿼리할 수 있는 좋은 방법을 제공하지 않습니다.
클래스의 경우 클래스를 구성하기 위한 래퍼를 만드는 것에 대해 생각할 수 있습니다. 그러면 래퍼가 인스턴스 생성기 함수를 만들 수 있고 해당 인스턴스 생성 중에 클래스에 순환 참조를 제공할 수 있습니다(이로 인해 메모리 누수가 발생할 수 있음). -- 순환 참조 등을 제거하기 위해 클래스를 삭제해야 할 때 추적 시스템을 만들고 삭제자 메서드를 제공/호출해야 합니다.
예를 들면 다음과 같습니다.
Names Default to Here( 1 );
New Namespace( "class" );
class:Get Init Args = Function( {_class},
{Default Local},
For( i = 1, i <= N Items( _class ), i++,
If( Head Name( Arg( _class, i ) ) == "Glue",
For( j = 1, j <= N Arg( Arg( _class, i ) ), j++,
If( As Name( Head Name( Arg( Arg( Arg( _class, i ), j ), 1 ) ) ) == As Name( "_create_" ),
Return( Arg( Arg( Arg( Arg( _class, i ), j ), 2 ), 1 ) )
)
)
)
);
Return( {} )
);
class:Define Class = Function( {_class},
{Default Local},
class = Expr( Define Class() );
Summation( i = 1, N Arg( _class ),
Insert Into( class, Arg( _class, i ) )
);
init args = class:Get Init Args( _class );
init redirects = Expr( __cl:_create_() );
Summation( i = 1, N Items( init args ),
If( Head Name( Arg( init args, i ) ) == "Assign",
Insert Into( init redirects, Eval Expr( Name Expr( Expr( Arg( Arg( init args, i ), 1 ) ) ) ) )
,
Insert Into( init redirects, Eval Expr( Name Expr( Expr( Arg( init args, i ) ) ) ) )
)
);
Eval( class );
ns = Namespace( "class" );
Eval( Substitute( Expr(
ns[__class__] = Function( __args__,
{__cl = New Object( __class__ )},
__cl:self = __cl;
__class_call__;
__cl
)
),
Expr( __class__ ), Arg( _class, 1 ),
Expr( __args__ ), init args,
Expr( __class_call__ ), Name Expr( init redirects )
) );
0
);
class:Define Class({
"example",
_init_ = Method( {}, 1 );
_create_ = Method( {assocArray},
For Each( {{key, setter}, _}, assocArray,
self << Insert( key, Eval Expr( Method( {value}, self:TrySetProperty( Expr( key ), value, Expr( setter ) ) ) ) )
)
);
Try Set Property = Method( {parameter, value, expression If Changed},
Match( value,
., ., //Do nothing if missing value
,
self[parameter], . //Do nothing if unchanged value
,
self[paremeter] = value; //Otherwise update the value
Eval( expression If Changed ); //and eval the expression
);
);
show = Function( {name},
show( name )
)
});
//show( namespace( "class" ) );
cls = class:example( ["A" => expr( self:show( "EXPLETIVE" ) ), "B" => Expr( thing 2 )] );
show( cls << get keys );하지만 JMP 클래스는 함수가 첨부된 미화된 네임스페이스일 뿐입니다(첨부된 함수가 자신이 속한 네임스페이스를 인식하는 네임스페이스).일반 네임스페이스와 메타 프로그래밍만으로 매우 유사한 작업을 수행할 수 있습니다.그리고 일반 네임스페이스를 사용하면 JMP는 함수 등에서 클래스 메서드에 액세스할 수 없다는 불필요한 오류를 발생시키지 않습니다.
클래스 정의 내에서 "this"에 메시지 전달메서드 내에서 클래스의 인스턴스로 메시지를 전달할 수 있습니까?
다음은 내가하려는 작업의 예입니다.
Define Class(
"example",
x=1;
test = Method( {name, method},
<< Insert(name, method);
);
);
t = New Object( example());
// This fails to insert the blah method
t:test("blah", Method({y}, show("Blah " || char(x) || char(y))));
t:blah(6);
//This succeeds in inserting and calling the blah method
t << Insert("blah", Method({y}, show("Blah " || char(x) || char(y))));
t:blah(6);"this << Insert"를 명시적으로 작성해야 할 수도 있다고 생각했지만 다른 오류가 발생했습니다.
Define Class(
"example",
x=1;
test = Method( {name, method},
<STRONG>this << Insert(name, method);</STRONG>
);
);
t = New Object( example());
// This fails because "send expects scriptable object"
t:test("blah", Method({y}, show("Blah " || char(x) || char(y));));
t:blah(6);또한 명시적으로 Send(메서드 추가 실패) 및 this:Send(Send 이름을 확인하지 못함)를 호출하는 것도 고려했습니다.
또한 이것을 직접 호출하는 것도 고려했습니다. 삽입(Insert라는 이름을 확인하지 못함) 및 삽입(blah 메서드를 성공적으로 추가했지만 호출 메커니즘을 올바르게 연결하지 못하여 메서드에 인수가 전달되지 않음).
동기 부여:
클래스 속성 목록에 대해 getter 및 setter 메서드를 자동으로 생성하려고 하기 때문에 이 작업을 수행하고 있습니다.이상적으로는 다음을 수행할 수 있습니다.
Define Class(
"example",
_init_ = Method( {assocArray},
For Each({property, updateMethod}, assocArray,
Insert(key, Eval Expr(Method({value}, TrySetProperty(Expr(property), value, Expr(updateMethod)))));
);
);
TrySetProperty=Method({parameter, value, expressionIfChanged},
match(value,
., ., //Do nothing if missing value
this << Get Value(parameter), ., //Do nothing if unchanged value
this << Insert(parameter, value); //Otherwise update the value
Eval(expressionIfChanged); //and eval the expression
);
);
);
properties = Associative Array({{"prop1", Expr(ThingToDoOnUpdate1)},{"prop2", Expr(ThingToDoOnUpdate2)}});
t = New Object( example(properties));
고급 통계 모델링자동화 및 스크립팅품질 및 프로세스 엔지니어링Re: 클래스 정의 내에서 "this"에 메시지 전달이것은 JSL이 수행하도록 강제하는 일종의 해결 방법인 것 같습니다.
프로그래밍 패러다임을 조롱하는 "DreamBerd"라는 패러디 프로그래밍 언어가 있습니다.이 해결 방법은 패러디 언어가 클래스를 처리하는 방법과 매우 유사하지만 훨씬 더 복잡합니다.
(이것이 귀하의 잘못이라고 말하는 것이 아니라 JSL의 제한 사항의 결과일 뿐입니다.)
https://github.com/TodePond/DreamBerd
클래스클래스를 만들 수 있지만 클래스의 인스턴스는 하나만 만들 수 있습니다. 이것은 대부분의 객체 지향 프로그래머가 작업하는 방식에 영향을 미치지 않아야 합니다.
class Player {
const var health = 10!
}
const var player1 = new Player()!
const var player2 = new Player()! //Error: Can't have more than one 'Player' instance!다음과 같이 할 수 있습니다.
class PlayerMaker {
function makePlayer() => {
class Player {
const var health = 10!
}
const const player = new Player()!
return player!
}
}
const const playerMaker = new PlayerMaker()!
const var player1 = playerMaker.makePlayer()!
const var player2 = playerMaker.makePlayer()!
Re: 클래스 정의 내에서 "this"에 메시지 전달맞춤 메시지 전달로 더 잘 처리할 수 있다고 생각하지만 실제로 그렇게 하는 방법에 대한 문서를 찾을 수 없습니다.내가 알 수 있는 한, 자신의 메시지를 구현하는 방법에 대한 정보는 없습니다.
Re: 클래스 정의 내에서 "this"에 메시지 전달메시지는 클래스에 대한 메서드를 호출합니다. 기술적으로 메시지를 통해 인수가 있는 함수를 호출할 수 없지만 JSL 클래스의 메서드는 표현식이므로 메시지 호출의 결과는 호출 가능한 함수입니다.모든 의도와 목적을 위해 메시지를 통해 클래스 메서드를 호출할 수 있습니다.
줄을 확인 표시( clx << 추가( cly ) ); 호출 추가하다 메시지를 통한 방법.
Names Default To Here( 1 );
Define Class(
"complex",
real = 0;
imag = 0;
_init_ = Method( {a, b},
real = a;
imag = b;
);
Add = Method( {y},
PRINT( "ADDING" );
New Object( complex( real + y:real, imag + y:imag ) )
);
Sub = Method( {y},
New Object( complex( real - y:real, imag - y:imag ) )
);
Mul = Method( {y},
New Object( complex( real * y:real - imag * y:imag, imag * y:real + real * y:imag ) )
);
Div = Method( {y},
t = New Object( complex( 0, 0 ) );
mag2 = y:Magsq();
t:real = real * y:real + imag * y:imag;
t:imag = imag * y:real + real * y:imag;
t:real = t:real / mag2;
t:imag = t:imag / mag2;
t;
);
Magsq = Method( {},
real * real + imag * imag
);
Mag = Method( {},
Sqrt( real * real + imag * imag )
);
_to string_ = Method( {},
Char( real ) || " + " || Char( imag ) || "i"
);
_show_ = _to string_;
);
clx = New Object( complex( 1, 2 ) );
cly = New Object( complex( 2, 3 ) );
Show( clx << Add( cly ) );
clx << Delete;
cly << Delete;
Delete Classes( "complex" );Re: 클래스 정의 내에서 "this"에 메시지 전달나는 JSL이 최고로부터 차용하는 동안(이 경우 스몰토크에서 전달되는 메시지 ) 원본의 특별한 점을 포착하지 못합니다.