Skip to content

How to enable Ruby like method chains in wx(Python) shell

komoto edited this page May 13, 2021 · 10 revisions

In Ruby, everything is an object. Every bit of information and code can be given their own properties and actions as an example below, (https://www.ruby-lang.org/en/about/)

rb> 5.times { print "We *love* Ruby -- it's outrageous!" }

Some of them have criticized Python as an inconsistent language. For example, Python uses mix of method and functions like sum((1,2,3,4j)).real. Ugly? No. Rather, I think, it is flexibility of Python, no inconsistency.

** Thoery **

I got an idea to make Python chainable like Ruby. To do that, one and only one quite simple rule was required, as follows;

x @ y => y(x)

Hence, we can chain methods as x @y @z => z(y(x)) I named this rule 'pullback' which comes from mathmatical terminology. Actually, this rule can chain not only the instance method but also ANY functions.

Here shows a simple example:

rb> p 5.times.to_a
[0, 1, 2, 3, 4]
py> 5 @range @list @p
[0, 1, 2, 3, 4]

You may notice that the printing function (p = print) is also chained. I have extended the wx.py.shell to allow chain of the functions as follows:

In the next example, you will see that methods and functions in any modules are chained.

shell-magic

Suppose `buf' is the binary data received from the image server. The input and output-code are like these:

# input:
>>> buf @io.BytesIO @Image.open @np.asarray @plt.imshow; plt.show()

# interpreted as:
==> plt.imshow(np.asarray(Image.open(io.BytesIO(buf)))); plt.show()

Also, note that we are pressing [C-j] (eval-expression) each time we chain to see if the py expression is correct.

Clone this wiki locally