Tuesday, February 16, 2016

In Which I Take Things One Step Too Far...


So the chain of responsibility pattern in Dart… I've explored it with noSuchMethod(). I've explored it with mixins. But I have yet to explore it with noSuchMethod() in mixins.

Things are gonna get a little crazy tonight.

I continue to work with the _PurchasePower mixin for employee-like classes. It describes the ability of an employee to make purchasing decisions. It sets the successor in the responsibility chain to point to the employee next on the corporate ladder:
abstract class _PurchasePower {
  get successor => reportsTo;
  // ...
}
In this case, it simply delegates to the reportsTo property of Employee—the receiver of the mixin.

The _PurchasePower mixin completes the chain of responsibility pattern by declaring processRequest(). This method sends the request to the successor if the current class does not handle it, and _processRequest(), which performs the actual handling of the request:
abstract class _PurchasePower {
  // ...
  void processRequest(PurchaseRequest request) {
    if (_processRequest(request)) return;
    if (successor == null) return;

    successor.processRequest(request);
  }

  bool _processRequest(_) => false;
}
That works great when there is only one request to handle, but what if there are multiple requests to be handled (e.g. processorName() and processRequest())?

This is where it would be handy to be able to mixin noSuchMethod(). Instead of declaring processRequest() to possibly send the request to the successor, noSuchMethod() can do so. Except I hit a stumbling block right away here.

First, I need to handle requests by converting processRequest() to _processRequest() and processorName() to _processorName(). Just prepend an underscore, right? Well, no.

When I get the arguments inside noSuchMethod, I can figure out the method that was being invoked by checking memberName. From here, it should be a simple matter of interpolating noSuchMethod's memberName into a string:
  noSuchMethod(args) {
    var handlerMethod = "_${args.memberName}";
    // ...
  }
The problem is that memberName is a Symbol, which gets converted to strings as "Symbol('symbol_name_here'). So the handlerMethod winds up being _Symbol('_processRequest'). Not at all what I want.

I have two undesirable choices here—strip Symbol(' and ') from the resulting string or painstakingly lookup the string value. Neither is a good option, but the latter seems to be the most official way:
  noSuchMethod(args) {
    var handlerMethod = "_${MirrorSystem.getName(args.memberName)}";
    // ...
  }
Yuck. And unfortunately, I am not done with the yuck. I cannot invoke methods with strings, so I have to convert that back to a Symbol:
  noSuchMethod(args) {
    Symbol handlerMethod = new Symbol("_${MirrorSystem.getName(args.memberName)}");
    // ...
  }
Even now, I am not done with the yuck. And this next yuckiness takes me a while to track down.

It turns out that you cannot use the Symbol constructor to create a symbol that is private. Well, that is not 100% true, it lets me create a symbol, but I am not allowed to use it to invoked the private method. Making this situation even more annoying is that I can invoke _processRequest() with a symbol literal: #_processRequest. But if I dynamically try to create that symbol, it silently fails to call the right method.

Bummer.

Even if I choose a different naming convention, I would not want the method that actually processes the request to be public. Only the method invoking the handler or sending the request to the successor should be public. So I am left to either move handler code into noSuchMethod() to sit beside the successor code or I can give the handler method a weird name.

I opt for the latter by prepending xxx_ to the name:
  noSuchMethod(args) {
    Symbol handlerMethod = new Symbol("xxx_${MirrorSystem.getName(args.memberName)}");
    // ...
  }
With this approach, I eventually get the code working, but... yuck.

Even if this were back in the Employee class, I would still face the same limitation from the Symbol constructor. In other words, this seems like an ill-advised approach in current Dart.

Play with the code on DartPad: https://dartpad.dartlang.org/9f9ca7397d88f6cf7e54.



Day #97

12 comments:

  1. Thanks for sharing, nice post! Post really provice useful information!

    Hương Lâm chuyên cung cấp máy photocopy, chúng tôi cung cấp máy photocopy ricoh, toshiba, canon, sharp, đặc biệt chúng tôi có cung cấp máy photocopy màu uy tín, giá rẻ nhất.

    ReplyDelete
  2. website. If you want 928bet to apply and inquire for more information, read football, complete lotteries, baccarat and online casinos

    ReplyDelete
  3. Nice post! The author seems to be quite sarcastic! But he is absolutely right. The company is the best when it comes to shifting and moving your favorite vehicle. It is true that LogisticsGuru provides an effective logistic solution when it comes to car Car Transport In Gurgaon . If you want to get more information about the company, please click on the link.

    ReplyDelete
  4. อยากเล่นเกมสล็อตออนไลน์ก็เชิญมาทางนี้ ทางเข้าเล่น pg pgslot168game มีเกมสล็อตให้เลือกเล่นได้หลายรูปแบบไม่ว่าจะ แนวกีฬา แนวยิงปืน แนวตกปลา และ ยิงไข่ ก็มีให้เลือกเล่นแบบไม่อั้นไม่มีเบื่อที่สามารถเล่นได้ตลอดทั้งวันแบบไม่มีกระตุกและทำให้หงุดหงิดแน่นอน

    ReplyDelete
  5. รวมเว็บ SPINIX สล็อตแตกหนัก สัมผัสกับความสนุกได้แบบไม่รู้จักจบ และแนวเกมที่ไม่ซ้ำใครลุ้นรับเงินรางวัลจำนวนมากได้เมื่อใดก็ตามได้เข้ามาสัมผัสเลือกเข้าเล่นเกม ที่แตกหน้าจัดหนักจัดเต็ม เงินรางวัลที่คุ้มเพิ่มขึ้นเรื่อยๆกว่าเดิม

    ReplyDelete
  6. แทงบอล เว็บเดียวจบครบทุกการเดิมพัน

    ReplyDelete
  7. มวยพักยก พวกเราได้สะสมไว้ให้เพื่อช่วยเหลือสำหรับเพื่อการใช้บริการพนันมวยสเต็ป

    ReplyDelete
  8. เปลี่ยนเป็นอีกหนึ่งทริคเล่นเกม สูตรสล็อต PG ที่นักลงทุนทุกคนพร้อมเลือกใช้งาน เพื่อคิดแผนเล่นเกมโดยตลอด ซึ่งในช่วงเวลานี้นับว่าเป็นอีกหนึ่งแบบเล่นเกมที่ช่วยปรับให้การวางเป้าหมายเล่นเกมรื้นเริงเพิ่มขึ้นเรื่อยๆหลายเท่าตัว ยิ่งกว่านั้นยังทำให้การเล่นเกมของทุกคนแปลงเป็นเรื่องง่าย เพราะว่าสามารถดูไกลถึงตำแหน่งผู้ชนะได้ง่ายมากยิ่งขึ้น สูตรสล็อต PG

    ReplyDelete
  9. แบ่งตามจำพวก. ครั้งฟต์เบียร์สดหอม, รายละเอียดสูงของสาโท, เข้มข้นเต็มรส, ค่าทางโภชนาการที่สูงขึ้นและราคาแพง. เบียร์สดความรู้ความเข้าใจจำนวนมากมีจำนวนแอลกอฮอล์มากยิ่งกว่า 11 องศา, รวมทั้งครั้งฟต์เบียร์สดบางแก้วก็ไปถึง 20 องศา.https://beer6.net/

    ReplyDelete