Is object[x](y,z) always invalid?

I'm working on converting a Python module (RPy) to Ruby and am trying to keep the api as close to the original as possible. In Python it (appears - my Python is very weak) that this is valid syntax:

foo[x](y,z)

Where 'foo' is an object with attribute 'x' which itself is callable - in this case with the parameters 'y' and 'z'. The 'foo[x]' object is actually an R function and some magic is subsequently performed to convert the parameters and call the function from Python/Ruby.

SyntaxError in Ruby and the closest I can get in Ruby syntax to the Python is:

foo[x][y,z]

But this isn't quite as pretty, since the distinction between the function ('foo[x]') and the parameters 'y' and 'z' is not as visually obvious.

foo[x].call(y,z)

is another option, but goes still further from the Python api. Not a big problem for sure, but I just wanted to make sure there wasn't some magic trick I was missing to make the original Python ('foo[x](y,z)') also valid Ruby.

Dr Alex Gutteridge
Post-Doctoral Researcher

Bioinformatics Center
Institute for Chemical Research
Kyoto University
Gokasho, Uji, Kyoto 611-0011
Japan

···

From my experiments it appears that 'foo[x](y,z)' is always a

Alex Gutteridge wrote:

[snip]

is another option, but goes still further from the Python api. Not a big problem for sure, but I just wanted to make sure there wasn't some magic trick I was missing to make the original Python ('foo (y,z)') also valid Ruby.

I believe your summary of the situation is correct.

Hal

foo.call(y,z) may be further from the original python syntax, but it's
ruby's standard syntax for doing this, as exemplified by Proc objects and
Method objects. Given the philosophy of duck typing, I don't advise
trying to depart from this convention.

--Ken Bloom

···

On Thu, 28 Sep 2006 10:18:14 +0900, Alex Gutteridge wrote:

I'm working on converting a Python module (RPy) to Ruby and am trying
to keep the api as close to the original as possible. In Python it
(appears - my Python is very weak) that this is valid syntax:

foo(y,z)

Where 'foo' is an object with attribute 'x' which itself is callable
- in this case with the parameters 'y' and 'z'. The 'foo' object
is actually an R function and some magic is subsequently performed to
convert the parameters and call the function from Python/Ruby.

From my experiments it appears that 'foo(y,z)' is always a
SyntaxError in Ruby and the closest I can get in Ruby syntax to the
Python is:

foo[y,z]

But this isn't quite as pretty, since the distinction between the
function ('foo') and the parameters 'y' and 'z' is not as visually
obvious.

foo.call(y,z)

