Ruby에 자체 수정 코드를 작성하는 것에 대해 우려하고 있습니다. 자체 수정을 통해 코드 블록을 입력 값으로 사용하는 함수를 작성하고이를 기반으로 다른 코드 블록을 출력 할 수 있음을 의미합니다. (I는 런타임에 메서드를 재정의 등의 기본에 대한 요구 하진 않았어.)Ruby의 자체 수정 코드
_x_ = lambda { |a, b, c, d| b + c }
하나
가 알 수있는 것 I는 다음과 같은 블록을 가지고, 예를 들어, 수행 할 수 있습니다, 그 인수a
및
d
본문에 전혀 사용되지 않으므로 예를 들어 기능을 원합니다. 그들을 제거하기
#strip
서면으로 동일한 결과를 생성한다
x = _x_.strip
: 리스프 코드가 쉽게 조작 가능한 데이터이기 때문에
x = lambda { |b, c| b + c }
지금 리스프에,이, 쉽게 될 것입니다. 하지만 루비 코드를 조작하는 방법을 모르겠습니다. 나는 그것을 파싱 할 수있다. by
RubyVM::InstructionSequence.disassemble(x)
그러나 어떻게 이것을 기반으로 수정 된 블록을 작성합니까? 내가하고 싶은 다른 예는 예입니다.
y = lambda { A + B }
y.deconstantize
# should give block same as saying
lambda { |_A, _B| _A + _B }
지금까지 루비에서 나는 뭔가를 할 수 없다고 인정해야만했던 상황을 경험하지 못했습니다. 그러나 이번에는, 감각적 인 느낌은 아름답게 구조화 된 코드 대 약한 구문 (Lisp이 될 수있는)을 가진 코드의 근본적인 약점을 만났을 수도 있다는 것을 나에게 말해줍니다. 제발 저를 계몽하십시오.
구체적인 사용 사례가 있습니까? – Nevir
사용하지 않은 병을 감지하려면 AST 레벨로 내려야합니다. 아마도 [melbourne gem]을 통해 (https://github.com/simplabs/melbourne). 하지만 유스 케이스를 커버하기 위해 취할 수있는 다른 /보다 편리한 접근 방법이 있습니다. – Nevir
@Nevir :하지만 분명히하고 있습니다. 나는 관광객이 아니다, 나는 내가 할 일이없는 곳으로 가지 않는다 :-). 다음 코드를 상상해보십시오 :'ChemicalReaction.new (name : "A_and_B_assembly", rate : proc {A * B * 0.189})'. 나는 사용자가 쉽게 가고 싶어하므로,'proc {| _A, _B | _A * _B * 0.189}'이는 다음과 같은 의미 일 것입니다. (0.189는 속도 상수 임) ... –