Odd functional programming question

Ok this is probably not really functional programming but I was just
noodling about with Ruby when I thought “it would be quite nice if I
could do X”. In this case X is as follows:

def X(text, action)
x.action
end

X(“abcedf”, size)
=> 6

X(“abcdef”, upcase)
=> “ABCDEF”

X(“abcdef”, gsub(/[aeiouy]/, ‘_’))
=> “_bcd_f”

Quite clearly this does not actually work, otherwise I wouldn’t be
asking. But is there some way in Ruby to do something like this?

Typical I solved inspiration struck after I hit send:

def X(text, todo, *args)
text.send(todo, *args)
end

puts X(“abcdefgh”, ‘downcase’)
puts X(“abcdefgh”, ‘gsub’, /[aeiouy]/, “_”)

If only I had waited a few moments more :frowning:

Any other ideas gratefully received.

On Mon, Sep 06, 2010 at 10:50:35PM +0900, Peter H. wrote:

Any other ideas gratefully received.

That’s The Right Way To Do It. For methods which take a block you’ll
need to
pass that through, and it’s slightly more efficient to use symbols
instead
of strings (if you pass a string to send, it will have to convert it to
a
symbol for you).

def X(text, todo, *args, &blk)
text.send(todo, *args, &blk)
end

puts X(“abcdefgh”, :downcase)
puts X(“abcdefgh”, :each_byte) { |i| puts i }

On Mon, Sep 6, 2010 at 4:11 PM, Brian C. [email protected]
wrote:

On Mon, Sep 06, 2010 at 10:50:35PM +0900, Peter H. wrote:

Any other ideas gratefully received.

That’s The Right Way To Do It. For methods which take a block you’ll need to
pass that through, and it’s slightly more efficient to use symbols instead
of strings (if you pass a string to send, it will have to convert it to a
symbol for you).

def X(text, todo, *args, &blk)
text.send(todo, *args, &blk)
end

puts X(“abcdefgh”, :downcase)
puts X(“abcdefgh”, :each_byte) { |i| puts i }

Actually I’d say this definition of X is completely superfluous
since it does not add anything to #send and so only helps obfuscate
code and slows down execution.

Kind regards

robert

On Mon, Sep 6, 2010 at 10:11 PM, Brian C. [email protected]
wrote:

def X(text, todo, *args, &blk)

vs

puts X(“abcdefgh”, :each_byte) { |i| puts i }

some weird edges of ruby :slight_smile:

On 6 September 2010 15:52, Robert K. [email protected]
wrote:

Actually I’d say this definition of X is completely superfluous
since it does not add anything to #send and so only helps obfuscate
code and slows down execution.

It was just a dummy method to get a feel how the code would be used.
What I am using it for is a method to compare two pieces of data with
a variety of optional preprocessing. This way I can put the
preprocessing (of which there could be several variants) in an array,
as [ :gsub, /[aeiouy/, ‘_’ ] etc, and iterate over the data and the
preprocessors and get the fitness scores out of the X method.

I will mean that I have one X method rather than X1, X2 … Xn which
are all just minor variations on X.

On Mon, Sep 6, 2010 at 5:07 PM, Peter H.
[email protected] wrote:

On 6 September 2010 15:52, Robert K. [email protected] wrote:

Actually I’d say this definition of X is completely superfluous
since it does not add anything to #send and so only helps obfuscate
code and slows down execution.

It was just a dummy method to get a feel how the code would be used.
What I am using it for is a method to compare two pieces of data with
a variety of optional preprocessing. This way I can put the
preprocessing (of which there could be several variants) in an array,
as [ :gsub, /[aeiouy/, ‘_’ ] etc, and iterate over the data and the
preprocessors and get the fitness scores out of the X method.

I will mean that I have one X method rather than X1, X2 … Xn which
are all just minor variations on X.

Where do you take the sequence of operations from? Maybe it’s simpler
(but certainly more efficient) to just load a Ruby file and execute
the code fetched from there. Or use evil #eval to compile the code
for later execution. You could then store it in a lambda and execute
it from there.

Kind regards

robert

On 09/06/2010 06:40 AM, Peter H. wrote:

Ok this is probably not really functional programming but I was just
noodling about with Ruby when I thought “it would be quite nice if I
could do X”. In this case X is as follows:

def X(text, action)
x.action
end

X(“abcedf”, size)
=> 6

X(“abcdef”, upcase)
=> “ABCDEF”

X(“abcdef”, gsub(/[aeiouy]/, ‘_’))
=> “_bcd_f”

Quite clearly this does not actually work, otherwise I wouldn’t be
asking. But is there some way in Ruby to do something like this?

Looks like a case for #instance_exec.

def foo(x, &action)
x.instance_exec(&action)
end

p foo(“abcedf”) {size}
p foo(“abcdef”) {upcase}
p foo(“abcdef”) {gsub(/[aeiouy]/, ‘_’)}

unlike #send, you can have more complex code than one single

method call

p foo(“abcdef”) {self+reverse}

also #instance_exec lets you pass thru args, which gives you

some flexibility in how you factor actions

def bar(x, *args, &action)
x.instance_exec(*args, &action)
end

p bar(“abcdef”, /[aeiouy]/, ‘_’) {|pat, str| gsub(pat, str)}

On 6 September 2010 18:58, Joel VanderWerf [email protected]
wrote:

Looks like a case for #instance_exec.

Oh yes, that looks very interesting

Thanks a lot

On 6 September 2010 16:22, Robert K. [email protected]
wrote:

Where do you take the sequence of operations from? Maybe it’s simpler
(but certainly more efficient) to just load a Ruby file and execute
the code fetched from there. Or use evil #eval to compile the code
for later execution. You could then store it in a lambda and execute
it from there.

At the moment this is the exploration of an idea and I want to stop
the code becoming cluttered up with minor code variants. When I find
out what works then I will look into the performance of the code. But
at this point ease of exploration is the key.

Thanks for your help.