is another option, but goes still further from the Python api. Not a
big problem for sure, but I just wanted to make sure there wasn't
some magic trick I was missing to make the original Python ('foo
(y,z)') also valid Ruby.

--
Ken Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology.
http://www.iit.edu/~kbloom1/
I've added a signing subkey to my GPG key. Please update your keyring.

Alex Gutteridge:

foo(y,z)
foo[y,z]
foo.call(y,z)

Would it be a problem to write foo(x,y,z) or foo[x,y,z]?

Kalman

> I'm working on converting a Python module (RPy) to Ruby and am trying
> to keep the api as close to the original as possible. In Python it
> (appears - my Python is very weak) that this is valid syntax:
>
> foo(y,z)

...

> foo.call(y,z)
>
> is another option, but goes still further from the Python api. Not a
> big problem for sure, but I just wanted to make sure there wasn't
> some magic trick I was missing to make the original Python ('foo
> (y,z)') also valid Ruby.

foo.call(y,z) may be further from the original python syntax, but it's
ruby's standard syntax for doing this, as exemplified by Proc objects and
Method objects. Given the philosophy of duck typing, I don't advise
trying to depart from this convention.

I would go so far as saying that the standard Ruby syntax for this is

  foo.x y, z

···

On 2006.09.28 12:55, Ken Bloom wrote:

On Thu, 28 Sep 2006 10:18:14 +0900, Alex Gutteridge wrote:

That is another option I had considered. However, in the library in question 'foo' represents a running R interpreter, 'x' represents an R function and 'y' and 'z' represent arguments to that function. So I would like to keep 'x' and 'y,z' visually separate as much as possible. So, while it is a little extra typing, I prefer: r['sum'].call(1,2) over r('sum',1,2). In this case it would also be possible to write the preferred form: r.sum(1,2) but as I mentioned, this is not possible for some strangely named R functions such as '$' or '[['.

Dr Alex Gutteridge
Post-Doctoral Researcher

Bioinformatics Center
Institute for Chemical Research
Kyoto University
Gokasho, Uji, Kyoto 611-0011
Japan

···

On 1 Oct 2006, at 23:00, Kalman Noel wrote:

Alex Gutteridge:

foo(y,z)
foo[y,z]
foo.call(y,z)

Would it be a problem to write foo(x,y,z) or foo[x,y,z]?

Kalman

Eero Saynatkari wrote:

I would go so far as saying that the standard Ruby syntax for this is

  foo.x y, z

I don't know what you mean. That is not valid in Ruby (unless
x is a singleton method). In particular it doesn't work if
foo.x is a Proc, which is the situation discussed.

Hal

You could still use the r.sum(1,2) for 99% of your method calls. The
use of square brackets rather than round ones would hardly matter for
the remaining few, which already look odd!

Alex Gutteridge wrote:

···

On 1 Oct 2006, at 23:00, Kalman Noel wrote:

> Alex Gutteridge:
>> foo(y,z)
>> foo[y,z]
>> foo.call(y,z)
>
> Would it be a problem to write foo(x,y,z) or foo[x,y,z]?
>
> Kalman

That is another option I had considered. However, in the library in
question 'foo' represents a running R interpreter, 'x' represents an
R function and 'y' and 'z' represent arguments to that function. So I
would like to keep 'x' and 'y,z' visually separate as much as
possible. So, while it is a little extra typing, I prefer: r
['sum'].call(1,2) over r('sum',1,2). In this case it would also be
possible to write the preferred form: r.sum(1,2) but as I mentioned,
this is not possible for some strangely named R functions such as '$'
or '[['.

Dr Alex Gutteridge
Post-Doctoral Researcher

Bioinformatics Center
Institute for Chemical Research
Kyoto University
Gokasho, Uji, Kyoto 611-0011
Japan

Eero Saynatkari wrote:
>
>I would go so far as saying that the standard Ruby syntax for this is
>
> foo.x y, z

I don't know what you mean. That is not valid in Ruby (unless
x is a singleton method). In particular it doesn't work if
foo.x is a Proc, which is the situation discussed.

It is valid if x is a method that foo responds to.

Storing callable objects seems not a very rubyesque
thing to do--albeit necessary on occasion. In lieu
of worrying about keeping interface compatibility
with Python, I would recommend the OP merely make
the API as idiomatic Ruby as possible.

···

On 2006.09.28 14:32, Hal Fulton wrote:

Hal

Yeah, it would be pretty easy to redefine method_missing to forward
calls to r.symbol(*args) to r[:symbol, *args], or whatever internal
structure you have. Then your end users would have a clean syntax, and
you wouldn't have to do a lot of work.

Timothy Goddard wrote:

···

You could still use the r.sum(1,2) for 99% of your method calls. The
use of square brackets rather than round ones would hardly matter for
the remaining few, which already look odd!

Alex Gutteridge wrote:
> On 1 Oct 2006, at 23:00, Kalman Noel wrote:
>
> > Alex Gutteridge:
> >> foo(y,z)
> >> foo[y,z]
> >> foo.call(y,z)
> >
> > Would it be a problem to write foo(x,y,z) or foo[x,y,z]?
> >
> > Kalman
>
> That is another option I had considered. However, in the library in
> question 'foo' represents a running R interpreter, 'x' represents an
> R function and 'y' and 'z' represent arguments to that function. So I
> would like to keep 'x' and 'y,z' visually separate as much as
> possible. So, while it is a little extra typing, I prefer: r
> ['sum'].call(1,2) over r('sum',1,2). In this case it would also be
> possible to write the preferred form: r.sum(1,2) but as I mentioned,
> this is not possible for some strangely named R functions such as '$'
> or '[['.
>
> Dr Alex Gutteridge
> Post-Doctoral Researcher
>
> Bioinformatics Center
> Institute for Chemical Research
> Kyoto University
> Gokasho, Uji, Kyoto 611-0011
> Japan

