内容简介:.Unironically :-)This is a bit scary. On the one hand, Objective-Smalltalk has been in use in my own applications for well over a decade and runs the
.
Unironically :-)
This is a bit scary. On the one hand, Objective-Smalltalk has been in use in my own applications for well over a decade and runs the http://objective.st site, both without a hitch and the latter shrugging of a Hacker News "Hug of Death" without even the hint of glitch. On the other hand, well, it's scary.
As for usability, you include two frameworks in your application bundle, and the code to start up and interact with the interpreter or interpreters is also fairly minimal, not least of all because I've been doing so in quite a number of applications now, so inconvenience gets whittled away over time.
In terms of suitability, I of course can't answer that except for saying it is absolutely the best ever. I can also add that another macOS embeddable Smalltalk, FScript, was used successfully in a number of products. Anyway, Ilja was kind enough to at least pretend to take my suggestion seriously, and responded with the following question as to how code would look in practice:
It is not obvious to me how such a custom script in Objective-SmallTalk would look like. Here is a JavaScript pseudo-code example that ends & restarts certain listings. How would this look like in Obj-ST? pic.twitter.com/UjbwUD0Q4b
— Ilja A. Iwas (@iljawascoding) May 13, 2020I am only too happy to answer that question, but the answer is a bit beyond the scope of twitter, hence this blog post.
First, we can keep things very close to the original,
just replacing the loop with a -select:
and of course changing the syntax to Objective-Smalltalk.
runningListings := context getAllRunningListings. listingsToRelist := runningListings select:{ :listing | listing daysRunning > 30 and: listing watchers < 3 . } ebay endListings:listingsToRelist ended:{ :ended | ebay relistListings:ended relisted: { :relisted | ui alert:"Relisted: {relisted}". } }Note the use of "and:" instead of "&&" and the general reduction of sigils. Although I personally don't like the pyramid of doom
, the keyword message syntax makes it significantly less odious.
So much in fact, that Swift recently adopted open keyword syntax for the special case of multiple trailing closures. Of course the mind boggles a bit, but that's a topic for a separate post.
So how else can we simplify? Well, the context
seems a little unspecific, and getAllRunningListings
a bit specialized, it probably has lots of friends that
result from mapping a website with lots of resources onto
a procedural interface.
Let's instead use URLs for this, so an ebay:
scheme that encapsulates the resources that EBay lets
us play with.
listingsToRelist := ebay:listings/running select:{ :listing | listing daysRunning > 30 and: listing watchers < 3 . } ebay endListings:listingsToRelist ended:{ :ended | ebay relistListings:ended relisted: { :relisted | ui alert:"Relisted {relisted} listings". } }
I have to admit I also don't really understand the use of callbacks in the relisting process, as we are waiting for everything to complete before moving to the next stage. So let's just implement this as plain sequential code:
listingsToRelist := ebay:listings/running select:{ :listing | listing daysRunning > 30 and: listing watchers < 3 . } ended := ebay endListings:listingsToRelist. relisted := ebay relistListings:ended. ui alert:"Relisted: {relisted}".
(In scripting contexts, Objective-Smalltalk currently allows defining variables by assigning to them. This can be turned off.)
However, it seems odd and a bit non-OO that the listings
shouldn't know how to do stuff, so how about just having relist
and end
be methods on
the listings themselves? That way the code simplifies
to the following:
listingsToRelist := ebay:listings/running select:{ :listing | listing daysRunning > 30 and: listing watchers < 3 . } ended := listingsToRelist collect end. relisted := ended collect relist. ui alert:"Relisted: {relisted}".
If batch operations are typical, it probably makes sense to have a listings collection that understands about those operations:
listingsToRelist := ebay:listings/running select:{ :listing | listing daysRunning > 30 and: listing watchers < 3 . } ended := listingsToRelist end. relisted := ended relist. ui alert:"Relisted: {relisted}".
Here I am assuming that ending and relisting can fail and therefore these operations need to return the listings that succeeded.
Oh, and you might want to give that predicate a name, which then makes it possible to replace the last gobbledygook with a clean, "do what I mean" Higher Order Message. Oh, and since we've had Unicode for a while now, you can also use '←' for assignment, if you want.
extension EBayListing { -<bool>shouldRelist { self daysRunning > 30 and: self watchers < 3. } } listingsToRelist ← ebay:listings/running select shouldRelist. ended ← listingsToRelist end. relisted ← ended relist. ui alert:"Relisted: {relisted}".
To my obviously completely unbiased eyes, this looks pretty close to a high-level, pseudocode specification of the actions to be taken, except that it is executable.
This is a nice step-by-step script, but with everything so compact now, we can get rid of the temporary variables (assuming the extension) and make it a one-liner (plus the alert):
relisted ← ebay:listings/running select shouldRelist end relist. ui alert:"Relisted: {relisted}".
It should be noted that the one-liner came to be not as a result of sacrificing readability in order to maximally compress the code, but rather as an indirect result of improving readability by removing the cruft that's not really part of the problem being solved.
Although not needed in this case (the precedence rules of unary message sends make things unambiguous) some pipe separators may make things a bit more clear.
relisted ← ebay:listings/running select shouldRelist | end | relist. ui alert:"Relisted: {relisted}".
Whether you prefer the one-liner or the step-by-step is probably a matter of taste.
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。