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.

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs