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

A

Alex Gutteridge

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.

From my experiments it appears that 'foo[x](y,z)' is always a
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
 
H

Hal Fulton

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[x] (y,z)')
also valid Ruby.

I believe your summary of the situation is correct.


Hal
 
K

Ken Bloom

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.

From my experiments it appears that 'foo[x](y,z)' is always a
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.

foo[x].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
 
E

Eero Saynatkari

--mFHiwr52TKrxpkjc
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Thu, 28 Sep 2006 10:18:14 +0900, Alex Gutteridge wrote:
=20
I'm working on converting a Python module (RPy) to Ruby and am trying = =20
to keep the api as close to the original as possible. In Python it =20
(appears - my Python is very weak) that this is valid syntax:
=20
foo[x](y,z) =2E..
foo[x].call(y,z)
=20
is another option, but goes still further from the Python api. Not a = =20
big problem for sure, but I just wanted to make sure there wasn't =20
some magic trick I was missing to make the original Python ('foo[x]=20
(y,z)') also valid Ruby.
=20
foo[x].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

--mFHiwr52TKrxpkjc
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (FreeBSD)

iD8DBQFFG1l67Nh7RM4TrhIRAp1mAKCfK5/U5dl+AoK0l0fwJoMxo7wBxACdH026
bHpqkr2DReNC9mefTnlgxsI=
=GrRU
-----END PGP SIGNATURE-----

--mFHiwr52TKrxpkjc--
 
H

Hal Fulton

Eero said:
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
 
E

Eero Saynatkari

--W/+CTqSGWdiRg+8j
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

=20
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.

--W/+CTqSGWdiRg+8j
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (FreeBSD)

iD8DBQFFG2G77Nh7RM4TrhIRAosPAJ9a9tmnNtJBnZHsmkFMlppO5eOXZwCdFsp8
dRduO1x+bwlCBG8LfFHTqfk=
=MJng
-----END PGP SIGNATURE-----

--W/+CTqSGWdiRg+8j--
 
H

Hal Fulton

Eero said:
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. ;)

The apparent inconsistency of foo[x] 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
 
A

Alex Gutteridge

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. ;)

I will endeavour to do it properly. ;)
The apparent inconsistency of foo[x] 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)... return
...<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
 
A

Alex Gutteridge

Alex Gutteridge:
foo[x](y,z)
foo[x][y,z]
foo[x].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
 
T

Timothy Goddard

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 said:
Alex Gutteridge:
foo[x](y,z)
foo[x][y,z]
foo[x].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
 
N

Noah Easterly

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 said:
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 said:
Alex Gutteridge:
foo[x](y,z)
foo[x][y,z]
foo[x].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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,228
Members
46,818
Latest member
SapanaCarpetStudio

Latest Threads

Top