CORE - Alternative Variable Substitution

ruby 1.9

prints “#{name} has 5 credits”

Is there any existent library (ruby 1.9) availbale, which enables an
alternative variable substitution, like e.g.

prints “&name has 5 credits”

Ilias what are you doing? Are you trying to feed the source of another
language into Ruby?

On 1 , 12:12, Peter H. [email protected]
wrote:

Ilias what are you doing?

I’m exploring, assessing, adapting, evolving, assimilating ruby.

This is a personal process that you cannot influence in any way.

Are you trying to feed the source of another language into Ruby?

No.

Can I have now an in-topic reply?

“Is there any existent library (ruby 1.9) availbale, which enables
an
alternative variable substitution”.

.

2011/6/1 Ilias L. [email protected]:

Can I have now an in-topic reply?

“Is there any existent library (ruby 1.9) availbale, which enables
an
alternative variable substitution”.

You don’t need a library for that. It can be as easy as

class String
def replace(bind)
gsub %r{(?<!\)&(\w+)} do |m|
eval($1, bind)
end
end
end

name = “foo”
puts “&name has 5 credits”.replace binding

Other equally simple variants can be implemented.

Kind regards

robert

well…

p name + " has 5 credits"

…though i assume this is not what you’re looking for.

How about you actually say what you want. The one line example tells
us nothing about the variable substitution mechanism you are expecting

What constitutes a variable name to be substituted, anything between
the ‘&’ and the next whitespace perhaps?
How would you expect it to handle something line “&this&that&other”.
Will it correctly concatenate the values together or will it force
spaces between the substitutions?
How should it escape real &s in the text such as “cat & dog”?
How should it handle missing variables?
How will it handle trailing text such as this in Ruby #{distance}m or
#{year}-#{month}-#{day}?
Will it be expected to handle constants, classes, instance / class
variables and globals?

Until you tell us what you want no one can help you. Given your one
example it could be possible to create a dozen different libraries
that handle the cases I’ve given in completely different ways and yet
be consistent for the one case you give

But more interestingly what is deficient in the current #{} method?

On Wed, Jun 1, 2011 at 1:15 AM, Ilias L. [email protected]
wrote:

ruby 1.9

prints “#{name} has 5 credits”

Is there any existent library (ruby 1.9) availbale, which enables an
alternative variable substitution, like e.g.

prints “&name has 5 credits”

I don’t know of anything that that modifies the behavior of String
that way, and changing the semantics of string literals is probably a
bad idea for all kinds of reasons, in the same way as changing the
semantics of integer literals so that 2 no longer represented the
integer between 1 and 3 would be.

On the other hand, Ruby has a wide variety of templating libraries
that will let you interpolate into strings in lots of different ways,
though you need to pass the string to a method of the templating
engine rather than just write a string literal that gets interpreted
in a manner that differs from normal Ruby evaluation.

