pione 0.4.2 → 0.5.0.alpha.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (306) hide show
  1. checksums.yaml +8 -8
  2. data/.travis.yml +1 -1
  3. data/History.txt +6 -0
  4. data/example/ActionError/ActionError.action.md +11 -0
  5. data/example/ActionError/ActionError.pione +6 -3
  6. data/example/ActionError/ActionError.pnml +86 -0
  7. data/example/ActionError/Package.pione +2 -0
  8. data/example/ActionError/pione-package.json +5 -1
  9. data/example/CTFCorrection/CTFCorrection.action.md +46 -0
  10. data/example/CTFCorrection/CTFCorrection.pione +19 -41
  11. data/example/CTFCorrection/CTFCorrection.pnml +839 -0
  12. data/example/CTFCorrection/Package.pione +1 -0
  13. data/example/CTFCorrection/Params.pione +21 -0
  14. data/example/CTFCorrection/pione-package.json +20 -0
  15. data/example/ChildPackage/ChildPackage.pione +8 -0
  16. data/example/ChildPackage/pione-package.json +20 -0
  17. data/example/CountChar/CountChar.pione +31 -0
  18. data/example/CountChar/CountChar.pnml +239 -0
  19. data/example/CountChar/Main.pione +6 -26
  20. data/example/CountChar/Main.pnml +32 -100
  21. data/example/CountChar/Package.pione +1 -0
  22. data/example/CountChar/pione-package.json +3 -1
  23. data/example/DeferredChoice/DeferredChoice.action.md +46 -0
  24. data/example/DeferredChoice/DeferredChoice.pione +2 -7
  25. data/example/DeferredChoice/DeferredChoice.pnml +371 -0
  26. data/example/DeferredChoice/Package.pione +4 -0
  27. data/example/DeferredChoice/pione-package.json +7 -3
  28. data/example/DeferredChoiceWithPage/DeferredChoiceWithPage.action.md +34 -0
  29. data/example/DeferredChoiceWithPage/DefferredChoiceWithPage.pnml +371 -0
  30. data/example/DeferredChoiceWithPage/Package.pione +2 -0
  31. data/example/FeatureExample/FeatureExample.action.md +7 -0
  32. data/example/FeatureExample/FeatureExample.pione +7 -4
  33. data/example/FeatureExample/FeatureExample.pnml +86 -0
  34. data/example/FeatureExample/Package.pione +1 -0
  35. data/example/FeatureExample/pione-package.json +4 -0
  36. data/example/Fib/Fib.action.md +33 -0
  37. data/example/Fib/Fib.pnml +208 -0
  38. data/example/Fib/FibN.pnml +807 -0
  39. data/example/Fib/Package.pione +6 -0
  40. data/example/HelloWorld/HelloWorld.action.md +7 -0
  41. data/example/HelloWorld/HelloWorld.pione +6 -2
  42. data/example/HelloWorld/HelloWorld.pnml +86 -0
  43. data/example/HelloWorld/Package.pione +2 -0
  44. data/example/HelloWorld/pione-package.json +5 -1
  45. data/example/Interaction/Interaction.action.md +21 -0
  46. data/example/Interaction/Interaction.pnml +89 -0
  47. data/example/Interaction/Package.pione +2 -0
  48. data/example/LoopByTouch/LoopByTouch.pione +32 -12
  49. data/example/LoopByTouch/LoopByTouch.pnml +575 -0
  50. data/example/LoopByTouch/Package.pione +3 -0
  51. data/example/LoopByTouch/PairLoop.pione +6 -7
  52. data/example/LoopByTouch/PairLoop.pnml +188 -0
  53. data/example/LoopByTouch/SingleLoop.pione +6 -0
  54. data/example/LoopByTouch/SingleLoop.pnml +86 -0
  55. data/example/LoopByTouch/TripletLoop.pione +12 -13
  56. data/example/LoopByTouch/TripletLoop.pnml +239 -0
  57. data/example/LoopByTouch/pione-package.json +7 -3
  58. data/example/LucasNumber/LucasNumber.action.md +25 -0
  59. data/example/LucasNumber/LucasNumber.pnml +244 -0
  60. data/example/LucasNumber/LucasNumberN.pnml +1719 -0
  61. data/example/LucasNumber/Package.pione +2 -0
  62. data/example/MakePair/MakePair.pione +8 -10
  63. data/example/MakePair/MakePair.pnml +1141 -0
  64. data/example/MakePair/Package.pione +2 -0
  65. data/example/MakePair/pione-package.json +7 -3
  66. data/example/MakePair/scenario/case1/pione-scenario.json +30 -30
  67. data/example/MakePair/scenario/case2/pione-scenario.json +10 -10
  68. data/example/MakePair/scenario/case3/pione-scenario.json +28 -28
  69. data/example/OddSelector/OddSelector.pione +8 -8
  70. data/example/OddSelector/OddSelector.pnml +401 -0
  71. data/example/OddSelector/Package.pione +2 -0
  72. data/example/OddSelector/pione-package.json +4 -0
  73. data/example/OddSelector/scenario/pione-scenario.json +8 -8
  74. data/example/ParentPackage/ParentPackage.pione +13 -0
  75. data/example/ParentPackage/pione-package.json +18 -0
  76. data/example/PegasusWMS/Merge/Package.pione +2 -0
  77. data/example/PegasusWMS/Merge/PegasusWMSMerge.action.md +17 -0
  78. data/example/PegasusWMS/Merge/{Merge.pione → PegasusWMSMerge.pione} +9 -10
  79. data/example/PegasusWMS/Merge/PegasusWMSMerge.pnml +217 -0
  80. data/example/PegasusWMS/Merge/pione-package.json +6 -2
  81. data/example/PegasusWMS/Pipeline/Package.pione +2 -0
  82. data/example/PegasusWMS/Pipeline/PegasusWMSPipeline.action.md +17 -0
  83. data/example/PegasusWMS/Pipeline/{Pipeline.pione → PegasusWMSPipeline.pione} +7 -9
  84. data/example/PegasusWMS/Pipeline/PegasusWMSPipeline.pnml +137 -0
  85. data/example/PegasusWMS/Pipeline/pione-package.json +6 -2
  86. data/example/PegasusWMS/Split/Package.pione +2 -0
  87. data/example/PegasusWMS/Split/PegasusWMSSplit.action.md +19 -0
  88. data/example/PegasusWMS/Split/{Split.pione → PegasusWMSSplit.pione} +9 -10
  89. data/example/PegasusWMS/Split/PegasusWMSSplit.pnml +293 -0
  90. data/example/PegasusWMS/Split/pione-package.json +6 -2
  91. data/example/ScoreAggregation/Package.pione +2 -0
  92. data/example/ScoreAggregation/ScoreAggregation.action.md +56 -0
  93. data/example/ScoreAggregation/ScoreAggregation.pione +37 -76
  94. data/example/ScoreAggregation/ScoreAggregation.pnml +1221 -0
  95. data/example/ScoreAggregation/pione-package.json +6 -2
  96. data/example/ScoreAggregation/scenario/case1/pione-scenario.json +21 -21
  97. data/example/SelectRuleByParam/Package.pione +2 -0
  98. data/example/SelectRuleByParam/SelectRuleByParam.action.md +19 -0
  99. data/example/SelectRuleByParam/SelectRuleByParam.pnml +388 -0
  100. data/example/SequentialParameter/Package.pione +2 -0
  101. data/example/SequentialParameter/SequentialParameter.pione +9 -3
  102. data/example/SequentialParameter/SequentialParameter.pnml +140 -0
  103. data/example/SequentialParameter/pione-package.json +19 -0
  104. data/example/SerialProcessing/A.pione +25 -0
  105. data/example/SerialProcessing/A.pnml +395 -0
  106. data/example/SerialProcessing/B.pione +25 -0
  107. data/example/SerialProcessing/B.pnml +395 -0
  108. data/example/SerialProcessing/Package.pione +2 -0
  109. data/example/SerialProcessing/SerialProcessing.pione +9 -60
  110. data/example/SerialProcessing/SerialProcessing.pnml +160 -0
  111. data/example/SerialProcessing/pione-package.json +7 -1
  112. data/example/SieveOfEratosthenes/CreateUndeterminedNumbers.pnml +157 -0
  113. data/example/SieveOfEratosthenes/Package.pione +4 -0
  114. data/example/SieveOfEratosthenes/Sieve.pnml +1493 -0
  115. data/example/SieveOfEratosthenes/SieveOfEratosthenes.pnml +174 -0
  116. data/example/SingleParticlesWithRef/Create3dinfo.pnml +342 -0
  117. data/example/SingleParticlesWithRef/Package.pione +42 -0
  118. data/example/SingleParticlesWithRef/SingleParticlesWithRef.action.md +34 -0
  119. data/example/SingleParticlesWithRef/SingleParticlesWithRef.pnml +404 -0
  120. data/example/SingleParticlesWithRef/{Makefile → misc/Makefile} +0 -0
  121. data/example/SingleParticlesWithRef/{SingleParticlesWithRef.Display2.pione → misc/SingleParticlesWithRef.Display2.pione} +0 -0
  122. data/example/SingleParticlesWithRef/{SingleParticlesWithRef.Makefile → misc/SingleParticlesWithRef.Makefile} +0 -0
  123. data/example/SingleParticlesWithRef/{SingleParticlesWithRefFull.pione → misc/SingleParticlesWithRefFull.pione} +0 -0
  124. data/example/Sum/CalcEachLine.pione +30 -0
  125. data/example/Sum/CalcEachLine.pnml +327 -0
  126. data/example/Sum/Package.pione +2 -0
  127. data/example/Sum/Sum.action.md +35 -0
  128. data/example/Sum/Sum.pione +9 -35
  129. data/example/Sum/Sum.pnml +191 -0
  130. data/example/Sum/pione-package.json +5 -0
  131. data/example/Touch/Package.pione +2 -0
  132. data/example/Touch/Touch.pione +8 -2
  133. data/example/Touch/Touch.pnml +89 -0
  134. data/example/Touch/pione-package.json +4 -0
  135. data/example/WorkflowPatterns/01_Sequence/Package.pione +2 -0
  136. data/example/WorkflowPatterns/01_Sequence/Sequence.pione +9 -9
  137. data/example/WorkflowPatterns/01_Sequence/Sequence.pnml +191 -0
  138. data/example/WorkflowPatterns/01_Sequence/pione-package.json +19 -0
  139. data/example/WorkflowPatterns/02_PrallelSplit/Package.pione +2 -0
  140. data/example/WorkflowPatterns/02_PrallelSplit/ParallelSplit.pione +12 -12
  141. data/example/WorkflowPatterns/02_PrallelSplit/ParallelSplit.pnml +265 -0
  142. data/example/WorkflowPatterns/02_PrallelSplit/pione-package.json +19 -0
  143. data/example/WorkflowPatterns/03_Synchronization/Package.pione +2 -0
  144. data/example/WorkflowPatterns/03_Synchronization/Synchronization.pione +12 -13
  145. data/example/WorkflowPatterns/03_Synchronization/Synchronization.pnml +273 -0
  146. data/example/WorkflowPatterns/03_Synchronization/pione-package.json +19 -0
  147. data/example/WorkflowPatterns/04_ExclusiveChoice/ExclusiveChoice.pione +15 -22
  148. data/example/WorkflowPatterns/04_ExclusiveChoice/ExclusiveChoice.pnml +533 -0
  149. data/example/WorkflowPatterns/04_ExclusiveChoice/Package.pione +4 -0
  150. data/example/WorkflowPatterns/04_ExclusiveChoice/pione-package.json +19 -0
  151. data/example/WorkflowPatterns/05_SimpleMerge/Package.pione +4 -0
  152. data/example/WorkflowPatterns/05_SimpleMerge/SimpleMerge.pione +10 -18
  153. data/example/WorkflowPatterns/05_SimpleMerge/SimpleMerge.pnml +431 -0
  154. data/example/WorkflowPatterns/05_SimpleMerge/pione-package.json +19 -0
  155. data/example/WorkflowPatterns/06_MultiChoice/MultiChoice.pione +20 -28
  156. data/example/WorkflowPatterns/06_MultiChoice/MultiChoice.pnml +797 -0
  157. data/example/WorkflowPatterns/06_MultiChoice/Package.pione +5 -0
  158. data/example/WorkflowPatterns/06_MultiChoice/pione-package.json +19 -0
  159. data/example/WorkflowPatterns/07_StructuredSynchronizingMerge/Package.pione +5 -0
  160. data/example/WorkflowPatterns/07_StructuredSynchronizingMerge/StructuredSynchronizingMerge.pnml +668 -0
  161. data/example/WorkflowPatterns/08_MultiMerge/MultiMerge.pione +9 -20
  162. data/example/WorkflowPatterns/08_MultiMerge/MultiMerge.pnml +551 -0
  163. data/example/WorkflowPatterns/08_MultiMerge/Package.pione +4 -0
  164. data/example/WorkflowPatterns/08_MultiMerge/pione-package.json +19 -0
  165. data/example/WorkflowPatterns/11_ImplicitTermination/ImplicitTermination.pione +9 -17
  166. data/example/WorkflowPatterns/11_ImplicitTermination/ImplicitTermination.pnml +188 -0
  167. data/example/WorkflowPatterns/11_ImplicitTermination/Package.pione +2 -0
  168. data/example/WorkflowPatterns/11_ImplicitTermination/pione-package.json +19 -0
  169. data/example/WorkflowPatterns/12_MultipleInstancesWithoutSynchronization/MultipleInstancesWithoutSynchronization.pione +11 -11
  170. data/example/WorkflowPatterns/12_MultipleInstancesWithoutSynchronization/MultipleInstancesWithoutSynchronization.pnml +319 -0
  171. data/example/WorkflowPatterns/12_MultipleInstancesWithoutSynchronization/Package.pione +4 -0
  172. data/example/WorkflowPatterns/12_MultipleInstancesWithoutSynchronization/pione-package.json +19 -0
  173. data/example/WorkflowPatterns/13_MultipleInstancesWithDesignTimeKnowledge/MultipleInstancesWithDesignTimeKnowledge.pione +11 -11
  174. data/example/WorkflowPatterns/13_MultipleInstancesWithDesignTimeKnowledge/MultipleInstancesWithDesignTimeKnowledge.pnml +319 -0
  175. data/example/WorkflowPatterns/13_MultipleInstancesWithDesignTimeKnowledge/Package.pione +2 -0
  176. data/example/WorkflowPatterns/13_MultipleInstancesWithDesignTimeKnowledge/pione-package.json +19 -0
  177. data/example/WorkflowPatterns/14_MultipleInstancesWithRunTimeKnowledge/MultipleInstancesWithRunTimeKnowledge.pione +14 -17
  178. data/example/WorkflowPatterns/14_MultipleInstancesWithRunTimeKnowledge/MultipleInstancesWithRunTimeKnowledge.pnml +355 -0
  179. data/example/WorkflowPatterns/14_MultipleInstancesWithRunTimeKnowledge/Package.pione +4 -0
  180. data/example/WorkflowPatterns/14_MultipleInstancesWithRunTimeKnowledge/pione-package.json +19 -0
  181. data/example/WorkflowPatterns/33_GeneralizedANDJoin/GeneralizedANDJoin.pione +9 -10
  182. data/example/WorkflowPatterns/33_GeneralizedANDJoin/GeneralizedANDJoin.pnml +409 -0
  183. data/example/WorkflowPatterns/33_GeneralizedANDJoin/Package.pione +2 -0
  184. data/example/WorkflowPatterns/33_GeneralizedANDJoin/pione-package.json +19 -0
  185. data/example/WorkflowPatterns/37_LocalSynchronizingMerge/A.pione +34 -0
  186. data/example/WorkflowPatterns/37_LocalSynchronizingMerge/A.pnml +570 -0
  187. data/example/WorkflowPatterns/37_LocalSynchronizingMerge/LocalSynchronizingMerge.pione +36 -70
  188. data/example/WorkflowPatterns/37_LocalSynchronizingMerge/LocalSynchronizingMerge.pnml +854 -0
  189. data/example/WorkflowPatterns/37_LocalSynchronizingMerge/Package.pione +5 -0
  190. data/example/WorkflowPatterns/37_LocalSynchronizingMerge/pione-package.json +20 -0
  191. data/example/WorkflowPatterns/38_GeneralSynchronizingMerge/GeneralSynchronizingMerge.pnml +1003 -0
  192. data/example/WorkflowPatterns/38_GeneralSynchronizingMerge/Package.pione +6 -0
  193. data/example/WorkflowPatterns/41_ThreadMerge/A.pnml +429 -0
  194. data/example/WorkflowPatterns/41_ThreadMerge/A1.pnml +141 -0
  195. data/example/WorkflowPatterns/41_ThreadMerge/Package.pione +2 -0
  196. data/example/WorkflowPatterns/41_ThreadMerge/ThreadMerge.pnml +205 -0
  197. data/example/WorkflowPatterns/42_ThreadSplit/Package.pione +2 -0
  198. data/example/WorkflowPatterns/42_ThreadSplit/ThreadSplit.pnml +217 -0
  199. data/lib/pione/agent/job-manager.rb +4 -3
  200. data/lib/pione/agent/task-worker.rb +2 -7
  201. data/lib/pione/command.rb +1 -0
  202. data/lib/pione/command/basic-command.rb +3 -1
  203. data/lib/pione/command/command-exception.rb +14 -0
  204. data/lib/pione/command/pione-action-exec.rb +4 -1
  205. data/lib/pione/command/pione-clean.rb +13 -6
  206. data/lib/pione/command/pione-client.rb +5 -5
  207. data/lib/pione/command/pione-compile.rb +1 -1
  208. data/lib/pione/command/pione-log-format.rb +1 -1
  209. data/lib/pione/command/pione-package-add.rb +1 -1
  210. data/lib/pione/command/pione-package-build.rb +87 -32
  211. data/lib/pione/command/pione-package-remove.rb +117 -0
  212. data/lib/pione/command/pione-package.rb +1 -0
  213. data/lib/pione/command/spawner.rb +12 -3
  214. data/lib/pione/lang/boolean.rb +1 -1
  215. data/lib/pione/lang/common-parser.rb +5 -3
  216. data/lib/pione/lang/context-parser.rb +8 -2
  217. data/lib/pione/lang/context-transformer.rb +13 -3
  218. data/lib/pione/lang/context.rb +20 -2
  219. data/lib/pione/lang/data-expr.rb +1 -1
  220. data/lib/pione/lang/declaration-parser.rb +18 -4
  221. data/lib/pione/lang/declaration-transformer.rb +1 -1
  222. data/lib/pione/lang/declaration.rb +5 -3
  223. data/lib/pione/lang/definition.rb +1 -0
  224. data/lib/pione/lang/environment.rb +37 -2
  225. data/lib/pione/lang/expr.rb +10 -12
  226. data/lib/pione/lang/feature-expr.rb +1 -1
  227. data/lib/pione/lang/float.rb +1 -1
  228. data/lib/pione/lang/integer.rb +1 -1
  229. data/lib/pione/lang/keyed-sequence.rb +5 -5
  230. data/lib/pione/lang/lang-exception.rb +9 -5
  231. data/lib/pione/lang/literal-parser.rb +2 -2
  232. data/lib/pione/lang/literal-transformer.rb +3 -0
  233. data/lib/pione/lang/message.rb +3 -3
  234. data/lib/pione/lang/ordinal-sequence.rb +1 -1
  235. data/lib/pione/lang/package-expr.rb +1 -1
  236. data/lib/pione/lang/parameters.rb +1 -1
  237. data/lib/pione/lang/pione-method.rb +16 -16
  238. data/lib/pione/lang/rule-expr.rb +6 -1
  239. data/lib/pione/lang/sequence.rb +8 -3
  240. data/lib/pione/lang/string.rb +1 -1
  241. data/lib/pione/lang/ticket-expr.rb +1 -1
  242. data/lib/pione/lang/type.rb +17 -8
  243. data/lib/pione/lang/variable.rb +4 -1
  244. data/lib/pione/literate-action.rb +1 -2
  245. data/lib/pione/literate-action/document.rb +1 -1
  246. data/lib/pione/literate-action/handler.rb +22 -7
  247. data/lib/pione/literate-action/{parser.rb → markdown-parser.rb} +2 -1
  248. data/lib/pione/log/domain-log.rb +1 -1
  249. data/lib/pione/model/task-worker-broker-model.rb +1 -1
  250. data/lib/pione/package/package-database.rb +16 -2
  251. data/lib/pione/package/package-exception.rb +1 -1
  252. data/lib/pione/package/package-handler.rb +11 -7
  253. data/lib/pione/package/package-info.rb +13 -7
  254. data/lib/pione/package/package-scanner.rb +1 -1
  255. data/lib/pione/package/scenario-info.rb +2 -2
  256. data/lib/pione/pnml.rb +6 -0
  257. data/lib/pione/pnml/compiler.rb +329 -95
  258. data/lib/pione/pnml/declaration-extractor.rb +90 -0
  259. data/lib/pione/pnml/input-merge-complement.rb +17 -11
  260. data/lib/pione/pnml/input-parallelization-complement.rb +10 -6
  261. data/lib/pione/pnml/input-reduction.rb +5 -5
  262. data/lib/pione/pnml/invalid-arc-elimination.rb +2 -2
  263. data/lib/pione/pnml/io-expansion.rb +9 -5
  264. data/lib/pione/pnml/isolated-element-elimination.rb +2 -2
  265. data/lib/pione/pnml/label-extractor.rb +258 -0
  266. data/lib/pione/pnml/net-rewriter.rb +6 -4
  267. data/lib/pione/pnml/output-decomposition-complement.rb +12 -7
  268. data/lib/pione/pnml/output-reduction.rb +11 -5
  269. data/lib/pione/pnml/output-synchronization-complement.rb +11 -7
  270. data/lib/pione/pnml/parser.rb +106 -0
  271. data/lib/pione/pnml/pione-model.rb +685 -230
  272. data/lib/pione/pnml/pnml-model.rb +73 -41
  273. data/lib/pione/pnml/ticket-instantiation.rb +42 -0
  274. data/lib/pione/rule-engine/action-handler.rb +212 -135
  275. data/lib/pione/rule-engine/basic-handler.rb +29 -3
  276. data/lib/pione/rule-engine/engine-exception.rb +10 -6
  277. data/lib/pione/system/status.rb +12 -6
  278. data/lib/pione/version.rb +1 -1
  279. data/lib/rootage/help.md.erb +45 -0
  280. data/lib/rootage/help.rb +1 -0
  281. data/lib/rootage/scenario.rb +20 -2
  282. data/misc/pione-completion.bash +15 -5
  283. data/misc/pione-completion.zsh +16 -6
  284. data/test/command/spec_pione-client.rb +60 -60
  285. data/test/lang/data/context-parser.yml +12 -1
  286. data/test/lang/spec_pione-method.rb +7 -6
  287. data/test/literate-action/spec_handler.rb +19 -13
  288. data/test/literate-action/{spec_parser.rb → spec_markdown-parser.rb} +3 -3
  289. data/test/log/spec_message-log-receiver.rb +1 -1
  290. data/test/package/spec_package-info.rb +1 -1
  291. data/test/pnml/spec_input-merge-complement.rb +4 -2
  292. data/test/pnml/spec_input-parallelization-complement.rb +4 -2
  293. data/test/pnml/spec_input-reduction.rb +8 -4
  294. data/test/pnml/spec_invalid-arc-elimination.rb +2 -1
  295. data/test/pnml/spec_io-expansion.rb +4 -2
  296. data/test/pnml/spec_isolated-element-elimination.rb +2 -1
  297. data/test/pnml/spec_label-extractor.rb +100 -0
  298. data/test/pnml/spec_output-decomposition-complement.rb +4 -2
  299. data/test/pnml/spec_output-reduction.rb +8 -4
  300. data/test/pnml/spec_output-synchronization-complement.rb +4 -2
  301. data/test/pnml/spec_pione-element.rb +116 -37
  302. data/test/pnml/spec_pnml-element.rb +32 -8
  303. data/test/rule-engine/spec_action-handler.rb +12 -20
  304. metadata +159 -16
  305. data/example/CTFCorrection/package.yml +0 -1
  306. data/example/DeferredChoice/bin/ui.xml +0 -28
@@ -70,7 +70,13 @@ module Pione
70
70
  # @return [Array<Arc>]
71
71
  # result arcs
72
72
  def find_all_arcs_by_source_id(source_id)
73
- arcs.select {|arc| arc.source_id == source_id}
73
+ _arcs = arcs.select {|arc| arc.source_id == source_id}
74
+
75
+ if block_given?
76
+ _arcs.each {|arc| yield arc}
77
+ else
78
+ return _arcs
79
+ end
74
80
  end
75
81
 
76
82
  # Find all arcs by the target ID.
@@ -80,7 +86,13 @@ module Pione
80
86
  # @return [Array<Arc>]
81
87
  # result arcs
82
88
  def find_all_arcs_by_target_id(target_id)
83
- arcs.select {|arc| arc.target_id == target_id}
89
+ _arcs = arcs.select {|arc| arc.target_id == target_id}
90
+
91
+ if block_given?
92
+ _arcs.each {|arc| yield arc}
93
+ else
94
+ return _arcs
95
+ end
84
96
  end
85
97
 
86
98
  # Return all arcs which have the direction from transtion to place.
@@ -88,7 +100,13 @@ module Pione
88
100
  # @return [Array<PNML::Arc>]
89
101
  # arcs
90
102
  def tp_arcs
