Odd functional programming question

P

Peter Hickman

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?
 
P

Peter Hickman

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 :(

Any other ideas gratefully received.
 
B

Brian Candler

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 }
 
R

Robert Klemme

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 instea= d
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)
=A0text.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

--=20
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
 
P

Peter Hickman

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.
 
R

Robert Klemme

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
 
P

Peter Hickman

Where do you take the sequence of operations from? =A0Maybe it's simpler
(but certainly more efficient) to just load a Ruby file and execute
the code fetched from there. =A0Or use evil #eval to compile the code
for later execution. =A0You 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.
 
J

Joel VanderWerf

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)}
 

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

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,050
Latest member
AngelS122

Latest Threads

Top