thanks for all the response on the float problem. alot of people jumped on
that one. guess everyone but me knew the answer.
anyway, i’m sitting here coding my billy-bad-ass cgi accounting system, in
yours truly, ruby, and i’m running into small sticky spots in which i want to
keep a library i created pure for general use, yet i run into particular
situations where the behavior needs a minor tweak to work. upon looking at
these recoccuring catches, i started to develop a notion of "virus-like"
arguments.
the idea is that rather then pass simple argumments, one could pass a little
piece of code that would execute in the context of the method.
here’s a foo example (vproc is like proc but viral):
Thus, no argument returns a predefined default
Argument returns defined behavior operating on argument
Block returns returns operation on variable i
Note & in front of block names (bar and baz); this tells Ruby a block
has been passed (given). The block_given? method in the if statement
tests for that.
This is a very powerful feature; there are a lot of possibilities. Play
araound, experiement and enjoy.
Hope this helps?
Regards,
Kent Starr
···
On Fri, 2002-12-27 at 03:12, Tom Sawyer wrote:
the idea is that rather then pass simple argumments, one could pass a little
piece of code that would execute in the context of the method.
here’s a foo example (vproc is like proc but viral):
def foo(x)
i = 1
puts “#{x + i}”
end
puts foo(4) → 5
puts foo(vproc {i + 1}) → 3
any thoughts? can ruby achieve something like this already?
Adding a new instance method to String class which “re evaluates”
the string in the context of the Kernel::binding object we pass in.
(Note that the here-document approach this uses tacks on an extra
\n to the resulting string… but that was fine for my purposes.)
class String
def reeval(b = TOPLEVEL_BINDING)
eval(%Q{<<“END_REEVAL”\n} + self + “\nEND_REEVAL\n”, b)
end
end
class BeadShot
…
def gen_fullsize_html(prev_shot, next_shot)
#
# Here, a string containing the HTML template for the
# page we’re generating is “reevaluated” in the current
# context - so it has access (via interpolation #{ }) to
# the current BeadShot instance’s methods, and even the
# local variables in scope at the moment (prev_shot,
# next_shot).
#
html = $bead_fullsize_page.reeval(binding)
end
def item_number @file_num + $item_number_offset
end
… etc.
end
Here’s an excerpt from the string reevaluated by the code
above. Note that I wanted interpolation to occur both when
the string was defined - to pull in other components of the
page like $header_html - and later when re-evaluated; so
the interpolation that’s deferred for “reeval” is escaped
thanks for all the response on the float problem. alot of people jumped on
that one. guess everyone but me knew the answer.
anyway, i’m sitting here coding my billy-bad-ass cgi accounting system, in
yours truly, ruby, and i’m running into small sticky spots in which i want to
keep a library i created pure for general use, yet i run into particular
situations where the behavior needs a minor tweak to work. upon looking at
these recoccuring catches, i started to develop a notion of “virus-like”
arguments.
the idea is that rather then pass simple argumments, one could pass a little
piece of code that would execute in the context of the method.
here’s a foo example (vproc is like proc but viral):
def foo(x)
i = 1
puts “#{x + i}”
end
puts foo(4) → 5
puts foo(vproc {i + 1}) → 3
any thoughts? can ruby achieve something like this already?
It’s not clear to me why executing “i+1” at the top of the method
would do anything but raise an exception (unless the object has an #i
method)… but in any case, see Kent’s answer about blocks. Also,
consider the impossibility of maintaining and debugging code where the
names of a method’s local variables have to be known outside the
method. That’s why they’re local
If I understand you (which I very well may not :), you are asking if you can
execute a block in the context of the method you send the block into.
Check out html/common.rb (comes standard with Ruby) which has html
generation code. In the middle of HTML.def_element you’ll see:
buf = instance_eval(&block)
It’s that simple.
(Mind you, it took me quite a while to figure out why my #$*!ing blocks
weren’t working properly! When I found out what was going on, I stopped
using this library and wrote a quick-n-dirty one of my own. Now I just
subclass.)
If I am understanding you correctly, Ruby has this mechanism already.
It is called a “block” (much better sounding than “viral” is it not?)
…
Thus, no argument returns a predefined default
Argument returns defined behavior operating on argument
Block returns returns operation on variable i
Note & in front of block names (bar and baz); this tells Ruby a block
has been passed (given). The block_given? method in the if statement
tests for that.
This is a very powerful feature; there are a lot of possibilities. Play
araound, experiement and enjoy.
Kent,
this is kind of like what i’m talking about. blocks are very powerful indeed,
and i have used blocks many a time.
the differenece between this and my idea though is that, with blocks, one must
pre-program the method to deal with the incoming block. my notion dosen’t
have this requirement.
of course david’s right, my example is poor in that the viral argument
shouldn’t be able to access local variables, only public accessable methods.
-transami
···
On Friday 27 December 2002 03:11 am, W. Kent Starr wrote:
Saturday, December 28, 2002, 9:10:33 AM, you wrote:
the differenece between this and my idea though is that, with blocks, one must
pre-program the method to deal with the incoming block. my notion dosen’t
have this requirement.
i think that thing you want called “lazy (deferred) evaluation”. it’s fashion
of modern functional languages, but it’s slows down all the program and more
hard to understand by “average” programmer. see haskell language if you interested
in this. one example of power of this technique:
def natural_numbers
return [1] + natural_numbers.map{|x| x+1}
end
def fib
return [1,1] + natural_numbers.each{|i| fib[i-1]+fib[i]}
end
print fib[0…100]
actuall, this technique - passing ALL arguments as blocks and evaluating
them only when algorithm needs concrete value and only to that
deepness level that needed for algorithm. it’s very power technique
for lists manipulation - you can represent naturally INFINITE lists
with recursive definition which will be evaluated only to the element(s)
you need