91
- arcs.select {|arc| arc.from_transition_to_place?}
103
+ _arcs = arcs.select {|arc| arc.from_transition_to_place?}
104
+
105
+ if block_given?
106
+ _arcs.each {|arc| yield arc}
107
+ else
108
+ return _arcs
109
+ end
92
110
  end
93
111
 
94
112
  # Return all arcs which have the direction from place to transition.
@@ -96,7 +114,13 @@ module Pione
96
114
  # @return [Array<PNML::Arc>]
97
115
  # arcs
98
116
  def pt_arcs
99
- arcs.select {|arc| arc.from_place_to_transition?}
117
+ _arcs = arcs.select {|arc| arc.from_place_to_transition?}
118
+
119
+ if block_given?
120
+ _arcs.each {|arc| yield arc}
121
+ else
122
+ return _arcs
123
+ end
100
124
  end
101
125
 
102
126
  # Find a transition by ID.
@@ -116,7 +140,7 @@ module Pione
116
140
  # @return [Transition]
117
141
  # a transition, or nil
118
142
  def find_transition_by_name(name)
119
- _transitions = transitions.select {|transition| transition.name == name}
143
+ _transitions = find_all_transitions_by_name(name)
120
144
 
121
145
  # the result shouldn't be ambiguous
122
146
  if _transitions.size > 1
@@ -133,7 +157,13 @@ module Pione
133
157
  # @return [Array<Transition>]
134
158
  # transitions
135
159
  def find_all_transitions_by_name(name)
136
- transitions.select {|transition| transition.name == name}
160
+ _transitions = transitions.select {|transition| transition.name == name}
161
+
162
+ if block_given?
163
+ _transitions.each {|transition| yield transition}
164
+ else
165
+ return _transitions
166
+ end
137
167
  end
138
168
 
139
169
  # Find a transition by the source place ID.
@@ -143,10 +173,7 @@ module Pione
143
173
  # @return [Array<Transition>]
144
174
  # result transitions
145
175
  def find_transition_by_source_id(place_id)
146
- _arcs = arcs.select {|arc| arc.source_id == place_id}
147
- _transitions = _arcs.map do |arc|
148
- transitions.find {|transition| transition.id == arc.target_id}
149
- end.compact.uniq
176
+ _transitions = find_all_transitions_by_source_id(place_id)
150
177
 
151
178
  # the result shouldn't be ambiguous
152
179
  if _transitions.size > 1
@@ -166,8 +193,13 @@ module Pione
166
193
  _arcs = arcs.select {|arc| arc.source_id == place_id}
167
194
  _transitions = _arcs.map do |arc|
