my previous question에 이어 정확히 정확하게 내가 원하는 것을 덜 어둡게 만듭니다. 나는 화학 약품을 썼다. 화학 약품과 반응의 이름이 'ATP', '아데노신', '데 옥시 시티 딘'등으로 대문자로 표기 될 것이라는 결정을 내렸다. 예를 들면 :Ruby의 자체 수정 코드가 다시로드되었습니다
ATP = ChemicalSpecies.new initial_concentration: 225.0 # in micromolars
GDP = ChemicalSpecies.new initial_concentration: 75.0 # in micromolars
ChemicalReaction.new name: ATP_GDP_phosphate_exchange,
rate: lambda { ATP * GDP * NDPK_constant }
난 그냥 쓸 수있다 : 촉매 일정
NDPK_constant = 0.6
와 효소 NDPK를 사용하여 ATP가 GDP를 인산화하는 데 사용되는 경우 이제
는, 내가 원하는이로 기록 될
ChemicalReaction.new name: ATP_GDP_phosphate_exchange,
reactants: [ ATP, GDP ],
rate: lambda { |reactant_1, reactant_2| reactant_1 * reactant_2 * NDPK_constant }
하지만 너무 젖어 보인다. reactant_1
, reactant_2
이 두 번 반복되는 방법을 확인하고 ATP
, GDP
을 염두에 두십시오. 쉬운 해결책은 다음과 같습니다
ChemicalReaction.new name: ATP_GDP_phosphate_exchange,
rate: lambda { _ATP * _GDP * NDPK_constant }
그리고 instance_eval
ATP
, GDP
의 농도로 _ATP
및 _GDP
을 정의하는 맥락에서 속도-찾는 블록. 이것은 매우 가깝지만, 은 정확히이 아니고, 나는 천국에서 나에게 화를냅니다. 심지어 어떤 화학 물질이 블록 내부에서 사용되는지 찾기 위해 RubyVM
을 사용할 수도 있습니다. _ATP
및 _GDP
을이 구문 분석하여
require 'ap' # (awesome_print, like pretty_print but fancier, install if you don't have)
ap RubyVM::InstructionSequence.disassemble(lambda { _ATP * _GDP * NDPK_constant }).split("\n")
#=> [ 0] "== disasm: <RubyVM::InstructionSequence:block in [email protected](irb)>=====",
[ 1] "== catch table",
[ 2] "| catch type: redo st: 0000 ed: 0027 sp: 0000 cont: 0000",
[ 3] "| catch type: next st: 0000 ed: 0027 sp: 0000 cont: 0027",
[ 4] "|------------------------------------------------------------------------",
[ 5] "0000 trace 1 ( 22)",
[ 6] "0002 putself ",
[ 7] "0003 send :_ATP, 0, nil, 24, <ic:0>",
[ 8] "0009 putself ",
[ 9] "0010 send :_GDP, 0, nil, 24, <ic:1>",
[10] "0016 opt_mult <ic:5>",
[11] "0018 getinlinecache 25, <ic:3>",
[12] "0021 getconstant :NDPK_constant",
[13] "0023 setinlinecache <ic:3>",
[14] "0025 opt_mult <ic:6>",
[15] "0027 leave
, 하나는 내부에 어떤 이름을 배운다. 하지만 내가 말했듯이, 고집에서, 나는 _ATP
, _GDP
을 찾는다. 화학자들이 농도에 대괄호를 사용하기 때문에 ATP
, GDP
또는 [ATP]
, [GDP]
이라고 말하고 싶습니다. 나는 Yusuke Endoh가 제약 코딩이라고 부르는 것을 알고 있습니다. 내 질문은,이 두 가지 바람직한 구문 중 하나가 맞을 수 있습니까? 예를 들어, 폐쇄 lambda { ATP * GDP * NDPK_constant }
을 가진이 제공 분해 :
ap RubyVM::InstructionSequence.disassemble(lambda { ATP * GDP * NDPK_constant }).split("\n")
#=> [ 0] "== disasm: <RubyVM::InstructionSequence:block in [email protected](irb)>=====",
[ 1] "== catch table",
[ 2] "| catch type: redo st: 0000 ed: 0027 sp: 0000 cont: 0000",
[ 3] "| catch type: next st: 0000 ed: 0027 sp: 0000 cont: 0027",
[ 4] "|------------------------------------------------------------------------",
[ 5] "0000 trace 1 ( 23)",
[ 6] "0002 getinlinecache 9, <ic:0>",
[ 7] "0005 getconstant :ATP",
[ 8] "0007 setinlinecache <ic:0>",
[ 9] "0009 getinlinecache 16, <ic:1>",
[10] "0012 getconstant :GDP",
[11] "0014 setinlinecache <ic:1>",
[12] "0016 opt_mult <ic:5>",
[13] "0018 getinlinecache 25, <ic:3>",
[14] "0021 getconstant :NDPK_constant",
[15] "0023 setinlinecache <ic:3>",
[16] "0025 opt_mult <ic:6>",
[17] "0027 leave
하나는 getconstant
는 :ATP
, :GDP
를 들어, 라인 7에서 10을 나타 것으로보고있다. 블록 외부의 ATP
및 GDP
상수는 ChemicalSpecies
인스턴스를 포함하지만 블록 안에는 ATP 및 GDP 의 농도 인을 참조해야합니다. 상수 자체가 다른 의미를 갖는 환경에서 블록을 평가할 방법을 찾지 못했습니다 (즉, 내가 원하지 않는 더러운 트릭을 사용하여 런타임에 상수를 임시로 다시 쓰지 않는 한). 내가 간절히 원했던 것은이 RubyVM 코드 getconstant :ATP
명령어를 예를 들어 대체 할 수 있다는 것이다. send :_ATP, 0, nil, 24, <ic:0>
그리고 나서 예. instance_eval
_ATP
가 ATP.concentration
을 의미 evironment이 폐쇄 ... 난 하나가 새로운 배열의 어떤 종류의 활성화가 필요 것이라고, 내가 두 번째 옵션 [ATP]
, [GDP]
에 관해서는
... 죄송합니다 다시 어려운 질문을 부탁 해요 알고 생성 후크가 블록 내부에만 있으므로, 요소가 하나만있는 경우 (ChemicalSpecies
), 배열 객체 대신 해당 집중이 반환됩니다. 나는 이것이 불가능하지는 않더라도 똑같이 어렵다고 생각한다.
모든 화학 대화를 제거하고 일반화하십시오. 우리는 마치 우리가 외계 종소리를 말하는 것처럼 들릴지도 모릅니다.하지만 이것은 그리스어입니다. 또한 해체는 무의미합니다. – Linuxios
이것은 단지 망치를 포크로 구부리려고하는 (또는 다른 영리한 말을 삽입) 것을 확인하는 것입니다. 사용자가 주요 우려 사항이라면 프로그래밍 철학자가 말한 것처럼 지옥에 빠지면됩니다 :) 사용자를 주요 지시어 1로 코딩하십시오. [ATP]가 아무도없는 추악한 스파게티 코드의 똥 더미없이 멋지게 행동하게하는 방법은 없습니다 해독하고 유지할 수있을 것입니다. 뿐만 아니라 Ruby 내부에 의존적 인 취성 코드가 될 것입니다. 자신 만의 도메인 언어를 작성하면 궁극의 통제력을 발휘할 수 있으며 결국에는 더 행복해하는 코더가됩니다 (사용자도 행복합니다). – Casper
[내 이전 답변] (http://stackoverflow.com/a/14658827/823617)도 볼 수 있습니다. 파서를 만들지 않고도 모든 것을 처리 할 수 있습니다. 간단한 문자열 교체와'eval'만으로도이 트릭을 수행 할 수 있습니다. 나는. '[ATP]'를'ATP.concetration'와'eval'로 대체하십시오. – Casper