-
Notifications
You must be signed in to change notification settings - Fork 16
Description
Disclaimer: I'm relatively new to R6 and PhantomJS
Would it make sense to create a small R6 subclass of process for the return value of run_phantomjs()?
As I'm envisioning it, the class (i.e. Phantom) would just additional fields for port and (possibly) host, and a session instantiation method (i.e. phtm <- Phantom$new(); sesh <- phtm$session()). Additional methods could be added to make life easier for the user, but wouldn't be required for a basic implementation.
Pros
- Reference Semantics: Since the main functionality of the package is already in the
SessionR6 class, it seems like it would make sense to keep those reference semantics for the PhantomJS process as well (especially sinceprocessis already an R6 class). - Object Relations:
Sessions only work when connected to a PhantomJS process. This is currently not clear from the implementation alone (although admittedly likely an easy guess for the target user of webdriver). Spawning aSessionfrom an instantiatedPhantomobject makes this relationship much clearer (whether by passing thePhantomobject toSession$new()or by creating aPhantom$session()method). As a bonus, the user doesn't need to extract information from the object- it just works. - Browsing Experience: The above deals with relations between object in R. A closely related point is that these semantics also mimic what's actually happening in the background in the PhantomJS process, as well as roughly mimicking the experience of browsing with tabs. To me, this makes the user experience more transparent and conceptually cleaner.
Cons
- Breaking Change: The main issue I see is that this has to be a breaking change from the current
listimplementation in cases where theprocessorportis accessed by position (i.e.proc <- pjs[[1]]) or to return another list (port_lst <- pjs['port']). Notably, this does not break accessingportby name using$or[[. Compatibility with accessingprocessusing the same methods can also be maintained with aprocessfield that returnsself. I'm also not entirely sure what the use case for returning a length 1 list is here, so maybe that's less of an issue. - Reference Semantics: It's worth noting that many R users aren't very comfortable with OOP and modify-in-place semantics, so the first Pro is also a Con. With the current list implementation, I don't ever need to know that the list contains an R6
processobject; I just get theport, stick it inSession$new(), and go. Granted, I don't find this a convincing argument, since you need to use the R6Sessionclass to actually do anything in webdriver anyway.
One last point; if you find this convincing, it may make more sense to create a general WebDriver or Driver class, rather than a Phantom class, that could be extended for use with backends other than PhantomJS. I'm not sure what the roadmap/timeline (if any) is for those extensions, just that theoretical support is mentioned in the README, and there are a few related open issues.