Eero Saynatkari wrote:

Eero Saynatkari wrote:

I would go so far as saying that the standard Ruby syntax for this is

foo.x y, z

I don't know what you mean. That is not valid in Ruby (unless
x is a singleton method). In particular it doesn't work if
foo.x is a Proc, which is the situation discussed.

It is valid if x is a method that foo responds to.

Storing callable objects seems not a very rubyesque
thing to do--albeit necessary on occasion. In lieu
of worrying about keeping interface compatibility
with Python, I would recommend the OP merely make
the API as idiomatic Ruby as possible.

I think he was merely striving to keep the code
intuitive, not striving for compatibility with
Python as such. I concur with his desire for
intuitiveness (and I concur with your statement
that he should stick to idiomatic Ruby when
writing Ruby).

As for storing callable objects -- in general this
is not an unrubyish practice if done properly; it's
just slightly advanced. Nothing done properly is
unrubyish. :wink:

The apparent inconsistency of foo or foo.call(x)
stems partly from the fact that Ruby does not require
declarations as such.

If foo were a Proc and we called it the "intuitive"
way -- foo() -- it would look just like a method call.
This is good for readability in a way, but bad in that
we lose part of the disambiguation. Ruby is happy to
have a local variable foo and a method foo in the same
scope (though naturally I don't recommend it).

Hal

···

On 2006.09.28 14:32, Hal Fulton wrote:

Eero Saynatkari wrote:

Eero Saynatkari wrote:

I would go so far as saying that the standard Ruby syntax for this is

foo.x y, z

I don't know what you mean. That is not valid in Ruby (unless
x is a singleton method). In particular it doesn't work if
foo.x is a Proc, which is the situation discussed.

It is valid if x is a method that foo responds to.
Storing callable objects seems not a very rubyesque
thing to do--albeit necessary on occasion. In lieu
of worrying about keeping interface compatibility
with Python, I would recommend the OP merely make
the API as idiomatic Ruby as possible.

I think he was merely striving to keep the code
intuitive, not striving for compatibility with
Python as such. I concur with his desire for
intuitiveness (and I concur with your statement
that he should stick to idiomatic Ruby when
writing Ruby).

Indeed. I am 99% certain that the

foo['x'].call(y,z)

syntax is best here, since it is more familiar for Ruby programmers (and there are a lot more Ruby programmers than RPy programmers). This is only for edge cases anyway, most of the time the more intuitive form can be used:

foo.x(y,z)

and some method_missing magic will be used. The only trouble is that R has a few methods such as '$' and even '[[' which require this work around to be able to call. I'm sure

foo.[[(y.z)

can never be made into valid Ruby, but

foo['[['].call(y,z)

while hideous, is at least valid syntax.

As for storing callable objects -- in general this
is not an unrubyish practice if done properly; it's
just slightly advanced. Nothing done properly is
unrubyish. :wink:

I will endeavour to do it properly. :wink:

The apparent inconsistency of foo or foo.call(x)
stems partly from the fact that Ruby does not require
declarations as such.

If foo were a Proc and we called it the "intuitive"
way -- foo() -- it would look just like a method call.
This is good for readability in a way, but bad in that
we lose part of the disambiguation. Ruby is happy to
have a local variable foo and a method foo in the same
scope (though naturally I don't recommend it).

Yes, a quick test with Python shows the difference between it and Ruby in this respect (which I'd never really though about before):

Python 2.3.5 (#1, May 31 2005, 16:03:09)
>>> foo=5
>>> def foo():
... return
...
>>> print foo
<function foo at 0x444c70>

Compared to:

irb(main):001:0> foo=5
=> 5
irb(main):002:0> def foo() return end
=> nil
irb(main):004:0> puts foo
5
=> nil

Dr Alex Gutteridge
Post-Doctoral Researcher

Bioinformatics Center
Institute for Chemical Research
Kyoto University
Gokasho, Uji, Kyoto 611-0011
Japan

···

On 28 Sep 2006, at 15:00, Hal Fulton wrote:

On 2006.09.28 14:32, Hal Fulton wrote: