From: ara.t.howard@... Date: 2007-02-07T01:49:09+09:00 Subject: Re: Fwd: Ruby Quiz Corrections ---1400102478-653386089-1170780526=:18133 Content-Type: MULTIPART/MIXED; BOUNDARY="-1400102478-653386089-1170780526=:18133" This message is in MIME format. The first part should be readable text, while the remaining parts are likely unreadable without MIME-aware tools. ---1400102478-653386089-1170780526=:18133 Content-Type: TEXT/PLAIN; CHARSET=US-ASCII; FORMAT=flowed Content-ID: On Tue, 6 Feb 2007, James Edward Gray II wrote: > Some new coverage of an old but favorite quiz. thanks james > > Begin forwarded message: > >> From: Ryan Kinderman >> Date: February 5, 2007 10:38:35 PM CST >> To: suggestion@rubyquiz.com >> Subject: Ruby Quiz Corrections >> >> I'm not sure if this is the right place to send this, so I apologize if >> it's not. I recently solved Quiz #67: metakoans.rb (I know, I'm a bit >> behind). Anyways, I think that the koans are missing or have incorrect >> assertions. >> >> I'm not sure if you post corrections, or if you can forward this on to the >> author, but I posted some of the problems that I discovered while solving >> the quiz at http://kinderman.net/articles/2007/02/05/ >> problems-with-the-metakoans-rb-ruby-quiz. hi ryan- yeah. interesting point. in fact, you are right but for reasons you might not suspect. regarding the assert{ (o.a = nil) == nil } assertions you'll note they all start when default values are being provided, what'd i'd meant to testing here was that the setter should always return the new value and not the one provided as a default. obviously that's a mistake since, in ruby, setters always do this, one cannot change it: harp:~ > cat a.rb def a=(x) 42 end p(self.a = 'forty-two') harp:~ > ruby a.rb "forty-two" so the best thing would be to simple remove those test or, as you point out, do a two step test. i chose the latter for the new version. regarding incrementing 42 - that's impossible! ;-) see if you like my new approach. it acheives the same end goal, which is valuable: harp: ~> cat a.rb # # metakoans.rb is an arduous set of exercises designed to stretch # meta-programming muscle. the focus is on a single method 'attribute' which # behaves much like the built-in 'attr', but whose properties require deleving # deep into the depths of meta-ruby. usage of the 'attribute' method follows # the general form of # # class C # attribute 'a' # end # # o = C::new # o.a = 42 # setter # o.a # getter # o.a? # query # # but reaches much farther than the standard 'attr' method as you will see # shortly. # # your path, should you choose to follow it, is to write a single file # 'knowledge.rb' implementing all functionality required by the koans below. # as a student of meta-programming your course will be guided by a guru whose # wisdom and pithy sayings will assist you on your journey. # # a successful student will eventually be able to do this # # harp:~ > ruby metakoans.rb knowledge.rb # koan_1 has expanded your awareness # koan_2 has expanded your awareness # koan_3 has expanded your awareness # koan_4 has expanded your awareness # koan_5 has expanded your awareness # koan_6 has expanded your awareness # koan_7 has expanded your awareness # koan_8 has expanded your awareness # koan_9 has expanded your awareness # mountains are again merely mountains # module MetaKoans # # 'attribute' must provide getter, setter, and query to instances # def koan_1 c = Class::new { attribute 'a' } o = c::new assert{ not o.a? } assert{ o.a = 31 } assert{ o.a == 31 } assert{ o.a? } end # # 'attribute' must provide getter, setter, and query to classes # def koan_2 c = Class::new { class << self attribute 'a' end } assert{ not c.a? } assert{ c.a = 32 } assert{ c.a == 32 } assert{ c.a? } end # # 'attribute' must provide getter, setter, and query to modules at module # level # def koan_3 m = Module::new { class << self attribute 'a' end } assert{ not m.a? } assert{ m.a = 33 } assert{ m.a == 33 } assert{ m.a? } end # # 'attribute' must provide getter, setter, and query to modules which operate # corectly when they are included by or extend objects # def koan_4 m = Module::new { attribute 'a' } c = Class::new { include m extend m } o = c::new assert{ not o.a? } assert{ o.a = 34 } assert{ o.a == 34 } assert{ o.a? } assert{ not c.a? } assert{ c.a = 35 } assert{ c.a == 35 } assert{ c.a? } end # # 'attribute' must provide getter, setter, and query to singleton objects # def koan_5 o = Object::new class << o attribute 'a' end assert{ not o.a? } assert{ o.a = 36 } assert{ o.a == 36 } assert{ o.a? } end # # 'attribute' must provide a method for providing a default value as hash # def koan_6 c = Class::new { attribute 'a' => 37 } o = c::new assert{ o.a == 37 } assert{ o.a? } assert{ o.a = nil; o.a == nil } assert{ not o.a? } end # # 'attribute' must provide a method for providing a default value as block # which is evaluated at instance level # def koan_7 c = Class::new { attribute('a'){ b } def b 38 end } o = c::new assert{ o.b == 38 } assert{ o.a == 38 } assert{ o.a? } assert{ o.a = nil; o.a == nil } assert{ not o.a? } assert{ o.b == 38 } end # # 'attribute' must provide inheritence of default values at both class and # instance levels # def koan_8 b = Class::new { class << self attribute 'a' => 39 attribute('b'){ a } end attribute 'a' => 40 attribute('b'){ a } } c = Class::new b assert{ c.b == 39 } assert{ c.a == 39 } assert{ c.a? } assert{ c.a = nil; c.a == nil } assert{ not c.a? } assert{ c.b == 39 } o = c::new assert{ o.b == 40 } assert{ o.a == 40 } assert{ o.a? } assert{ o.a = nil; o.a == nil } assert{ not o.a? } assert{ o.b == 40 } end # # into the void # def koan_9 b = Class::new { class << self attribute 'a' => 41 attribute('b'){ a } end include Module::new { attribute 'a' => 42 attribute('b'){ a } } } c = Class::new b assert{ c.b == 41 } assert{ c.a == 41 } assert{ c.a? } assert{ c.a = nil; c.a == nil } assert{ not c.a? } assert{ c.b == 41 } o = c::new assert{ o.b == 42 } assert{ o.a == 42 } assert{ o.a? } assert{ o.a = nil; o.a == nil } assert{ not o.a? } assert{ o.b == 42 } end def assert() raise unless yield end end class MetaStudent def initialize knowledge require knowledge end def ponder koan begin send koan true rescue => e STDERR.puts %Q[#{ e.message } (#{ e.class })\n#{ e.backtrace.join 10.chr }] false end end end class MetaGuru require "singleton" include Singleton def enlighten student student.extend MetaKoans koans = student.methods.grep(%r/koan/).sort attainment = nil koans.each do |koan| awakened = student.ponder koan if awakened puts "#{ koan } has expanded your awareness" attainment = koan else puts "#{ koan } still requires meditation" break end end puts( case attainment when nil "mountains are merely mountains" when 'koan_1', 'koan_2' "learn the rules so you know how to break them properly" when 'koan_3', 'koan_4' "remember that silence is sometimes the best answer" when 'koan_5', 'koan_6' "sleep is the best meditation" when 'koan_7' "when you lose, don't lose the lesson" when 'koan_8' "things are not what they appear to be: nor are they otherwise" else "mountains are again merely mountains" end ) end def self::method_missing m, *a, &b instance.send m, *a, &b end end knowledge = ARGV.shift or abort "#{ $0 } knowledge.rb" student = MetaStudent::new knowledge MetaGuru.enlighten student -a -- we can deny everything, except that we have the possibility of being better. simply reflect on that. - the dalai lama ---1400102478-653386089-1170780526=:18133 Content-Type: TEXT/PLAIN; CHARSET=US-ASCII; NAME=a.rb Content-Transfer-Encoding: BASE64 Content-ID: Content-Description: Content-Disposition: ATTACHMENT; FILENAME=a.rb Iw0KIyBtZXRha29hbnMucmIgaXMgYW4gYXJkdW91cyBzZXQgb2YgZXhlcmNp c2VzIGRlc2lnbmVkIHRvIHN0cmV0Y2gNCiMgbWV0YS1wcm9ncmFtbWluZyBt dXNjbGUuICB0aGUgZm9jdXMgaXMgb24gYSBzaW5nbGUgbWV0aG9kICdhdHRy aWJ1dGUnIHdoaWNoDQojIGJlaGF2ZXMgbXVjaCBsaWtlIHRoZSBidWlsdC1p biAnYXR0cicsIGJ1dCB3aG9zZSBwcm9wZXJ0aWVzIHJlcXVpcmUgZGVsZXZp bmcNCiMgZGVlcCBpbnRvIHRoZSBkZXB0aHMgb2YgbWV0YS1ydWJ5LiAgdXNh Z2Ugb2YgdGhlICdhdHRyaWJ1dGUnIG1ldGhvZCBmb2xsb3dzDQojIHRoZSBn ZW5lcmFsIGZvcm0gb2YNCiMgICANCiMgICBjbGFzcyBDDQojICAgICBhdHRy aWJ1dGUgJ2EnDQojICAgZW5kDQojICAgDQojICAgbyA9IEM6Om5ldw0KIyAg IG8uYSA9IDQyICAjIHNldHRlcg0KIyAgIG8uYSAgICAgICAjIGdldHRlciAN CiMgICBvLmE/ICAgICAgIyBxdWVyeSANCiMgICANCiMgYnV0IHJlYWNoZXMg bXVjaCBmYXJ0aGVyIHRoYW4gdGhlIHN0YW5kYXJkICdhdHRyJyBtZXRob2Qg YXMgeW91IHdpbGwgc2VlDQojIHNob3J0bHkuDQojICAgDQojIHlvdXIgcGF0 aCwgc2hvdWxkIHlvdSBjaG9vc2UgdG8gZm9sbG93IGl0LCBpcyB0byB3cml0 ZSBhIHNpbmdsZSBmaWxlDQojICdrbm93bGVkZ2UucmInIGltcGxlbWVudGlu ZyBhbGwgZnVuY3Rpb25hbGl0eSByZXF1aXJlZCBieSB0aGUga29hbnMgYmVs b3cuDQojIGFzIGEgc3R1ZGVudCBvZiBtZXRhLXByb2dyYW1taW5nIHlvdXIg Y291cnNlIHdpbGwgYmUgZ3VpZGVkIGJ5IGEgZ3VydSB3aG9zZQ0KIyB3aXNk b20gYW5kIHBpdGh5IHNheWluZ3Mgd2lsbCBhc3Npc3QgeW91IG9uIHlvdXIg am91cm5leS4NCiMgICANCiMgYSBzdWNjZXNzZnVsIHN0dWRlbnQgd2lsbCBl dmVudHVhbGx5IGJlIGFibGUgdG8gZG8gdGhpcyAgIA0KIyAgIA0KIyAgIGhh cnA6fiA+IHJ1YnkgbWV0YWtvYW5zLnJiIGtub3dsZWRnZS5yYg0KIyAgIGtv YW5fMSBoYXMgZXhwYW5kZWQgeW91ciBhd2FyZW5lc3MNCiMgICBrb2FuXzIg aGFzIGV4cGFuZGVkIHlvdXIgYXdhcmVuZXNzDQojICAga29hbl8zIGhhcyBl eHBhbmRlZCB5b3VyIGF3YXJlbmVzcw0KIyAgIGtvYW5fNCBoYXMgZXhwYW5k ZWQgeW91ciBhd2FyZW5lc3MNCiMgICBrb2FuXzUgaGFzIGV4cGFuZGVkIHlv dXIgYXdhcmVuZXNzDQojICAga29hbl82IGhhcyBleHBhbmRlZCB5b3VyIGF3 YXJlbmVzcw0KIyAgIGtvYW5fNyBoYXMgZXhwYW5kZWQgeW91ciBhd2FyZW5l c3MNCiMgICBrb2FuXzggaGFzIGV4cGFuZGVkIHlvdXIgYXdhcmVuZXNzDQoj ICAga29hbl85IGhhcyBleHBhbmRlZCB5b3VyIGF3YXJlbmVzcw0KIyAgIG1v dW50YWlucyBhcmUgYWdhaW4gbWVyZWx5IG1vdW50YWlucw0KIyAgIA0KDQoN Cm1vZHVsZSBNZXRhS29hbnMNCiMNCiMgJ2F0dHJpYnV0ZScgbXVzdCBwcm92 aWRlIGdldHRlciwgc2V0dGVyLCBhbmQgcXVlcnkgdG8gaW5zdGFuY2VzDQoj DQogIGRlZiBrb2FuXzENCiAgICBjID0gQ2xhc3M6Om5ldyB7DQogICAgICBh dHRyaWJ1dGUgJ2EnDQogICAgfQ0KDQogICAgbyA9IGM6Om5ldw0KDQogICAg YXNzZXJ0eyBub3Qgby5hPyB9DQogICAgYXNzZXJ0eyBvLmEgPSAzMSB9DQog ICAgYXNzZXJ0eyBvLmEgPT0gMzEgfQ0KICAgIGFzc2VydHsgby5hPyB9DQog IGVuZA0KIw0KIyAnYXR0cmlidXRlJyBtdXN0IHByb3ZpZGUgZ2V0dGVyLCBz ZXR0ZXIsIGFuZCBxdWVyeSB0byBjbGFzc2VzIA0KIw0KICBkZWYga29hbl8y DQogICAgYyA9IENsYXNzOjpuZXcgew0KICAgICAgY2xhc3MgPDwgc2VsZg0K ICAgICAgICBhdHRyaWJ1dGUgJ2EnDQogICAgICBlbmQNCiAgICB9DQoNCiAg ICBhc3NlcnR7IG5vdCBjLmE/IH0NCiAgICBhc3NlcnR7IGMuYSA9IDMyIH0N CiAgICBhc3NlcnR7IGMuYSA9PSAzMiB9DQogICAgYXNzZXJ0eyBjLmE/IH0N CiAgZW5kDQojDQojICdhdHRyaWJ1dGUnIG11c3QgcHJvdmlkZSBnZXR0ZXIs IHNldHRlciwgYW5kIHF1ZXJ5IHRvIG1vZHVsZXMgYXQgbW9kdWxlDQojIGxl dmVsDQojDQogIGRlZiBrb2FuXzMNCiAgICBtID0gTW9kdWxlOjpuZXcgew0K ICAgICAgY2xhc3MgPDwgc2VsZg0KICAgICAgICBhdHRyaWJ1dGUgJ2EnDQog ICAgICBlbmQNCiAgICB9DQoNCiAgICBhc3NlcnR7IG5vdCBtLmE/IH0NCiAg ICBhc3NlcnR7IG0uYSA9IDMzIH0NCiAgICBhc3NlcnR7IG0uYSA9PSAzMyB9 DQogICAgYXNzZXJ0eyBtLmE/IH0NCiAgZW5kDQojDQojICdhdHRyaWJ1dGUn IG11c3QgcHJvdmlkZSBnZXR0ZXIsIHNldHRlciwgYW5kIHF1ZXJ5IHRvIG1v ZHVsZXMgd2hpY2ggb3BlcmF0ZQ0KIyBjb3JlY3RseSB3aGVuIHRoZXkgYXJl IGluY2x1ZGVkIGJ5IG9yIGV4dGVuZCBvYmplY3RzDQojDQogIGRlZiBrb2Fu XzQNCiAgICBtID0gTW9kdWxlOjpuZXcgew0KICAgICAgYXR0cmlidXRlICdh Jw0KICAgIH0NCg0KICAgIGMgPSBDbGFzczo6bmV3IHsNCiAgICAgIGluY2x1 ZGUgbQ0KICAgICAgZXh0ZW5kIG0NCiAgICB9DQoNCiAgICBvID0gYzo6bmV3 DQoNCiAgICBhc3NlcnR7IG5vdCBvLmE/IH0NCiAgICBhc3NlcnR7IG8uYSA9 IDM0IH0NCiAgICBhc3NlcnR7IG8uYSA9PSAzNCB9DQogICAgYXNzZXJ0eyBv LmE/IH0NCg0KICAgIGFzc2VydHsgbm90IGMuYT8gfQ0KICAgIGFzc2VydHsg Yy5hID0gMzUgfQ0KICAgIGFzc2VydHsgYy5hID09IDM1IH0NCiAgICBhc3Nl cnR7IGMuYT8gfQ0KICBlbmQNCiMNCiMgJ2F0dHJpYnV0ZScgbXVzdCBwcm92 aWRlIGdldHRlciwgc2V0dGVyLCBhbmQgcXVlcnkgdG8gc2luZ2xldG9uIG9i amVjdHMgDQojDQogIGRlZiBrb2FuXzUNCiAgICBvID0gT2JqZWN0OjpuZXcN Cg0KICAgIGNsYXNzIDw8IG8NCiAgICAgIGF0dHJpYnV0ZSAnYScNCiAgICBl bmQNCg0KICAgIGFzc2VydHsgbm90IG8uYT8gfQ0KICAgIGFzc2VydHsgby5h ID0gMzYgfQ0KICAgIGFzc2VydHsgby5hID09IDM2IH0NCiAgICBhc3NlcnR7 IG8uYT8gfQ0KICBlbmQNCiMNCiMgJ2F0dHJpYnV0ZScgbXVzdCBwcm92aWRl IGEgbWV0aG9kIGZvciBwcm92aWRpbmcgYSBkZWZhdWx0IHZhbHVlIGFzIGhh c2gNCiMNCiAgZGVmIGtvYW5fNg0KICAgIGMgPSBDbGFzczo6bmV3IHsNCiAg ICAgIGF0dHJpYnV0ZSAnYScgPT4gMzcgDQogICAgfQ0KDQogICAgbyA9IGM6 Om5ldw0KDQogICAgYXNzZXJ0eyBvLmEgPT0gMzcgfQ0KICAgIGFzc2VydHsg by5hPyB9DQogICAgYXNzZXJ0eyBvLmEgPSBuaWw7IG8uYSA9PSBuaWwgfQ0K ICAgIGFzc2VydHsgbm90IG8uYT8gfQ0KICBlbmQNCiMNCiMgJ2F0dHJpYnV0 ZScgbXVzdCBwcm92aWRlIGEgbWV0aG9kIGZvciBwcm92aWRpbmcgYSBkZWZh dWx0IHZhbHVlIGFzIGJsb2NrDQojIHdoaWNoIGlzIGV2YWx1YXRlZCBhdCBp bnN0YW5jZSBsZXZlbCANCiMNCiAgZGVmIGtvYW5fNw0KICAgIGMgPSBDbGFz czo6bmV3IHsNCiAgICAgIGF0dHJpYnV0ZSgnYScpeyBiIH0NCiAgICAgIGRl ZiBiIA0KICAgICAgICAzOA0KICAgICAgZW5kDQogICAgfQ0KDQogICAgbyA9 IGM6Om5ldw0KDQogICAgYXNzZXJ0eyBvLmIgPT0gMzggfQ0KICAgIGFzc2Vy dHsgby5hID09IDM4IH0NCiAgICBhc3NlcnR7IG8uYT8gfQ0KICAgIGFzc2Vy dHsgby5hID0gbmlsOyBvLmEgPT0gbmlsIH0NCiAgICBhc3NlcnR7IG5vdCBv LmE/IH0NCiAgICBhc3NlcnR7IG8uYiA9PSAzOCB9DQogIGVuZA0KIw0KIyAn YXR0cmlidXRlJyBtdXN0IHByb3ZpZGUgaW5oZXJpdGVuY2Ugb2YgZGVmYXVs dCB2YWx1ZXMgYXQgYm90aCBjbGFzcyBhbmQNCiMgaW5zdGFuY2UgbGV2ZWxz DQojDQogIGRlZiBrb2FuXzgNCiAgICBiID0gQ2xhc3M6Om5ldyB7DQogICAg ICBjbGFzcyA8PCBzZWxmDQogICAgICAgIGF0dHJpYnV0ZSAnYScgPT4gMzkg DQogICAgICAgIGF0dHJpYnV0ZSgnYicpeyBhIH0NCiAgICAgIGVuZA0KICAg ICAgYXR0cmlidXRlICdhJyA9PiA0MA0KICAgICAgYXR0cmlidXRlKCdiJyl7 IGEgfQ0KICAgIH0NCg0KICAgIGMgPSBDbGFzczo6bmV3IGINCg0KICAgIGFz c2VydHsgYy5iID09IDM5IH0NCiAgICBhc3NlcnR7IGMuYSA9PSAzOSB9DQog ICAgYXNzZXJ0eyBjLmE/IH0NCiAgICBhc3NlcnR7IGMuYSA9IG5pbDsgYy5h ID09IG5pbCB9DQogICAgYXNzZXJ0eyBub3QgYy5hPyB9DQogICAgYXNzZXJ0 eyBjLmIgPT0gMzkgfQ0KDQogICAgbyA9IGM6Om5ldw0KDQogICAgYXNzZXJ0 eyBvLmIgPT0gNDAgfQ0KICAgIGFzc2VydHsgby5hID09IDQwIH0NCiAgICBh c3NlcnR7IG8uYT8gfQ0KICAgIGFzc2VydHsgby5hID0gbmlsOyBvLmEgPT0g bmlsIH0NCiAgICBhc3NlcnR7IG5vdCBvLmE/IH0NCiAgICBhc3NlcnR7IG8u YiA9PSA0MCB9DQogIGVuZA0KIw0KIyBpbnRvIHRoZSB2b2lkIA0KIw0KICBk ZWYga29hbl85DQogICAgYiA9IENsYXNzOjpuZXcgew0KICAgICAgY2xhc3Mg PDwgc2VsZg0KICAgICAgICBhdHRyaWJ1dGUgJ2EnID0+IDQxDQogICAgICAg IGF0dHJpYnV0ZSgnYicpeyBhIH0NCiAgICAgIGVuZA0KICAgICAgaW5jbHVk ZSBNb2R1bGU6Om5ldyB7DQogICAgICAgIGF0dHJpYnV0ZSAnYScgPT4gNDIN CiAgICAgICAgYXR0cmlidXRlKCdiJyl7IGEgfQ0KICAgICAgfQ0KICAgIH0N Cg0KICAgIGMgPSBDbGFzczo6bmV3IGINCg0KICAgIGFzc2VydHsgYy5iID09 IDQxIH0NCiAgICBhc3NlcnR7IGMuYSA9PSA0MSB9DQogICAgYXNzZXJ0eyBj LmE/IH0NCiAgICBhc3NlcnR7IGMuYSA9IG5pbDsgYy5hID09IG5pbCB9DQog ICAgYXNzZXJ0eyBub3QgYy5hPyB9DQogICAgYXNzZXJ0eyBjLmIgPT0gNDEg fQ0KDQogICAgbyA9IGM6Om5ldw0KDQogICAgYXNzZXJ0eyBvLmIgPT0gNDIg fQ0KICAgIGFzc2VydHsgby5hID09IDQyIH0NCiAgICBhc3NlcnR7IG8uYT8g fQ0KICAgIGFzc2VydHsgby5hID0gbmlsOyBvLmEgPT0gbmlsIH0NCiAgICBh c3NlcnR7IG5vdCBvLmE/IH0NCiAgICBhc3NlcnR7IG8uYiA9PSA0MiB9DQog IGVuZA0KDQogIGRlZiBhc3NlcnQoKSByYWlzZSB1bmxlc3MgeWllbGQgZW5k DQplbmQNCg0KDQpjbGFzcyBNZXRhU3R1ZGVudA0KICBkZWYgaW5pdGlhbGl6 ZSBrbm93bGVkZ2UNCiAgICByZXF1aXJlIGtub3dsZWRnZQ0KICBlbmQNCiAg ZGVmIHBvbmRlciBrb2FuDQogICAgYmVnaW4NCiAgICAgIHNlbmQga29hbg0K ICAgICAgdHJ1ZQ0KICAgIHJlc2N1ZSA9PiBlDQogICAgICBTVERFUlIucHV0 cyAlUVsjeyBlLm1lc3NhZ2UgfSAoI3sgZS5jbGFzcyB9KVxuI3sgZS5iYWNr dHJhY2Uuam9pbiAxMC5jaHIgfV0NCiAgICAgIGZhbHNlDQogICAgZW5kDQog IGVuZA0KZW5kDQoNCg0KY2xhc3MgTWV0YUd1cnUNCiAgcmVxdWlyZSAic2lu Z2xldG9uIg0KICBpbmNsdWRlIFNpbmdsZXRvbg0KDQogIGRlZiBlbmxpZ2h0 ZW4gc3R1ZGVudA0KICAgIHN0dWRlbnQuZXh0ZW5kIE1ldGFLb2Fucw0KDQog ICAga29hbnMgPSBzdHVkZW50Lm1ldGhvZHMuZ3JlcCglci9rb2FuLykuc29y dA0KDQogICAgYXR0YWlubWVudCA9IG5pbA0KDQogICAga29hbnMuZWFjaCBk byB8a29hbnwgDQogICAgICBhd2FrZW5lZCA9IHN0dWRlbnQucG9uZGVyIGtv YW4NCiAgICAgIGlmIGF3YWtlbmVkDQogICAgICAgIHB1dHMgIiN7IGtvYW4g fSBoYXMgZXhwYW5kZWQgeW91ciBhd2FyZW5lc3MiDQogICAgICAgIGF0dGFp bm1lbnQgPSBrb2FuDQogICAgICBlbHNlDQogICAgICAgIHB1dHMgIiN7IGtv YW4gfSBzdGlsbCByZXF1aXJlcyBtZWRpdGF0aW9uIg0KICAgICAgICBicmVh aw0KICAgICAgZW5kDQogICAgZW5kDQoNCiAgICBwdXRzKA0KICAgICAgY2Fz ZSBhdHRhaW5tZW50DQogICAgICAgIHdoZW4gbmlsIA0KICAgICAgICAgICJt b3VudGFpbnMgYXJlIG1lcmVseSBtb3VudGFpbnMiDQogICAgICAgIHdoZW4g J2tvYW5fMScsICdrb2FuXzInDQogICAgICAgICAgImxlYXJuIHRoZSBydWxl cyBzbyB5b3Uga25vdyBob3cgdG8gYnJlYWsgdGhlbSBwcm9wZXJseSINCiAg ICAgICAgd2hlbiAna29hbl8zJywgJ2tvYW5fNCcNCiAgICAgICAgICAicmVt ZW1iZXIgdGhhdCBzaWxlbmNlIGlzIHNvbWV0aW1lcyB0aGUgYmVzdCBhbnN3 ZXIiDQogICAgICAgIHdoZW4gJ2tvYW5fNScsICdrb2FuXzYnDQogICAgICAg ICAgInNsZWVwIGlzIHRoZSBiZXN0IG1lZGl0YXRpb24iDQogICAgICAgIHdo ZW4gJ2tvYW5fNycNCiAgICAgICAgICAid2hlbiB5b3UgbG9zZSwgZG9uJ3Qg bG9zZSB0aGUgbGVzc29uIg0KICAgICAgICB3aGVuICdrb2FuXzgnDQogICAg ICAgICAgInRoaW5ncyBhcmUgbm90IHdoYXQgdGhleSBhcHBlYXIgdG8gYmU6 IG5vciBhcmUgdGhleSBvdGhlcndpc2UiDQogICAgICAgIGVsc2UNCiAgICAg ICAgICAibW91bnRhaW5zIGFyZSBhZ2FpbiBtZXJlbHkgbW91bnRhaW5zIg0K ICAgICAgZW5kDQogICAgKQ0KICBlbmQNCiAgZGVmIHNlbGY6Om1ldGhvZF9t aXNzaW5nIG0sICphLCAmYg0KICAgIGluc3RhbmNlLnNlbmQgbSwgKmEsICZi DQogIGVuZA0KZW5kDQoNCg0KDQprbm93bGVkZ2UgPSBBUkdWLnNoaWZ0IG9y IGFib3J0ICIjeyAkMCB9IGtub3dsZWRnZS5yYiINCnN0dWRlbnQgPSBNZXRh U3R1ZGVudDo6bmV3IGtub3dsZWRnZSANCk1ldGFHdXJ1LmVubGlnaHRlbiBz dHVkZW50DQo= ---1400102478-653386089-1170780526=:18133-- ---1400102478-653386089-1170780526=:18133--