답변:
귀하의 질문은 명확하지 않지만 관찰자 패턴은 당신이 찾고있는 것 같습니다 http://en.wikipedia.org/wiki/Observer_pattern
구문 현명한, 꽤 많은 언어에는 when키워드가 있지만 설명하는 방식으로 사용하는 언어는 알지 못합니다.
'X가 발생하면 Y를 수행'패턴은 종횡비 프로그래밍의 핵심입니다. 선형 흐름을 정의하는 대신 핸들러를 특정 조건 (일명 '이벤트'에 가입)에 연결합니다. 이러한 종류의 프로그래밍은 프로그램의 핵심 루틴이 이벤트 디스패처 인 GUI 응용 프로그램에서 널리 사용됩니다.
일부 언어에는 언어 구문을 통해 이러한 메커니즘을 제공하는 광범위한 구문 기능이 있습니다. 예를 들어 델리게이트와 이벤트가있는 C #이 있습니다.
// 'when btnOK is clicked, run HandleOKClick'
btnOK.Clicked += this.HandleOKClick;
다른 언어는 OOP 구조 (Observer 패턴, 이벤트 리스너 등)를 사용합니다 .Java의 예 (내 Java는 약간 녹슨 편이므로 자유롭게 편집하십시오) :
Foobar f = this;
btnOK.registerClickHandler(
new ClickHandler {
public void handleClick(Event e) {
f.handleOKClick(e);
}
});
또 다른 접근법은 평범한 오래된 콜백을 사용하는 것입니다. 자바 스크립트의 예 :
var btnOK = $('btnOK');
btnOK.click(handleOKClick);
아직 아무도 INTERCAL 의 COMEFROM에 대해 언급하지 않았습니다 .
COMEFROM은 처음에 농담 어셈블리 언어 명령어 목록 ( 'CMFRM')에서 발견되었습니다. 1973 년 R. Lawrence Clark의 Datamation 기사에서 Edsger Dijkstra의 Go Go Statement Statemented Harmedful에 대한 응답으로 작성되었습니다. COMEFROM은 결국 난해한 프로그래밍 언어 인 INTERCAL의 C-INTERCAL 변형에서 훨씬 더 모호한 '계산 된 COMEFROM'과 함께 구현되었습니다. '지정된 COME FROM'과 'DONT'키워드 (기존의 'DO'루프를 보완하기위한)에 대한 포트란 제안도있었습니다.
2004 년 4 월 1 일, Richie Hindle은 Python 프로그래밍 언어를 위해 GOTO와 COMEFROM을 모두 구현했습니다. 만우절에 릴리스되어 심각한 용도로 사용되지는 않지만 구문이 유효하며 구현이 완전히 작동합니다.
Tcl 언어에는 변수가 설정되어 있거나 읽거나 삭제할 때마다 임의 코드가 실행될 수있는 변수에 대한 추적 이 있습니다. 이 임의의 코드에는 표현식을 평가하고 보유한 경우 일부 코드를 실행하는 것이 쉽게 포함될 수 있습니다. 주요 제약 조건은 로컬 변수에 대해이 작업을 수행 할 수 있지만 수명이 매우 짧은 경향이 있기 때문에 일반적으로별로 유용하지 않으므로 일반적으로 전역 및 네임 스페이스 변수로 제한됩니다. (Tcl에는 클로저가 없습니다.)
그러나이 작업을 수행하는 경우주의해야합니다. 공식적으로 재진입에 문제가 없지만 (몸이 실행되는 동안 추적이 비활성화 됨) 여전히 명확하지 않은 코드를 작성하고 많은 혼란을 유발하는 좋은 방법입니다. 성능 적중이 상당히 클 수 있으므로 루프 변수 (디버깅 제외)와 함께 사용하는 것은 정말 끔찍한 아이디어입니다.
위의 링크 된 매뉴얼 페이지의 코드를 기반으로 한 예를 보여줍니다.
set foo 1
set bar 2
proc doMult args {
global foo bar foobar
set foobar [expr {$foo * $bar}]
}
trace add variable foo write doMult
trace add variable bar write doMult
doMult
그 시점부터, $foo또는 $bar새로운 정수 $foobar가 될 때마다이 둘의 곱이됩니다. 자동으로.
또한 Tcl을 사용하면 명령 실행, 명령 삭제, 타이머, 소켓에서 사용할 수있는 데이터 등과 같은 다른 종류의 트리거에서 코드를 실행할 수 있습니다. Tk 라이브러리를 추가하면 전체적으로 큰 세트를 포함하도록 확장됩니다. GUI 이벤트도 마찬가지입니다. Tcl은 실제로 매우 강력한 이벤트 지향 언어라고 말할 수 있습니다 (이러한 기능을 전혀 사용하지 않는 코드를 쉽게 작성할 수있는 경우에도 마찬가지 임).
예, Perl에는 명령문 수정 자와 같은 키워드가 있습니다.
say 'Well done!' when 'A';
또한 switch 문의 일부입니다.
given ($foo) {
when (/^abc/) { $abc = 1; }
when (/^def/) { $def = 1; }
when (/^xyz/) { $xyz = 1; }
default { $nothing = 1; }
}
switch나에게 진술 처럼 냄새가 난다 . (황동 그것에 노브하지만, 다시로 그것은 이다 펄 ...)
caseA의 switch문. 에이다처럼.
않습니다 이 ( COMEFROM위키 백과에 설명 문) 계산?
요약:
COMEFROM은 코드의 임의 지점에서 COMEFROM 문으로 실행 상태를 취할 수 있다는 점에서 GOTO와 반대입니다. 상태 전송이 발생하는 코드 포인트는 일반적으로 COMEFROM에 매개 변수로 제공됩니다. 전송이 지정된 전송 지점에서 명령 이전 또는 이후에 발생하는지는 사용 된 언어에 따라 다릅니다. 사용 된 언어에 따라 동일한 출발점을 참조하는 여러 COMEFROM이 유효하지 않거나 비 결정적이거나 정의 된 우선 순위로 실행되거나 스레드 인터 칼에서 볼 수 있듯이 병렬 또는 동시 실행을 유발할 수 있습니다.
동기식 또는 비동기식 when 문이있는 언어를 찾고 있습니까?
나에게 이벤트 (/ 구독 / 콜백) 패턴처럼 들린다.
예 :
conditionOwner.Condition += listener.WhenCondition
조건 소유자가 조건이 발생했음을 알릴 때마다 리스너는 WhenCondition ()을 수행합니다.
여러 입력 변수의 상태를 확인하고 (변경시) 조건을 계산하는 변환기와 바인딩 패턴을 사용할 수 있으며, 리스너의 입력 특성이 출력에 바인드되고 해당 입력이 변경 될 때 작동합니다.
언어와 같이 .NET (예 : C #)에는 동기식 구독 (이벤트)이 내장되어 있으며 RX (Reactive Extensions)는 비동기식 구독을 추가합니다.
설명 은 특정 시나리오를 기다렸다가 실행하도록 설계된 데이터베이스 트리거 처럼 들립니다 .
Wikipedia에서 :
데이터베이스 트리거는 데이터베이스의 특정 테이블 또는 뷰에서 특정 이벤트에 대한 응답으로 자동 실행되는 절차 코드입니다. 트리거는 주로 데이터베이스의 정보 무결성을 유지하는 데 사용됩니다. 예를 들어, 새 레코드 (새 작업자를 나타냄)가 직원 테이블에 추가되면 세금, 휴가 및 급여 테이블에도 새 레코드가 작성되어야합니다.
당신이 말하는 것은 structure 보다 구문 이 적습니다 . 유한 한 양의 논리를 실행 한 다음 명령문 을 실행 한 다음 루프를 반복하고 논리를 다시 실행하여 무한 루프를 계속 하는 시스템에서는 실제로 이와 같은 명령문을 가질 수 있습니다 .whenwhen
예를 들어 Windows 프로그래밍은 일반적으로 "이벤트 기반"입니다. 버튼 Click이벤트에 가입한다는 것은 본질적으로 "클릭 할 때이 작업을 수행"을 의미합니다. 그러나 현재 진행중인 작업은 메시지 처리 루프입니다. 사용자가 버튼을 클릭하면 Windows가 응용 프로그램에 메시지를 보내고 응용 프로그램의 메시지 처리 루프가 적절한 이벤트 처리기를 실행합니다.
예를 들어 C #에서 이벤트를 사용하는 경우 메시지 루프없이이 작업을 수행 할 수 있지만 이벤트를 미리 선언해야한다는 제한이 있으므로 when어떤 종류의 이벤트도 감시하는 문장을 작성할 수 없습니다. 상태. 특정 이벤트를 기다려야합니다.
Von Neumann Architecture에서이 동작을 얻으려면 적절한 코드를 실행하는 루프를 통해 매번 모든 조건을 확인하는 일종의 무한 루프를 실행해야합니다. 내부적으로 당신은 if/ then또는 switch진술 의 큰 목록을 얻습니다 . 대부분의 데스크톱 응용 프로그램과 웹 프로그래머는 그러한 구조를 보았을 때 구토를 일으키므로 Windows 이벤트 모델과 같은 일종의 구문 설탕으로 감싸면 맛이 좋을 것입니다.
반면 임베디드 펌웨어 개발, 실시간 경영진 또는 산업용 컨트롤러 분야를 살펴보면이 프로그래밍 모델이 매우 일반적입니다. 예를 들어, 실시간 프로그램이있는 경우 다음을 표현할 수 있습니다.
outputA = input1 && input2
코드는 이해하기 쉽습니다 (선언적이므로). 그러나 제대로 작동하려면 꽉 조이는 루프에서 실행해야합니다. outputA루프를 통해 매번 재평가 합니다. 많은 데스크탑 또는 웹 프로그래머는 비효율적이므로 이것을 좋아하지 않을 것입니다. 그들에게 재평가해야 할 유일한시기 outputA는 언제 input1또는 input2변경 일뿐 입니다. 그들은 당신이 묘사하는 것과 같은 것을 오히려 보게 될 것입니다.
when input1 changes
evaluateOutputA()
when input2 changes
evaluateOutputA()
evaluateOutputA()
outputA = input1 && input2
이제 이것이 당신이 원하는 것 (그리고 개인적으로 나는이 아이디어를 선호하지 않음)이고 당신의 목표가 효율성이라면, 여전히 프로세서가 어떤 일을하고 있는지 스스로에게 물어봐야합니다. 분명히 매번 입력 상태를 이전 입력 상태와 비교하고 변경 될 때마다 적절한 코드를 실행하는 일종의 루프 실행이 여전히 있습니다. 따라서 실제로는 효율성이 떨어지고 읽기가 어렵고 유지 관리가 어렵습니다.
반면에, input1변경이 있을 때해야 할 일 이 중요하다면, 그 when절이 의미가있을 수 있습니다. PLC에서이 유형의 명령어를 "상승 에지 감지"라고합니다. input1루프를 통해 마지막 시간 의 상태를 저장하고 이번 값과 비교 한 후 마지막 상태가 false이고이 상태가 true 인 경우 논리를 실행합니다.
Von Neumann Architecture가 없으면 게임이 변경됩니다. 예를 들어 VHDL 에서 FPGA를 프로그래밍하는 경우 다음을 작성할 때 :
outputA = input1 && input2
(... 또는 적합한 VHDL 구문 것이 무엇이든) 다음 FPGA 실제로 업되도록 유선 도착 input1및 input2AND 게이트의 입력에 배선되고, 상기 출력은 AND 게이트에 결선된다 outputA. 따라서 코드는 이해하기 쉬울뿐만 아니라 다른 모든 논리와 동시에 실행되며 효율적입니다.
5 개의 IEC-61131-3 언어 중 하나로 프로그래밍 된 PLC 또는 PAC와 같은 산업용 컨트롤러에 대해 이야기 할 때 일반적인 경우는 다음과 같습니다.
이것은 시스템 아키텍처에 내장되어 있으므로 다음과 같이 작성하면됩니다.
outputA = input1 && input2
... 그리고 연속 루프에서 실행됩니다.
이 머신에는 인터럽트 루틴도 있습니다. 이것들은 when당신이 말하는 운영자를 위한 하드웨어 수준의 지원과 비슷합니다 . 하드웨어 인터럽트는 외부 이벤트에 일부 코드를 실행하는 방법이다. 예를 들어, 네트워크 카드에 데이터 대기 중이라고 표시되면 프로세서는 일반적으로 해당 데이터를 즉시 읽어야합니다. 그렇지 않으면 버퍼 공간이 부족합니다. 그러나 실제 하드웨어 인터럽트를 연결 해야하는 시간 동안 언어 키워드를 포함시키는 것이 가치가 있다고 생각합니다. CPU 입력 핀으로 제한되어 내부 프로그램 상태를 테스트하려는 것처럼 보입니다.
따라서 전통적인 언어 (무한한 루프없이 무한대로 실행)에서 "평가 코드는 언제 실행됩니까?"라는 질문을해야합니다.
당신이 쓰는 경우 :
when A do
launchNukes()
... A임의의 부울 표현식 이라고 가정하면 해당 표현식을 언제 다시 평가해야하는지 어떻게 알 수 있습니까? 순진한 구현은 모든 단일 메모리 쓰기 후에 다시 평가해야한다는 것을 의미합니다. 좁힐 수 있다고 생각할 수도 있지만 다음을 고려하십시오.
when systemTime > actionTime do
launchNukes()
공지 사항 systemTime항상 변화 (당신이 그것을 읽을 때마다, 당신은 다른 번호를 얻을 것이다). 이는 모든 when조항 의 조건부 부분이 지속적으로 재평가되어야 함을 의미합니다 . 그것은 거의 불가능합니다 (그리고 조건식에 부작용이 있으면 잠시 동안 일어나는 일을 고려하십시오!)
when메인 프로그램을 실행하는 무한 루프를 기반으로 한 아키텍처 에서만 (설명하는 것처럼) 명령문을 가질 수 있으며이 루프 when에서 조건이 false에서 true 로 변경된 경우 명령문 을 실행합니다 . 이 아키텍처는 임베디드 및 산업용 장치에서 일반적이지만 범용 프로그래밍 언어에서는 일반적이지 않습니다.
AspectJ의 언어 상황을 정확히 이런 종류를 처리하기위한 하나 개의 솔루션입니다 가입 - 포인트 모델을 가지고 있습니다.
AspectJ의 Join-Point는 프로그램이 실행될 때 발생하는 Java 프로그램의 동적 이벤트입니다. 결합 점의 예는 다음과 같습니다. (1) 메소드가 호출됩니다. (2) 방법이 실행된다. (3) 생성자가 호출됩니다. (4) 생성자가 실행됩니다. (5) 필드가 설정됩니다. 또는 (6) 필드에 액세스합니다.
그런 다음 pointcut이라고하는 이러한 결합 점 세트를 작성할 수 있습니다. 그런 다음 일반적인 컷 이론 방식으로 포인트 컷을 결합, 보완 및 교차 할 수 있습니다. 다른 포인트 컷은 변수의 값 / 유형 (예 : "x가 양수인 경우에만", "설정되는 값이이 유형의 서브 클래스 인 경우에만") 및 프로그램 상태 ( " 이 메소드가 호출되지만이 다른 메소드가이 스레드의 스택에있는 경우에만 해당 메소드가 간접적으로 호출되었다는 것을 의미합니다 ").
이러한 모든 포인트 컷이 프로그램의 이벤트를 설명하면 AspectJ를 사용 하여 해당 이벤트 를 알릴 수 있습니다. 이벤트가 발생하기 전에 ( before조언), 이벤트가 발생한 후 ( after조언) 또는 이벤트가 발생하는 대신 ( 조언) 수행하도록 선택할 수 있습니다 around.
Around조언은 프로그램에 캐싱을 추가 할 때 특히 유용합니다. 일부 메소드가 실행될 때 동일한 계산이 이미 수행되었는지 확인하려면 캐시를 확인하십시오. 캐시 된 버전을 사용하십시오. AspectJ를 사용하면 매우 가볍고 표현력이 뛰어나므로 캐싱이 값을 추가하는지 여부를 찾기 위해 코드의 수백 가지 지점에서 이러한 캐싱 실험을 수행 할 수 있습니다.
Aspect 지향 프로그래밍 이외의 많은 사람들은 AOP가 "로깅"에 관한 것이라고 생각합니다. AspectJ를 사용하여 로깅을 처리 할 수 있으며 꽤 잘 수행됩니다 ( "이 패키지의 모든 공용 메소드가 호출 될 때이 로그 파일에 기록 및 결과 / 오류 결과"). 그러나 Worm Hole Pattern (슬라이드 23 및 다음 참조) 이라는 동적 범위를 시뮬레이션하는 영리한 트릭을 포함하여 AspectJ에는 훨씬 더 많은 기능이 있습니다.
AOP 외부에서, 관찰자 패턴 (다른 사람들이 지적했듯이)을 포함하는 이벤트 기반 프로그래밍에 대해서도 이야기하고 있습니다. 솔루션의 차이점은 다음과 같습니다. (1) 상태가 어떻게 감지되는지; (2) 조건이 표현되는 경우; 그리고 (3) 코드 간 실행이 이벤트에 어떻게 바인딩되는지.
Notify / Wait 사용 방법은 다음과 비슷합니다.
우리는 자바 대기 / 알림 메커니즘이 본질적으로 쓰레드간에 통신하는 방법이라고 언급했다. 간단히 말해서 아이디어는 다음과 같습니다.
- 하나 이상의 스레드가 신호를 기다리는 동안 앉아있다;
- 다른 스레드가 와서 대기중인 스레드에게 알립니다 (즉, 신호와 함께 "깨우기").
상황에 따라 이에 가까운 구조가 있지만 질문을 명확히해야합니다.
이 요소는 일련의 테스트를 기반으로 한 행동 과정을 결정하는 데 사용됩니다. 각 테스트는 요소 내부에서 수행됩니다. 테스트가 성공하면 요소의 본문이 실행됩니다. 테스트가 실패하지 않으면 요소를 사용하여 기본 조치를 지정할 수 있습니다.
XSLT "when"은 if보다 스위치 와 같은 조건문 입니다. 그러나 초기 질문에서 "언제"라는 의미의 맥락은 실제로 명확하지 않았습니다.
콘텐츠를 제공하기 위해 작업하는 Sitecore CMS에서 XSLT를 자주 사용하므로 경우에 따라 GUI 환경에서 사용할 수 있습니다.
ifif 는 프로그래밍 언어에서 찾을 수 있는 절차 적 유형이 아니지만 . (XSLT를 일반적인 프로그래밍 언어보다 특정 데이터 처리 언어로 더 많이 봅니다. XSLT를 사용하여 데스크탑 GUI를 작성하는 것을 보지 못합니다)
당신이 요구하는 것은 Reactive Programming 입니다.
변수가 할당 된 표현을 인식하고 표현식의 구성 요소가 변경 될 때마다 변수 가 표현식을 다시 평가하여 반응 하여 종속 체인에서 다른 유사한 재평가를 트리거 할 수있는 프로그래밍 패러다임 .
일반적으로이 반응 거동은 관찰자 패턴을 영리하게 사용하여 이루어지며, 반응 값은 값의 재평가를 트리거하는 일련의 이벤트에 대한 리스너로 등록됩니다.
내가 아는 한, 핵심에는 반응성 프로그래밍을 완전히 포용하는 프로그래밍 언어가 없지만 많은 언어에는 반응성 프로그래밍의 이점을 제공하는 많은 라이브러리가 있습니다.
대부분의 데이터 바인딩 프레임 워크는 반응 형 프로그래밍의 구현으로 간주 될 수 있습니다 .
" 관찰자 패턴을 사용하지 않는 , 아마도 내가 할 수있는 것보다 훨씬 더 잘 설명 할 것입니다.
오류 처리에 대해서만 그러한 종류의 진술을 알고 있습니다. 예를 들어, BASIC ON ERROR ...또는 SQL * PLUSWHENEVER SQLERROR ...
임의 조건의 경우 조건이 참일 때 정확한 순간을 포착하려면 매우 영리한 컴파일러 또는 다소 비싼 종류의 무차별 강제력이 필요합니다 (모든 진술 후에 확인).
조건 변수를 찾고있는 것처럼 들립니다 . 일부 술어가 true가 될 때까지 스레드를 잠들 수있게합니다.
Boost 는 C ++에 대해 구현하고 Apache Portable Runtime 은 C에 대해 구현합니다. Common Lisp에서는 bordeaux-thread's를 사용 make-condition-variable합니다.
Drools를 언어로 생각한다면, 그렇습니다.
예를 들면 :
rule "Rule 08 - Debit"
when
AccountingPeriod( $start : start, $end : end )
$cashflow : AllocatedCashflow( $account : account, $date : date <= $end, $amount : amount, type==TypedCashflow.DEBIT )
not AccountingPeriod( start < $start)
then
$account.setBalance($account.getBalance()-$amount);
retract($cashflow);
end
Perl 6은 tap다음을 사용하여 신호를 직접 처리 할 수 있습니다 .
signal(SIGINT).tap: {
note "Took { now - INIT now } seconds.";
exit;
}
for 0, 1, *+* ... * {
sleep 0.5;
.say;
}
반면 Powershell은 try / finally 블록으로 실행 루프를 사용하여 처리 할 수 있습니다.
$Start_Time = (Get-date).second
Write-Host "Type CTRL-C to Terminate..."
$n = 1
Try
{
While($true)
{
Write-Host $n
$n ++
Start-Sleep -m 500
}
}
Finally
{
$End_Time = (Get-date).second
$Time_Diff = $End_Time - $Start_Time
Write-Host "Total time in seconds"$Time_Diff
}
다음을 사용하여 예상 할 수 있습니다 trap.
package require Expect
proc sigint_handler {} {
puts "elapsed time: [expr {[clock seconds] - $::start_time}] seconds"
set ::looping false
}
trap sigint_handler SIGINT
set start_time [clock seconds]
set n 0
set looping true
while {$looping} {
puts [incr n]
after 500
}
참고 문헌
이것들을 살펴본 이후로 오랜 시간이 걸렸기 때문에 착각 할 수있었습니다.
내가 기억 하듯이 PL / I와 BASIC은 모두 "ON"문을 가지고 있었다. PL / I에서 개념은 "ON DO"였습니다. BASIC에서는 "ON"이었으며, 여기서 명령문은 일반적으로 GOSUB입니다. 두 언어 모두에서 지정된 조건이 충족 될 때마다 관련 명령문이 실행되었습니다.
당신은 오늘 이것을하고 싶지 않을 것입니다. 컴파일러는 기본적으로 조건이 true가 될 수있는시기와 시점을 파악하기 위해 많은 작업을 수행해야하므로 해당 시점에서 테스트를 생성 할 수 있습니다. 일단 당신이 관련 처리기에 있다면, 당신은 당신이 어디에서 왔는지 알지 못하므로, 당신이 거기에 도착하게 된 일을 알아 내야하며, 당신이 어디에서 왔는지 되돌아 가기를 원하지 않을 것입니다.
당신은 한 번 봐있을 수 있습니다 OPS5의 언어를. 프로그램은 일련의 조건으로 작성됩니다. 조건이 충족되면 해당 작업이 수행됩니다. 조치는 상태를 수정하여 다른 조건을 충족시킬 수 있습니다. when키워드를 사용하지 않지만 "조건"이 충족 될 때 동작을 수행하여 작동합니다. 에서 여기 :
OPS5 프로그램은 기본 데이터 구조가 정의 된 선언 섹션과 데이터 조작 규칙이있는 프로덕션 섹션으로 구성됩니다.
OPS5 프로그램은 작업 메모리 요소를 프로덕션 메모리의 규칙과 일치시키고 가장 지배적 인 규칙을 실행 (실행)하여 실행합니다. Match-Select-Execute주기는 프로그램이 명시 적으로 중지 될 때까지 또는 작업 메모리에 규칙을 일치시킬 수 없을 때까지 계속됩니다.
90 년대 초 대학에있을 때이 언어로 간단한 텍스트 어드벤처를 작성해야했습니다. 흥미롭지 만 대부분의 데스크톱 또는 모바일 작업에 얼마나 유용한 지 잘 모르겠습니다. 그러나 백엔드 환경에서는 의미가있을 수 있습니다.
하스켈에는 하나가 있습니다. 그러나 이것은 특별한 구조가 아니며 다른 함수 http://hackage.haskell.org/packages/archive/base/latest/doc/html/Control-Monad.html#v:when
select case table1.col1 when 1 then 'Y' else 'N' end as col1_yn from .... 또한 : msdn.microsoft.com/en-us/library/dd233249.aspx 기본적으로 Google 코드 검색을 사용하여 "언제"를 검색합니다.