Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.ruby > #4735 > unrolled thread
| Started by | Andreas Lundgren <andreas.lundgren.x@gmail.com> |
|---|---|
| First post | 2011-05-18 06:44 -0700 |
| Last post | 2011-05-24 16:54 -0500 |
| Articles | 20 on this page of 28 — 6 participants |
Back to article view | Back to comp.lang.ruby
Generating Functions in Ruby Andreas Lundgren <andreas.lundgren.x@gmail.com> - 2011-05-18 06:44 -0700
Re: Generating Functions in Ruby Steve Klabnik <steve@steveklabnik.com> - 2011-05-18 09:34 -0500
Re: Generating Functions in Ruby Robert Klemme <shortcutter@googlemail.com> - 2011-05-18 09:54 -0500
Re: Generating Functions in Ruby 7stud -- <bbxx789_05ss@yahoo.com> - 2011-05-18 14:44 -0500
Re: Generating Functions in Ruby 7stud -- <bbxx789_05ss@yahoo.com> - 2011-05-18 20:55 -0500
Re: Generating Functions in Ruby Robert Klemme <shortcutter@googlemail.com> - 2011-05-19 08:31 +0200
Re: Generating Functions in Ruby 7stud -- <bbxx789_05ss@yahoo.com> - 2011-05-19 13:00 -0500
Re: Generating Functions in Ruby Robert Klemme <shortcutter@googlemail.com> - 2011-05-20 01:28 -0500
Re: Generating Functions in Ruby Andreas Lundgren <andreas.lundgren.x@gmail.com> - 2011-05-23 05:54 -0700
Re: Generating Functions in Ruby 7stud -- <bbxx789_05ss@yahoo.com> - 2011-05-23 16:25 -0500
Re: Generating Functions in Ruby Thomas Preymesser <thopre@gmail.com> - 2011-05-19 04:35 -0500
Re: Generating Functions in Ruby Brian Candler <b.candler@pobox.com> - 2011-05-19 10:06 -0500
Re: Generating Functions in Ruby 7stud -- <bbxx789_05ss@yahoo.com> - 2011-05-23 16:09 -0500
Re: Generating Functions in Ruby 7stud -- <bbxx789_05ss@yahoo.com> - 2011-05-23 20:51 -0500
Re: Generating Functions in Ruby 7stud -- <bbxx789_05ss@yahoo.com> - 2011-05-23 21:07 -0500
Re: Generating Functions in Ruby Andreas Lundgren <andreas.lundgren.x@gmail.com> - 2011-05-24 00:10 -0700
Re: Generating Functions in Ruby Andreas Lundgren <andreas.lundgren.x@gmail.com> - 2011-05-24 00:24 -0700
Re: Generating Functions in Ruby Brian Candler <b.candler@pobox.com> - 2011-05-24 03:12 -0500
Re: Generating Functions in Ruby Robert Klemme <shortcutter@googlemail.com> - 2011-05-24 03:39 -0500
Re: Generating Functions in Ruby Andreas Lundgren <andreas.lundgren.x@gmail.com> - 2011-05-24 06:46 -0700
Re: Generating Functions in Ruby Robert Klemme <shortcutter@googlemail.com> - 2011-05-24 10:20 -0500
Re: Generating Functions in Ruby 7stud -- <bbxx789_05ss@yahoo.com> - 2011-05-24 17:27 -0500
Re: Generating Functions in Ruby 7stud -- <bbxx789_05ss@yahoo.com> - 2011-05-24 17:53 -0500
Re: Generating Functions in Ruby Andreas Lundgren <andreas.lundgren.x@gmail.com> - 2011-05-25 03:59 -0700
Re: Generating Functions in Ruby 7stud -- <bbxx789_05ss@yahoo.com> - 2011-05-25 12:26 -0500
Re: Generating Functions in Ruby 7stud -- <bbxx789_05ss@yahoo.com> - 2011-05-25 17:12 -0500
Re: Generating Functions in Ruby Andreas Lundgren <andreas.lundgren.x@gmail.com> - 2011-05-27 04:48 -0700
Re: Generating Functions in Ruby 7stud -- <bbxx789_05ss@yahoo.com> - 2011-05-24 16:54 -0500
Page 1 of 2 [1] 2 Next page →
| From | Andreas Lundgren <andreas.lundgren.x@gmail.com> |
|---|---|
| Date | 2011-05-18 06:44 -0700 |
| Subject | Generating Functions in Ruby |
| Message-ID | <5e21af14-befb-406e-b1c3-6758fe1527ab@s14g2000vbi.googlegroups.com> |
Hi!
I'm looking for a construction in Ruby to generate a (big) set of
functions. I need these functions to be class methods and called by
unique names since they are called via an external API.
As an example, let me create two functions that hard codes an addition
and then uses this in a small test program.
def FivePlusFour
return 5+4
end
def OnePlusSeven
return 1+7
end
puts("Five + Four is " + FivePlusFour().to_s)
puts("One + Seven is " + OnePlusSeven().to_s)
I would like a way to generate the methods in runtime. As an old C-
programmer, I'm looking for something like this:
# Define a macro
define SUM_TEMPLATE(namn,x,y) \\
def namn \\
return x+y \\
end
# Create each function with a one-liner in runtime.
SUM_TEMPLATE(FivePlusFour, 5, 4)
SUM_TEMPLATE(OnePlusSeven, 1, 7)
# Test program
puts("Five + Four is " + FivePlusFour().to_s)
puts("One + Seven is " + OnePlusSeven().to_s)
Is this possible in Ruby?
(Please don't reply how to solve this silly example in a better way,
the true use case is of cause much more complex. But conceptually it's
the same.)
Best Regards,
Andreas Lundgren - Sweden
[toc] | [next] | [standalone]
| From | Steve Klabnik <steve@steveklabnik.com> |
|---|---|
| Date | 2011-05-18 09:34 -0500 |
| Message-ID | <BANLkTi=bR3CSaHi2mFz9TtUjHvHLXgeuFA@mail.gmail.com> |
| In reply to | #4735 |
[Note: parts of this message were removed to make it a legal post.] What you want is define_method. Ill gives you some links when I'm not on my phone.
[toc] | [prev] | [next] | [standalone]
| From | Robert Klemme <shortcutter@googlemail.com> |
|---|---|
| Date | 2011-05-18 09:54 -0500 |
| Message-ID | <BANLkTik9J+XjqBwd8Wo0_0v3qXheQB02Tg@mail.gmail.com> |
| In reply to | #4735 |
On Wed, May 18, 2011 at 3:46 PM, Andreas Lundgren
<andreas.lundgren.x@gmail.com> wrote:
> Hi!
>
> I'm looking for a construction in Ruby to generate a (big) set of
> functions. I need these functions to be class methods and called by
> unique names since they are called via an external API.
>
> As an example, let me create two functions that hard codes an addition
> and then uses this in a small test program.
>
> def FivePlusFour
> return 5+4
> end
>
> def OnePlusSeven
> return 1+7
> end
>
> puts("Five + Four is " + FivePlusFour().to_s)
> puts("One + Seven is " + OnePlusSeven().to_s)
>
>
> I would like a way to generate the methods in runtime. As an old C-
> programmer, I'm looking for something like this:
>
> # Define a macro
> define SUM_TEMPLATE(namn,x,y) \\
> def namn \\
> return x+y \\
> end
>
> # Create each function with a one-liner in runtime.
> SUM_TEMPLATE(FivePlusFour, 5, 4)
> SUM_TEMPLATE(OnePlusSeven, 1, 7)
>
> # Test program
> puts("Five + Four is " + FivePlusFour().to_s)
> puts("One + Seven is " + OnePlusSeven().to_s)
>
> Is this possible in Ruby?
def SUM_TEMPLATE(name, x, y)
class <<self;self;end.class_eval "def #{name}; #{x} + #{y}; end"
end
> (Please don't reply how to solve this silly example in a better way,
> the true use case is of cause much more complex. But conceptually it's
> the same.)
Is it really? Do you always have one name and two values as input?
Can you give a bit more contextual information?
Cheers
robert
--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
[toc] | [prev] | [next] | [standalone]
| From | 7stud -- <bbxx789_05ss@yahoo.com> |
|---|---|
| Date | 2011-05-18 14:44 -0500 |
| Message-ID | <57836d5d927311efda42e4036904bf8d@ruby-forum.com> |
| In reply to | #4738 |
Robert K. wrote in post #999483:
> On Wed, May 18, 2011 at 3:46 PM, Andreas Lundgren
> <andreas.lundgren.x@gmail.com> wrote:
>> return 5+4
>> I would like a way to generate the methods in runtime. As an old C-
>> SUM_TEMPLATE(OnePlusSeven, 1, 7)
>>
>> # Test program
>> puts("Five + Four is " + FivePlusFour().to_s)
>> puts("One + Seven is " + OnePlusSeven().to_s)
>>
>> Is this possible in Ruby?
>
> def SUM_TEMPLATE(name, x, y)
> class <<self;self;end.class_eval "def #{name}; #{x} + #{y}; end"
> end
>
>> I need these functions to be class methods
..of what class? Perhaps something like this:
def SUM_TEMPLATE(the_class, meth_name, x, y)
class_obj = Object.const_get(the_class)
class_obj.singleton_class.class_eval do
define_method(meth_name) do
x + y
end
end
end
class Dog
end
SUM_TEMPLATE('Dog', 'FivePlusFour', 5, 4)
puts Dog.FivePlusFour
--output:--
9
--
Posted via http://www.ruby-forum.com/.
[toc] | [prev] | [next] | [standalone]
| From | 7stud -- <bbxx789_05ss@yahoo.com> |
|---|---|
| Date | 2011-05-18 20:55 -0500 |
| Message-ID | <b170292747e065962ce90f546e15cccd@ruby-forum.com> |
| In reply to | #4738 |
Robert K. wrote in post #999483:
>
> def SUM_TEMPLATE(name, x, y)
> class <<self;self;end.class_eval "def #{name}; #{x} + #{y}; end"
> end
>
I'm curious how you expected the op to use that method?
--
Posted via http://www.ruby-forum.com/.
[toc] | [prev] | [next] | [standalone]
| From | Robert Klemme <shortcutter@googlemail.com> |
|---|---|
| Date | 2011-05-19 08:31 +0200 |
| Message-ID | <93jrqvFrf0U2@mid.individual.net> |
| In reply to | #4752 |
On 19.05.2011 03:55, 7stud -- wrote:
> Robert K. wrote in post #999483:
>>
>> def SUM_TEMPLATE(name, x, y)
>> class<<self;self;end.class_eval "def #{name}; #{x} + #{y}; end"
>> end
>>
>
> I'm curious how you expected the op to use that method?
I am not sure I get your point. The method was intended to be used as a
top level method similarly to how he formulated his C macro sample.
$ ruby19 <<CODE
> def SUM_TEMPLATE(name, x, y)
> class <<self;self;end.class_eval "def #{name}; #{x} + #{y}; end"
> end
> SUM_TEMPLATE("f",1,2)
> p f
> CODE
3
But, frankly, this use case seems to be so far away from his real use
case that this approach is likely not what is needed. Since I have no
further information I stick with the example and leave speculation about
the nature of the real issue aside.
Kind regards
robert
--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
[toc] | [prev] | [next] | [standalone]
| From | 7stud -- <bbxx789_05ss@yahoo.com> |
|---|---|
| Date | 2011-05-19 13:00 -0500 |
| Message-ID | <41214f15ab9bccbeb6ceab7f7fb220b0@ruby-forum.com> |
| In reply to | #4753 |
Robert K. wrote in post #999582:
>
> I am not sure I get your point. The method was intended to be used as a
> top level method similarly to how he formulated his C macro sample.
>
> $ ruby19 <<CODE
> > def SUM_TEMPLATE(name, x, y)
> > class <<self;self;end.class_eval "def #{name}; #{x} + #{y}; end"
> > end
> > SUM_TEMPLATE("f",1,2)
> > p f
> > CODE
> 3
>
Oh, okay. But that isn't a class method.
--
Posted via http://www.ruby-forum.com/.
[toc] | [prev] | [next] | [standalone]
| From | Robert Klemme <shortcutter@googlemail.com> |
|---|---|
| Date | 2011-05-20 01:28 -0500 |
| Message-ID | <BANLkTinzF8wMFVU0NVcP4p5XvTgDAx3-7A@mail.gmail.com> |
| In reply to | #4775 |
On Thu, May 19, 2011 at 8:00 PM, 7stud -- <bbxx789_05ss@yahoo.com> wrote:
> Robert K. wrote in post #999582:
>>
>> I am not sure I get your point. The method was intended to be used as a
>> top level method similarly to how he formulated his C macro sample.
>>
>> $ ruby19 <<CODE
>> > def SUM_TEMPLATE(name, x, y)
>> > class <<self;self;end.class_eval "def #{name}; #{x} + #{y}; end"
>> > end
>> > SUM_TEMPLATE("f",1,2)
>> > p f
>> > CODE
>> 3
>>
>
> Oh, okay. But that isn't a class method.
That's true. But OP mentioned class methods in just one sentence but
all his examples (Ruby and C) were not using class methods. Besides
it should not be too difficult to modify the code to generate class
methods. I still would like to see more realistic requirements as all
speculations about proper ways to solve the problem are moot as long
as we do not know the problem.
Kind regards
robert
--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
[toc] | [prev] | [next] | [standalone]
| From | Andreas Lundgren <andreas.lundgren.x@gmail.com> |
|---|---|
| Date | 2011-05-23 05:54 -0700 |
| Message-ID | <5d31b677-f378-4a9a-9046-65dd3dbbfab1@dn9g2000vbb.googlegroups.com> |
| In reply to | #4796 |
Hi, and thank you all!
Yes, the example is far from reallity in one sense, but your example
really did the trick and conceptually it's the same!
So, for the interessted reader, I will provide my code here. (I have a
similar method for setting values.) Via an Ole32 server i communicate
with a sw that can extract all types of data from a odd type of
database.
(My final dilemma is how to get the value of STUB_CALLS into
Templates.rb by defining it in my test program Impl.rb. To define it
direcrly in the template file in not very nice... And of cause I don't
want to have to define it at all when running in non-test-mode.)
______Templates.rb______
STUB_CALLS = 1; # If this is '1', all instruments are stubed for
debugging purpouse
def GET_VALUE(f_name, method, return_format, no_of_params)
# Make a parameter list and an argument list
if 0<no_of_params
arg_list = 'x1';
params = 'x1.to_s';
for i in 2..no_of_params do
arg_list = arg_list + ', x' + i.to_s;
params = params + ' + \', \' + x' + i.to_s + '.to_s';
end
params = params+';';
else
arg_list = '';
params = 0;
end
if (0==STUB_CALLS)
class <<self;self;end.class_eval "def #{f_name}(#{arg_list});
handle = OA.instance.getWIN32OLEHandle();
params = #{params};
handle.call(['MethodNameIn','Params'],[#{method},params]);
ret_val = handle.GetControlValue(#{return_format});
error = handle.GetControlValue('error out');
if OA.instance.checkForError(error);
return 'NaN';
else;
return ret_val;
end;
end"
else
class <<self;self;end.class_eval "def #{f_name}(#{arg_list});
params = #{params};
puts('Calling #{method}(#{arg_list}) with parameters <' + params
+ '>');
end"
end
end
______Templates.rb______ <- this is just three out of many
methods...
require '.\Difinitions.rb'
#***ParamsList ["database"]
GET_VALUE('customer_getFrequency', 'getcustomerfreq', 'ResultDbl', 1)
#***ParamsList ["database"]
GET_VALUE('customer_getSpend_thr', 'getcustspend', 'ResultDbl', 1)
#***ParamsList ["database", "start", "stop", "inc"]
GET_VALUE('shop_GetFundReq', 'getfundreq', 'ResultDbl', 4)
______Impl.rb______ <- The implementation does already exist, and it's
huge. This is just a few lines from my test program:
require '.\Difinitions.rb'
f = customer_getFrequency(cdb)
s = customer_getSpend_thr(cdb)
fr = shop_GetFundReq(sdb, 20110101, 20110201, 'all')
[toc] | [prev] | [next] | [standalone]
| From | 7stud -- <bbxx789_05ss@yahoo.com> |
|---|---|
| Date | 2011-05-23 16:25 -0500 |
| Message-ID | <dba0a673be313aaa604fd13aeabd3781@ruby-forum.com> |
| In reply to | #4922 |
Andreas Lundgren wrote in post #1000369: > 5) Most ruby programmers don't use for-in because that construct just calls each(), so ruby programmers call each() directly: 2..no_of_params.each do |i| arg_list = arg_list + ', x' + i.to_s; params = params + ' + \', \' + x' + i.to_s + '.to_s'; end -- Posted via http://www.ruby-forum.com/.
[toc] | [prev] | [next] | [standalone]
| From | Thomas Preymesser <thopre@gmail.com> |
|---|---|
| Date | 2011-05-19 04:35 -0500 |
| Message-ID | <BANLkTikRXDC=eZqr0Pa7EqVSq_Hv+8qS4Q@mail.gmail.com> |
| In reply to | #4735 |
[Note: parts of this message were removed to make it a legal post.] On 18 May 2011 15:46, Andreas Lundgren <andreas.lundgren.x@gmail.com> wrote: > I'm looking for a construction in Ruby to generate a (big) set of > functions. I need these functions to be class methods and called by > unique names since they are called via an external API. > another way could be the method_missing method. In my gem 'weekday' you can call methods like first_monday(yyyy,mm) , third_tuesday(...), last_sunday(...) and any other combination of a number and weekday. -Thomas -- Thomas Preymesser thopre@gmail.com http://thopre.googlepages.com/ http://thopre.wordpress.com/
[toc] | [prev] | [next] | [standalone]
| From | Brian Candler <b.candler@pobox.com> |
|---|---|
| Date | 2011-05-19 10:06 -0500 |
| Message-ID | <6607a8ddf9ad5da65d6ca70c12e5ae6c@ruby-forum.com> |
| In reply to | #4735 |
Have a look at how ActionView (from Rails) caches its compiled
templates. It does this by defining methods on a module.
[actionpack/lib/action_view/template.rb]
def compile(view, mod) #:nodoc:
..
code = arity.abs == 1 ? @handler.call(self) :
@handler.call(self, view)
source = <<-end_src
def #{method_name}(local_assigns)
_old_output_buffer = @output_buffer;#{locals_code};#{code}
ensure
@output_buffer = _old_output_buffer
end
end_src
..
begin
mod.module_eval(source, identifier, 0)
ObjectSpace.define_finalizer(self, Finalizer[method_name,
mod])
rescue Exception => e # errors from template code
if logger = (view && view.logger)
logger.debug "ERROR: compiling #{method_name} RAISED #{e}"
logger.debug "Function body: #{source}"
logger.debug "Backtrace: #{e.backtrace.join("\n")}"
end
--
Posted via http://www.ruby-forum.com/.
[toc] | [prev] | [next] | [standalone]
| From | 7stud -- <bbxx789_05ss@yahoo.com> |
|---|---|
| Date | 2011-05-23 16:09 -0500 |
| Message-ID | <8511c0a8801106dc8bf820321807ccff@ruby-forum.com> |
| In reply to | #4735 |
1) Strings are mutable in ruby, so get rid of all those +'s. 2) Don't use back slashes in strings--unless you specifically intend to use an escape character. 3) > My final dilemma is how to get the value of STUB_CALLS into > Templates.rb by defining it in my test program Impl.rb. Why can't your methods have a 'debug' parameter with a default value? Then for debugging, you can 'override' the default. -- Posted via http://www.ruby-forum.com/.
[toc] | [prev] | [next] | [standalone]
| From | 7stud -- <bbxx789_05ss@yahoo.com> |
|---|---|
| Date | 2011-05-23 20:51 -0500 |
| Message-ID | <229eaaafa7ab13dbdc46143d3c08a655@ruby-forum.com> |
| In reply to | #4735 |
7) If you will have less than 9 parameters, you can do this:
param_str = temp = 'x1'
10.times do |i|
temp = temp.succ
param_str << ', ' << temp
end
p param_str
--output:--
"x1, x2, x3, x4, x5, x6, x7, x8, x9, y0, y1"
But in ruby, you can define variadic methods:
def my_meth(*args)
args.each {|arg| p arg}
end
my_meth(1, 2, 3)
my_meth('a', 'b', 4)
--output:--
1
2
3
"a"
"b"
4
--
Posted via http://www.ruby-forum.com/.
[toc] | [prev] | [next] | [standalone]
| From | 7stud -- <bbxx789_05ss@yahoo.com> |
|---|---|
| Date | 2011-05-23 21:07 -0500 |
| Message-ID | <dc2df7d480159878c42c65807d568cd8@ruby-forum.com> |
| In reply to | #4735 |
10)
params = 'hello'
params = #{params};
--output:--
prog.rb:3: syntax error, unexpected $end
11) Here's some advice: buy a beginning ruby book and read it.
--
Posted via http://www.ruby-forum.com/.
[toc] | [prev] | [next] | [standalone]
| From | Andreas Lundgren <andreas.lundgren.x@gmail.com> |
|---|---|
| Date | 2011-05-24 00:10 -0700 |
| Message-ID | <151562ef-aebd-4999-8b7b-816c21a7c6df@m40g2000vbt.googlegroups.com> |
| In reply to | #4959 |
Hi! This is why I did not put the real example at first, because then some people that do not understand the code always brings these stupid comments. I do not have any compilation errors, and the code works perfectly, so I don't think that I need a beginning ruby book for that reason. :-) (First params does not contain a simple string; please note the escaped string characters in the code that generates params. Kind of strings within strings). I cannot change the function signature since I cannot change the upper layer that makes calls to my Ruby glue layer... That is why I would like to introduce debugging by making changes in the glue layer at "compile" time. (In C I would have used a #define for the pre processor.) "1) Strings are mutable in ruby, so get rid of all those +'s." - I'm not sure that I understand this but it sounds interesting, what does it mean? Thanks for input about creating loops, new language = new flavours, and that is nice to adapt to! :-) I think that I could make use of the variable parameter input, with the extended error control code making sure all parameters are in place, I think that this will be the same amount of code. But I learned something new, so thanks! BR, Andreas
[toc] | [prev] | [next] | [standalone]
| From | Andreas Lundgren <andreas.lundgren.x@gmail.com> |
|---|---|
| Date | 2011-05-24 00:24 -0700 |
| Message-ID | <71dec76a-e0c1-4a7e-b3e6-a397ca4be291@f9g2000vbz.googlegroups.com> |
| In reply to | #4964 |
My bad to use the name "param" for two different content, but any
ways:
First params typically assembles to this:
x1.to_s + ', ' + x2.to_s + ', ' + x3.to_s + ', ' + x4.to_s
Now I have created the code, not the string.
The line
params_2 = #{params};
extends to:
params_2 = x1.to_s + ', ' + x2.to_s + ', ' + x3.to_s + ', ' + x4.to_s
and assembles my input so that
params_2 == 'myDB, 20110101, 20110201, all'
Output from the function when STUB_CALLS=1:
Calling shop_GetFundReq(x1, x2, x3, x4) with parameters <myDB,
20110101, 20110201, all>
BR,
Andreas
[toc] | [prev] | [next] | [standalone]
| From | Brian Candler <b.candler@pobox.com> |
|---|---|
| Date | 2011-05-24 03:12 -0500 |
| Message-ID | <385d62a492942fc7a357c795049cbd57@ruby-forum.com> |
| In reply to | #4965 |
Andreas Lundgren wrote in post #1000537:
> The line
> params_2 = #{params};
> extends to:
> params_2 = x1.to_s + ', ' + x2.to_s + ', ' + x3.to_s + ', ' + x4.to_s
Or you could do it like this:
params_2 = "#{x1}, #{x2}, #{x3}, #{x4}"
#{} interpolates the value of an expression into a string and calls to_s
automatically.
A slightly more DRY version:
params_2 = [x1, x2, x3, x4].join(", ")
Again, to_s is called automatically in this case.
Finally, if you used the *args syntax to collect a variable number of
args into an array, then it would become
params_2 = args.join(", ")
or even just: handle.call(['MethodNameIn','Params'],[method]+args)
> Output from the function when STUB_CALLS=1:
Tiny suggestion: STUB_CALLS = false / true would be clearer, because
then you could say
do_something if STUB_CALLS
rather than
do_something if STUB_CALLS != 0
A global variable ($stub_calls) would arguably be preferable, since you
can change it at runtime without generating a warning. And better again
would be an instance variable of a class or module, because then it
lives in its own namespace.
module MyStuff
@stub_calls = false # set the default
def self.stub_calls
@stub_calls
end
def self.stub_calls=(x)
@stub_calls = x
end
end
puts MyStuff.stub_calls
MyStuff.stub_calls = true
puts MyStuff.stub_calls
Another thing to look at is using heredoc, as it means you don't have to
worry about quoting double-quotes:
class <<self;self;end.class_eval <<EOS
def #{f_name}(#{arg_list})
puts "Hello world"
end
EOS
Anyway, these are just tiny style suggestions. Having working code is
worth far more :-)
--
Posted via http://www.ruby-forum.com/.
[toc] | [prev] | [next] | [standalone]
| From | Robert Klemme <shortcutter@googlemail.com> |
|---|---|
| Date | 2011-05-24 03:39 -0500 |
| Message-ID | <BANLkTin-UeuEPYjg_SaZNyGQEY=iO3fvkw@mail.gmail.com> |
| In reply to | #4965 |
On Tue, May 24, 2011 at 9:25 AM, Andreas Lundgren
<andreas.lundgren.x@gmail.com> wrote:
> My bad to use the name "param" for two different content, but any
> ways:
>
> First params typically assembles to this:
> x1.to_s + ', ' + x2.to_s + ', ' + x3.to_s + ', ' + x4.to_s
That does not look good. If you have to encode numbers in variable
names, you probably rather want to use an Array for that or even
generate that directly:
params = no_of_params.times.map {|i| "x#{i}"}.join(', ')
> Now I have created the code, not the string.
>
> The line
> params_2 = #{params};
> extends to:
> params_2 = x1.to_s + ', ' + x2.to_s + ', ' + x3.to_s + ', ' + x4.to_s
> and assembles my input so that
> params_2 == 'myDB, 20110101, 20110201, all'
When looking at your posting from 2:55 you don't really need "params =
.." in the generated code.
> Output from the function when STUB_CALLS=1:
> Calling shop_GetFundReq(x1, x2, x3, x4) with parameters <myDB,
> 20110101, 20110201, all>
SUB_CALLS should be a boolean and treated as such.
I can see why 7stud wrote his recommendation: the code looks overly
complicated. Also, there are some issues, for example:
handle.call(['MethodNameIn','Params'],[#{method},params]);
This only works if you call that method with something like
(..., "\"myMethod\"", ...)
where you should really passing the name plainly as string. Makes
usage much simpler and more robust. So in the method body you then
had
handle.call(['MethodNameIn','Params'],['#{method}', params]);
Same reasoning applies in other locations such as return_format.
And if you get rid of the no_of_params you can simply use *args and do
not have to go through the hassle generating argument lists. If may
be though that you want to be able to query arity from the method and
have it fail fast if the argument list does not match in which case
it's OK to generate the argument list.
All in all it seems this is simpler and more redundancy free:
def GET_VALUE(f_name, method, return_format, no_of_params)
args = no_of_params.times.map {|i| "x#{i}"}.join(", ")
body = if STUB_CALLS
%Q{printf("Calling #{method}(#{args}) with parameters <%p>\\n", [#{args}])}
else
%Q{
oai = OA.instance
handle = oai.getWIN32OLEHandle()
handle.call(['MethodNameIn','Params'],['#{method}', [#{args}]]);
ret_val = handle.GetControlValue(#{return_format});
error = handle.GetControlValue('error out');
return oai.checkForError(error) ? 'NaN': ret_val
}
end
code = "def #{f_name}(#{args})\n#{body}\nend"
puts code if ENV['DEBUG'] == 'true'
class <<self;self;end.class_eval code
end
Cheers
robert
--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
[toc] | [prev] | [next] | [standalone]
| From | Andreas Lundgren <andreas.lundgren.x@gmail.com> |
|---|---|
| Date | 2011-05-24 06:46 -0700 |
| Message-ID | <ac4f0814-c75d-4c1e-b8f4-c277b3c94f0b@f11g2000vbx.googlegroups.com> |
| In reply to | #4967 |
> > First params typically assembles to this:
> > x1.to_s + ', ' + x2.to_s + ', ' + x3.to_s + ', ' + x4.to_s
>
> That does not look good. If you have to encode numbers in variable
> names, you probably rather want to use an Array for that or even
> generate that directly:
>
> params = no_of_params.times.map {|i| "x#{i}"}.join(', ')
your example generates code looks like this:
params = x1, x2, x3, x4
But with that I get an error (eval):3:in `+': can't convert Fixnum
into String (TypeError)
If it should work, I recon that it has to look like this:
params = "\"\#{" + no_of_params.times.map {|i| "x#{i}"}.join("}, \#{")
+ "}\""
becaus I need the generated code to look like this:
params = "#{x1}, #{x2}, #{x3}, #{x4}"
> handle.call(['MethodNameIn','Params'],[#{method},params]);
Yes, this was a bug...
> params_2 = "#{x1}, #{x2}, #{x3}, #{x4}"
Yes, I could use this, but still I need to assembly this line since I
dont know the number of input parameters at coding time. And I know
that no input parameters contain any expressions that needs to be
evaluated since it is an input from my generated function.
Join and times.map was kind of cool, my prototype has now replaced the
first loops with this:
arg_list = no_of_params.times.map {|i| "x#{i}"}.join(", ")
args = no_of_params.times.map {|i| "x#{i}.to_s"}.join("+','+")
(Using #{} instead of .to_s is basically the same:
args = "\"\#{" + no_of_params.times.map {|i| "x#{i}"}.join("}, \#{") +
"}\""
BR,
Andreas
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | comp.lang.ruby
csiph-web