Also, as you are probably aware (though newbies reading may not be),
Ruby already provides a shortcut interpolation of the kind you ask
for, but only for instance variables, not locals (e.g., instead of
@foo is #{@foo}” you can use “@foo is #@foo”.)

On Wed, Jun 01, 2011 at 10:23:01PM +0900, Peter H. wrote:

How will it handle trailing text such as this in Ruby #{distance}m or
#{year}-#{month}-#{day}?
Will it be expected to handle constants, classes, instance / class
variables and globals?

To be fair, I think the answer to these might be “however the existing
library handles it,” if there is such a thing. The question called for
any existing library that offers (as I interpret it) an alternate syntax
for variable interpolation in strings; the & example seemed to me to be
nothing more than a way to illustrate the possibility of alternate
syntaxes in case the question was not clear, and not to illustrate a
specific syntax that was required.

Until you tell us what you want no one can help you. Given your one
example it could be possible to create a dozen different libraries
that handle the cases I’ve given in completely different ways and yet
be consistent for the one case you give

But more interestingly what is deficient in the current #{} method?

It’s a lot more typing than (for instance) Perl’s use of $ for variable
interpolation. I guess some people might consider that a “deficiency”.

Unless the answer to the posed question is easily discovered with a very
simple Google search (I don’t think it is) or the person posing the
question has an ulterior motive that undermines the honest interest of
the question (I have no specific reason to believe so, as far as I’m
aware), I think it’s a perfectly reasonable question to ask, if for no
other reason than curiosity.

. . . though I suspect the answer is “no, there isn’t such a library;
would you like to write one?”

On 1 , 16:23, Peter H. [email protected]
wrote:

How about you actually say what you want. The one line example tells
us nothing about the variable substitution mechanism you are expecting
[…] - (setting new context)

“&name” was just an example.

I will not go into a new context and a deeper analysis.

I’m just asking a simple question:

“Is there any existent library (ruby 1.9) availbale, which enables
an alternative variable substitution”.

That’s all.

.

On 1 Ιούν, 18:07, Christopher D. [email protected] wrote:

I don’t know of anything that that modifies the behavior of String
that way,
[…]

…or in a similar way (“&name” was just an example).

On the other hand, Ruby has a wide variety of templating libraries
[…]

Also, as you are probably aware (though newbies reading may not be),
Ruby already provides a shortcut interpolation of the kind you ask
for, but only for instance variables, not locals (e.g., instead of
@foo is #{@foo}” you can use “@foo is #@foo”.)

I understand, for local variables only:

print “#@name has 5 credits”

.

On Thu, 2 Jun 2011 13:00:29 +0900, Ilias L. wrote:

On 1 Ιούν, 18:07, Christopher D. [email protected] wrote:

Also, as you are probably aware (though newbies reading may not be),
Ruby already provides a shortcut interpolation of the kind you ask
for, but only for instance variables, not locals (e.g., instead of
@foo is #{@foo}” you can use “@foo is #@foo”.)

I understand, for local variables only:

print “#@name has 5 credits”

@name is not a local variable, but an instance variable.

On 1 , 16:22, Robert K. [email protected] wrote:

2011/6/1 Ilias L. [email protected]:

Can I have now an in-topic reply?

“Is there any existent library (ruby 1.9) availbale, which enables
an
alternative variable substitution”.

You don’t need a library for that.

I do nearly always look first for a existent (used, field tested)
library, prior to implementing functionality myself.

It can be as easy as
[…]

You suggested implementation adds a new function.

At least, if you suggest an implementation, do it in the OO way
(overloading the relevant method).

.

On Thu, 2 Jun 2011 13:25:25 +0900, Ilias L. wrote:

On 1 Ιούν, 16:22, Robert K. [email protected] wrote:

It can be as easy as
[…]

You suggested implementation adds a new function.

At least, if you suggest an implementation, do it in the OO way
(overloading the relevant method).

There is no separate method in Ruby which does the variable
substitution.
This functionality is hardcoded into lexer and parser.

On Thu, Jun 02, 2011 at 04:02:31PM +0900, Peter Z. wrote:

There is no separate method in Ruby which does the variable
substitution.
This functionality is hardcoded into lexer and parser.

I wonder how much that changes in the Rubinius implementation.

On Thu, 2 Jun 2011 16:12:37 +0900, Chad P. wrote:

On Thu, Jun 02, 2011 at 04:02:31PM +0900, Peter Z. wrote:

There is no separate method in Ruby which does the variable
substitution.
This functionality is hardcoded into lexer and parser.

I wonder how much that changes in the Rubinius implementation.

Yes, I thought about Rubinius too. It nevertheless uses lexer and
parser,
and amount of changes to code will be comparable IMO.

On Jun 2, 2011, at 9:44 AM, Peter Z. wrote:

and amount of changes to code will be comparable IMO.
I don’t think so. Literals are never “constructed”, so there is no step
you could hook into. There is also no way to delay the interpolation
step,
which is the second big question usually asked in this context.

What you can do, is using sprintf-substitution:

“%{firstname}, %{lastname}” % {:firstname => “Florian”,
:lastname => “Gilcher”}
# => “Florian G.”

It doesn’t save you any characters, though. Another way would be:

"%s %s" % ["Florian", "Gilcher"]

Shorter, if you like it.

If you really want to, you could write your own, similar substitution,
but I am not sure whether thats work worth doing.

Regards,
Florian G.

On 2 Ιούν, 10:02, Peter Z. [email protected] wrote:

There is no separate method in Ruby which does the variable
substitution.
This functionality is hardcoded into lexer and parser.

I understand.

This means it is not easy, if not impossible to alter the behaviour.

Can I change this functionality with a C-level extension, but without
altering the ruby source?

.

On 2 Ιούν, 10:01, Peter Z. [email protected] wrote:

print “#@name has 5 credits”

@name is not a local variable, but an instance variable.

Of course, my fault, correction:

for instance variables only:

print “#@name has 5 credits”

.

On Thu, 2 Jun 2011 20:05:34 +0900, Ilias L. wrote:

At least, if you suggest an implementation, do it in the OO way
Can I change this functionality with a C-level extension, but without
altering the ruby source?

Definitely no (for MRI, at least). Basically, C extensions can provide
the
same functionality as Ruby libraries (define modules, classes,
functions etc.),
but in C. There is several hacks you can do with an extension, but they
are hard
to implement/debug and are non-portable.

Moreover, the compiled lexer is a huge state machine which consists of
a switch()
and a lot of symbol-to-transition association tables. You won’t be able
to patch that
anyhow.

An alternative would be a preprocessor, such as C uses to handle the
#define and #include statements. It could parse the source in the
“Every &count times” format and convert it to “Every #{count} times”
which Ruby would have no difficulty with. But parsing the source just
to do variable substitution must be the hight of Yak shaving given
that Ruby provides a variable substitution mechanism.

Or you could hack the source for Ruby itself and insert this as an
alternative syntax. I don’t hack the source myself so I have no idea
of how hard this is or how portable it will be with regards to updates
but given the difficulty you seem to be having with the existing
system you might just consider it worth while.