168
195
  transitions.find {|transition| transition.id == arc.target_id}
196
+ end.compact.uniq
197
+
198
+ if block_given?
199
+ _transitions.each {|transition| yield transition}
200
+ else
201
+ return _transitions
169
202
  end
170
- return _transitions.compact.uniq
171
203
  end
172
204
 
173
205
  # Find a transition by the target place ID.
@@ -176,11 +208,8 @@ module Pione
176
208
  # place ID
177
209
  # @return [Array<Transition>]
178
210
  # result transitions
179
- def find_transition_by_target_id(target_id)
180
- _arcs = arcs.select {|arc| arc.target_id == target_id}
181
- _transitions = _arcs.map do |arc|
182
- transitions.find {|transition| transition.id == arc.source_id}
183
- end.compact.uniq
211
+ def find_transition_by_target_id(place_id)
212
+ _transitions = find_all_transitions_by_target_id(place_id)
184
213
 
185
214
  # the result shouldn't be ambiguous
186
215
  if _transitions.size > 1
@@ -200,8 +229,13 @@ module Pione
200
229
  _arcs = arcs.select {|arc| arc.target_id == target_id}
201
230
  _transitions = _arcs.map do |arc|
202
231
  transitions.find {|transition| transition.id == arc.source_id}
232
+ end.compact.uniq
233
+
234
+ if block_given?
235
+ _transitions.each {|transition| yield transition}
236
+ else
237
+ return _transitions
203
238
  end
204
- return _transitions.compact.uniq
205
239
  end
206
240
 
207
241
  # Find a place by ID.
@@ -221,7 +255,7 @@ module Pione
221
255
  # @return [Place]
222
256
  # a place, or nil
223
257
  def find_place_by_name(name)
224
- _places = places.select {|place| place.name == name}
258
+ _places = find_all_places_by_name(name)
225
259
 
226
260
  # the result shouldn't be ambiguous
227
261
  if _places.size > 1
@@ -238,7 +272,13 @@ module Pione
238
272
  # @return [Array<Place>]
239
273
  # places
240
274
  def find_all_places_by_name(name)
241
- places.select {|place| place.name == name}
275
+ _places = places.select {|place| place.name == name}
276
+
277
+ if block_given?
278
+ _places.each {|place| yield place}
279
+ else
280
+ return _places
281
+ end
242
282
  end
243
283
 
244
284
  # Find a place by the source transition ID.
@@ -248,10 +288,7 @@ module Pione
248
288
  # @return [Array<Transition>]
249
289
  # a result place
250
290
  def find_place_by_source_id(transition_id)
251
- _arcs = arcs.select {|arc| arc.source_id == transition_id}
252
- _places = _arcs.map do |arc|
253
- places.find {|place| place.id == arc.target_id}
254
- end.compact.uniq
291
+ _places = find_all_places_by_source_id(transition_id)
255
292
 
256
293
  # the result shouldn't be ambiguous
257
294
  if _places.size > 1
@@ -271,8 +308,13 @@ module Pione
271
308
  _arcs = arcs.select {|arc| arc.source_id == transition_id}
272
309
  _places = _arcs.map do |arc|
273
310
  places.find {|place| place.id == arc.target_id}
311
+ end.compact.uniq
312
+
313
+ if block_given?
314
+ _places.each {|place| yield place}
315
+ else
316
+ return _places
274
317
  end
275
- return _places.compact.uniq
276
318
  end
277
319
 
278
320
  # Find a place by the target transition ID.
@@ -282,10 +324,7 @@ module Pione
282
324
  # @return [Array<Transition>]
283
325
  # result places
284
326
  def find_place_by_target_id(transition_id)
285
- _arcs = arcs.select {|arc| arc.target_id == transition_id}
286
- _places = _arcs.map do |arc|
287
- places.find {|place| place.id == arc.source_id}
288
- end.compact.uniq
327
+ _places = find_all_places_by_target_id(transition_id)
289
328
 
290
329
  # the result shouldn't be ambiguous
291
330
  if _places.size > 1
@@ -305,25 +344,18 @@ module Pione
305
344
  _arcs = arcs.select {|arc| arc.target_id == transition_id}
306
345
  _places = _arcs.map do |arc|
307
346
  places.find {|place| place.id == arc.source_id}
347
+ end.compact.uniq
348
+
349
+ if block_given?
350
+ _places.each {|place| yield place}
351
+ else
352
+ return _places
308
353
  end
309
- return _places.compact.uniq
310
354
  end
311
355
  end
312
356
 
313
357
  # `Node` is a meta class for `Place` and `Transition`.
314
358
  class Node < StructX
315
- # Eliminate comments from the string. This implementation is temporary, we
316
- # should fix this.
317
- def eliminate_comment(str)
318
- # FIXME
319
- str.sub(/#.*$/, "")
320
- end
321
-
322
- # Return true if the name is empty.
323
- def empty_name?
324
- name.nil? or /^\s*[<>]?\s*$/.match(eliminate_comment(name))
325
- end
326
-
327
359
  def inspect
328
360
  "#<%s id=%s name=%s>" % [self.class.name, id.inspect, name.inspect]
329
361
  end
@@ -0,0 +1,42 @@
1
+ module Pione
2
+ module PNML
3
+ # TicketInstantiation is a net rewriting rule for ticket operation
4
+ # ">>>". This rule replaces anonymous ticket operations into named tickets.
5
+ # Net like this
6
+ #
7
+ # A --> >>> --> B
8
+ #
9
+ # is replaced
10
+ #
11
+ # A --> ticket <__TICKET_FROM_A_TO_B__> --> B
12
+ #
13
+ module TicketInstantiation
14
+ TICKET_NAME = "__TICKET_FROM_%s_TO_%s__"
15
+
16
+ def self.find_subjects(net, env)
17
+ net.places.each do |place|
18
+ next unless place.name.strip == ">>>"
19
+
20
+ net.find_all_transitions_by_target_id(place.id) do |transition_from|
21
+ net.find_all_transitions_by_source_id(place.id) do |transition_to|
22
+ return [transition_from, transition_to, place]
23
+ end
24
+ end
25
+ end
26
+
27
+ return nil
28
+ end
29
+
30
+ # Rewrite the net with subjects by the following way.
31
+ #
32
+ # - Change the place name
33
+ def self.rewrite(net, subjects, env)
34
+ transition_from, transition_to, place = subjects
35
+ name_from = Perspective.normalize_rule_name(transition_from.name)
36
+ name_to = Perspective.normalize_rule_name(transition_to.name)
37
+
38
+ place.name = "<%s>" % (TICKET_NAME % [name_from, name_to])
39
+ end
40
+ end
41
+ end
42
+ end
@@ -7,24 +7,46 @@ module Pione
7
7
  end
8
8
 
9
9
  attr_reader :working_directory
10
+ attr_reader :shell_script
10
11
 
11
12
  def initialize(param)
12
13
  super(param)
13
- @working_directory = Location[Global.working_directory_generator.mkdir]
14
- @env.variable_set(
15
- Lang::Variable.new("__WORKING_DIRECTORY__"),
16
- Lang::StringSequence.of(@working_directory.path.to_s)
17
- )
14
+
15
+ @working_directory = WorkingDirectory.new(@env, @base_location, @inputs)
16
+ @shell_script = ActionShellScript.new(@env, @working_directory, @rule_definition, @dry_run)
18
17
  end
19
18
 
20
19
  # Execute the action.
21
20
  def execute
22
21
  # prepare input files
23
- setup_working_directory
24
- # prepare shell script
25
- write_shell_script {|path| call_shell_script(path)}
22
+ @working_directory.import
23
+
24
+ # call shell script
25
+ sh = @shell_script.write
26
+ user_message(["-"*60, sh.split("\n"), "-"*60].flatten, 0, "SH")
27
+ result = @shell_script.call(@sesstion_id, @request_from, @client_ui)
28
+ unless result
29
+ # the case the script has errored
30
+ raise ActionError.new(self, @digest, @shell_script.stderr.read)
31
+ end
32
+
33
+ # handle stdout mode of outputs
34
+ copy_stdout_to_outputs(@shell_script.stdout)
35
+
26
36
  # collect outputs
27
- outputs = collect_outputs
37
+ output_conditions = @rule_condition.outputs.map {|condition| condition.eval(@env)}
38
+ outputs = @working_directory.collect_outputs(output_conditions).map.with_index do |names, i|
39
+ tuples = names.map {|name| make_output_tuple_with_time(name)}
40
+
41
+ # apply touch operation
42
+ apply_touch_operation(output_conditions[i], tuples) || tuples
43
+ end
44
+
45
+ # write data null if needed
46
+ outputs.each_with_index do |output, i|
47
+ write_data_null(output_conditions[i], outputs[i], i)
48
+ end
49
+
28
50
  # write output data
29
51
  write_output_data(outputs)
30
52
  # write tuples
@@ -35,25 +57,131 @@ module Pione
35
57
  write_other_resources
36
58
 
37
59
  # clear working directory
38
- @working_directory.delete
60
+ @working_directory.close
39
61
 
40
62
  # return tuples
41
63
  return outputs
42
64
  end
43
65
 
44
- # Setup the variable table with working directory in addition.
45
- def setup_variable_table
46
- super
66
+ # Make output tuple by name.
67
+ def make_output_tuple_with_time(name)
68
+ time = (@working_directory.location + name).mtime
69
+ location = make_output_location(name)
70
+ TupleSpace::DataTuple.new(name: name, domain: @domain_id, location: location, time: time)
71
+ end
72
+
73
+ # Copy stdout file in the working directory to outputs.
74
+ #
75
+ # @param stdout [Location]
76
+ # stdout file
77
+ # @return [void]
78
+ def copy_stdout_to_outputs(stdout)
79
+ if stdout.exist?
80
+ @rule_condition.outputs.map do |output|
81
+ condition = output.eval(@env)
82
+ if condition.output_mode == :stdout
83
+ condition.pieces.each do |piece|
84
+ stdout.copy(@working_directory.location + piece.pattern)
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
90
+
91
+ # Write output data with caching.
92
+ #
93
+ # @return [void]
94
+ def write_output_data(outputs)
95
+ outputs.flatten.compact.each do |output|
96
+ src = @working_directory.location + output.name
97
+ dest = output.location
98
+ System::FileCache.put(src, dest)
99
+ # copy the data to the caller's domain in file server
100
+ src.copy(dest)
101
+ end
102
+ end
103
+
104
+ # Write action environment information file.
105
+ def write_env_info
106
+ @env.variable_table.keys.map do |var|
107
+ val = @env.variable_get(var)
108
+ "%s: %s" % [var.name, val.textize]
109
+ end.tap {|x| (@working_directory.location + ".pione-env").create(x.join("\n"))}
110
+ end
47
111
 
48
- @variable_table.set(Variable.new("__BASE__"), PioneString.new(base_location.uri).to_seq)
49
- @variable_table.set(Variable.new("_"), PackageExprSequence.new([PackageExpr.new(@rule.package_name)]))
112
+ # Move other intermediate files to the domain location.
113
+ def write_other_resources
114
+ @working_directory.location.file_entries.each do |entry|
115
+ location = make_location(entry.path.basename, @domain_id)
116
+ begin
117
+ entry.move(location)
118
+ rescue => e
119
+ Log::SystemLog.warn("cannot move %s to %s: %s" % [entry.path, location, e.message])
120
+ end
121
+ end
122
+ end
123
+
124
+ # Writes output tuples into the tuple space server.
125
+ def write_output_tuples(outputs)
126
+ outputs.flatten.compact.each {|output| write(output)}
127
+ end
128
+ end
129
+
130
+ # WorkingDirectory is a directory that action rule executes the shell script.
131
+ class WorkingDirectory
132
+ def initialize(env, base_location, inputs)
133
+ @env = env
134
+ @dir = Location[Global.working_directory_generator.mkdir]
135
+ @base_location = base_location
136
+ @inputs = inputs
137
+ end
138
+
139
+ def location
140
+ @dir
50
141
  end
51
142
 
52
143
  # Synchronize input data into working directory.
53
- def setup_working_directory
144
+ def import
145
+ @env.variable_set(
146
+ Lang::Variable.new("__WORKING_DIRECTORY__"),
147
+ Lang::StringSequence.of(@dir.path.to_s)
148
+ )
149
+
150
+ import_inputs
151
+ import_bins
152
+ import_etc
153
+ end
154
+
155
+ # Collect output data by names from working directory.
156
+ #
157
+ # @param output_conditions [Condition]
158
+ # all output conditions of action rule
159
+ # @return [Array<Array<String>>]
160
+ # array of output filenames
161
+ def collect_outputs(output_conditions)
162
+ filenames = @dir.file_entries.map{|entry| entry.basename}
163
+ output_conditions.map do |condition|
164
+ case condition.distribution
165
+ when :all
166
+ filenames.select{|name| condition.match?(name)}
167
+ when :each
168
+ name = filenames.find {|name| condition.match?(name)}
169
+ name ? [name] : []
170
+ end
171
+ end
172
+ end
173
+
174
+ # Clear the working directory.
175
+ def close
176
+ @dir.delete
177
+ end
178
+
179
+ private
180
+
181
+ def import_inputs
54
182
  @inputs.flatten.each do |input|
55
183
  # get file path in working directory
56
- wd_location = @working_directory + input.name
184
+ wd_location = @dir + input.name
57
185
  # create a link to cache
58
186
  cache_location = System::FileCache.get(input.location)
59
187
  wd_location.path.make_symlink(cache_location.path)
@@ -61,12 +189,14 @@ module Pione
61
189
  raise RuleExecutionError.new(self)
62
190
  end
63
191
  end
192
+ end
64
193
 
194
+ def import_bins
65
195
  # FIXME: should not copy bin files in the package each time.
66
196
  bin = @base_location + "package" + "bin"
67
197
  if bin.exist?
68
198
  bin.entries.each do |entry|
69
- dest = @working_directory + "bin" + entry.basename
199
+ dest = @dir + "bin" + entry.basename
70
200
  unless dest.exist?
71
201
  # copy and set executable flag
72
202
  entry.copy(dest)
@@ -74,12 +204,14 @@ module Pione
74
204
  end
75
205
  end
76
206
  end
207
+ end
77
208
 
209
+ def import_etc
78
210
  # FIXME: should not copy files in the package each time
79
211
  file_dir = @base_location + "package" + "etc"
80
212
  if file_dir.exist?
81
213
  file_dir.entries.each do |entry|
82
- dest = @working_directory + "etc" + entry.basename
214
+ dest = @dir + "etc" + entry.basename
83
215
  unless dest.exist?
84
216
  # copy and unset executable flag
85
217
  entry.copy(dest)
@@ -88,147 +220,92 @@ module Pione
88
220
  end
89
221
  end
90
222
  end
223
+ end
224
+
225
+ # ActionShellScript handles action rule's shell script.
226
+ class ActionShellScript
227
+ attr_reader :location
228
+
229
+ def initialize(env, working_directory, rule_definition, dry_run)
230
+ @env = env
231
+ @working_directory = working_directory
232
+ @rule_definition = rule_definition
233
+ @dry_run = dry_run
234
+ @location = @working_directory.location + "__pione__.sh"
235
+ end
91
236
 
92
- # Write the action into a shell script.
93
- def write_shell_script(&b)
94
- file = @working_directory + "__pione__.sh"
237
+ # Write the rule action into a shell script.
238
+ #
239
+ # @return [String]
240
+ # written shell script
241
+ def write
95
242
  content = @rule_definition.action_context.eval(@env).content
96
243
  sh = Util::EmbededExprExpander.expand(@env, content)
97
244
 
98
245
  # write the action
99
246
  if @dry_run
100
- @rule.outputs.flatten.each do |output|
101
- file.create("touch %s" % output.eval(@env).name)
247
+ rule_condition = @rule_definition.rule_condition_context.eval(@env)
248
+ rule_definition.outputs.flatten.each do |output|
249
+ @location.append("touch %s" % output.eval(@env).pieces.first.pattern)
102
250
  end
103
251
  else
104
- file.create(sh)
105
-
106
- # chmod 700
107
- if @working_directory.scheme == "local"
108
- FileUtils.chmod(0700, file.path)
109
- end
252
+ @location.create(sh)
110
253
  end
111
254
 
112
- # message
113
- user_message(["-"*60, sh.split("\n"), "-"*60].flatten, 0, "SH")
255
+ # chmod 700
256
+ if @working_directory.location.scheme == "local"
257
+ FileUtils.chmod(0700, @location.path)
258
+ end
114
259
 
115
- return b.call(file.path)
260
+ return sh
116
261
  end
117
262
 
118
- # Call shell script of the path.
119
- def call_shell_script(path)
120
- scriptname = File.basename(path)
121
-
122
- # stdout & stderr
123
- rule_condition = @rule_definition.rule_condition_context.eval(@env)
124
- output_conditions = rule_condition.outputs.map {|output| output.eval(@env)}
125
- stdout = output_conditions.find{|output| output.output_mode == :stdout}
126
- out = stdout ? stdout.pieces.first.pattern : ".stdout"
127
- err = ".stderr"
128
-
129
- # execute command
130
- # `cd #{}; PATH=#{(@working_directory + "bin").path}:$PATH; ./#{scriptname} > #{out} 2> #{err}`
263
+ # Call the shell script.
264
+ #
265
+ # @param session_id [String]
266
+ # session id
267
+ # @param request_from [String]
268
+ # address of the client that task requested
269
+ # @param client_ui [String]
270
+ # UI type of the client
271
+ # @return [void]
272
+ def call(session_id, request_from, client_ui)
131
273
  callee_env = {
132
- "PATH" => (@working_directory + "bin").path.to_s + ";" + ENV["PATH"],
133
- "PIONE_SESSION_ID" => @session_id,
134
- "PIONE_REQUEST_FROM" => @request_from.to_s,
135
- "PIONE_CLIENT_UI" => @client_ui.to_s
274
+ "PATH" => (@working_directory.location + "bin").path.to_s + ":" + ENV["PATH"],
275
+ "PIONE_SESSION_ID" => session_id,
276
+ "PIONE_REQUEST_FROM" => request_from.to_s,
277
+ "PIONE_CLIENT_UI" => client_ui.to_s
136
278
  }
137
- command = "./#{scriptname} > #{out} 2> #{err}"
138
- options = {:chdir => @working_directory.path.to_s}
279
+ command = "./#{@location.basename} > #{stdout.basename} 2> #{stderr.basename}"
280
+ options = {:chdir => @working_directory.location.path.to_s}
139
281
 
282
+ # execute command
140
283
  system(callee_env, command, options)
141
284
 
142
- # the case the script has errored
143
- unless $?.success?
144
- raise ActionError.new(self, digest, (@working_directory + err).read)
145
- end
146
-
147
- # delete .stdout file if it is empty
148
- if stdout.nil? and (@working_directory + out).size == 0
149
- (@working_directory + out).delete
150
- end
151
-
152
- # delete .stderr file if it is emtpy
153
- if (@working_directory + err).size == 0
154
- (@working_directory + err).delete
285
+ result = $?.success?
286
+ if result
287
+ # delete .stderr and .stdout files if they are empty
288
+ stdout.delete if stdout.size == 0
289
+ stderr.delete if stderr.size == 0
155
290
  end
291
+ return result
292
+ #end
156
293
  end
157
294
 
158
- # Make output tuple by name.
159
- def make_output_tuple_with_time(name)
160
- time = (@working_directory + name).mtime
161
- location = make_output_location(name)
162
- TupleSpace::DataTuple.new(name: name, domain: @domain_id, location: location, time: time)
163
- end
164
-
165
- # Collect output data by names from working directory.
295
+ # Return the location of stdout file.
166
296
  #
167
- # @return [void]
168
- def collect_outputs
169
- outputs = []
170
- filenames = @working_directory.file_entries.map{|entry| entry.path.basename.to_s}
171
- @rule_condition.outputs.each_with_index do |condition, i|
172
- _condition = condition.eval(@env)
173
- case _condition.distribution
174
- when :all
175
- outputs[i] = filenames.select{|name| _condition.match?(name)}.map do |name|
176
- make_output_tuple_with_time(name)
177
- end
178
- when :each
179
- if name = filenames.find {|name| _condition.match?(name)}
180
- outputs[i] = [make_output_tuple_with_time(name)]
181
- end
182
- end
183
-
184
- # apply touch operation
185
- if tuple = apply_touch_operation(_condition, outputs[i])
186
- outputs[i] = tuple
187
- end
188
-
189
- # write data null if needed
190
- write_data_null(_condition, outputs[i], i)
191
- end
192
-
193
- return outputs
297
+ # @return [Location]
298
+ # location of stdout file
299
+ def stdout
300
+ @working_directory.location + ".stdout"
194
301
  end
195
302
 
196
- # Write output data with caching.
303
+ # Return the location of stderr file.
197
304
  #
198
- # @return [void]
199
- def write_output_data(outputs)
200
- outputs.flatten.compact.each do |output|
201
- src = @working_directory + output.name
202
- dest = output.location
203
- System::FileCache.put(src, dest)
204
- # copy the data to the caller's domain in file server
205
- src.copy(dest)
206
- end
207
- end
208
-
209
- # Write action environment information file.
210
- def write_env_info
211
- @env.variable_table.keys.map do |var|
212
- val = @env.variable_get(var)
213
- "%s: %s" % [var.name, val.textize]
214
- end.tap {|x| (@working_directory + ".pione-env").create(x.join("\n"))}
215
- end
216
-
217
- # Move other intermediate files to the domain location.
218
- def write_other_resources
219
- @working_directory.file_entries.each do |entry|
220
- location = make_location(entry.path.basename, @domain_id)
221
- begin
222
- entry.move(location)
223
- rescue => e
224
- Log::SystemLog.warn("cannot move %s to %s: %s" % [entry.path, location, e.message])
225
- end
226
- end
227
- end
228
-
229
- # Writes output tuples into the tuple space server.
230
- def write_output_tuples(outputs)
231
- outputs.flatten.compact.each {|output| write(output)}
305
+ # @return [Locaiton]
306
+ # location of stderr file
307
+ def stderr
308
+ @working_directory.location + ".stderr"
232
309
  end
233
310
  end
234
311
  end