[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

define anonymous module with closure

I. E. Smith-Heisters

9/16/2008 7:24:00 PM

Hi everyone,

I want to do this:

x, y = %w(x y)
definition = lambda{def z; x; end}
y.extend Module.new(&definition)
y.z # => 'x'

I expected x to be available within the closure, but it doesn't appear
to be. The only way I've found is with module_eval:

x, y = %w(x y)
mod = Module.new
mod.module_eval "def z; #{x.inspect}; end"
y.extend mod
y.z # => 'x'

Which I guess is fine, but I'm opposed to eval, and especially
eval'ing strings, on principle.

So:

Why doesn't the first option work? I saw something somewhere about the
argument to Module::new being called within some other scope/context/
whatsit?

Is there a way to do this without eval?

Thanks!
-Ian
4 Answers

ara.t.howard

9/16/2008 7:47:00 PM

0


On Sep 16, 2008, at 1:17 PM, I. E. Smith-Heisters wrote:

> x, y = %w(x y)
> definition = lambda{def z; x; end}
> y.extend Module.new(&definition)
> y.z # => 'x'



cfp:~ > cat a.rb
x, y = %w( x y )

definition = lambda{ define_method(:z){ x } }

y.extend Module.new(&definition)

p y.z # => 'x'


cfp:~ > ruby a.rb
"x"


'def' creates a new scope - you lose the closure surrounding 'x'. to
keep it use 'define_method', which takes a block - aka closure.


a @ http://codeforp...
--
we can deny everything, except that we have the possibility of being
better. simply reflect on that.
h.h. the 14th dalai lama




I. E. Smith-Heisters

9/16/2008 8:23:00 PM

0

On Sep 16, 12:46 pm, "ara.t.howard" <ara.t.how...@gmail.com> wrote:
> On Sep 16, 2008, at 1:17 PM, I. E. Smith-Heisters wrote:
>
> > x, y = %w(x y)
> >  definition = lambda{def z; x; end}
> >  y.extend Module.new(&definition)
> >  y.z # => 'x'
>
> cfp:~ > cat a.rb
> x, y = %w( x y )
>
> definition = lambda{ define_method(:z){ x } }
>
> y.extend Module.new(&definition)
>
> p y.z # => 'x'
>
> cfp:~ > ruby a.rb
> "x"
>
> 'def' creates a new scope - you lose the closure surrounding 'x'.  to  
> keep it use 'define_method', which takes a block - aka closure.
>
> a @http://codeforp...
> --
> we can deny everything, except that we have the possibility of being  
> better. simply reflect on that.
> h.h. the 14th dalai lama

brilliant! thanks for the explanation and solution all in one.

ara.t.howard

9/16/2008 10:32:00 PM

0


On Sep 16, 2008, at 2:17 PM, I. E. Smith-Heisters wrote:

> brilliant! thanks for the explanation and solution all in one.

np. if you need a block then:

cfp:~ > cat a.rb
x, y = %w( x y )

m = Module.new do
@@x = x

def z *args, &block
block.call if block
@@x
end
end

y.extend m

p y.z # => 'x'

y.z{ puts 'you need to do it this way if you want your method to take
a block' }


cfp:~ > ruby a.rb
"x"
you need to do it this way if you want your method to take a block


a @ http://codeforp...
--
we can deny everything, except that we have the possibility of being
better. simply reflect on that.
h.h. the 14th dalai lama




quixoticsycophant

9/17/2008 1:58:00 AM

0


Ara Howard wrote:
> cfp:~ > ruby a.rb
> "x"
> you need to do it this way if you want your method to take a block

...if you are constrained to 1.8.6.

% ruby --version
ruby 1.8.7 (2008-08-11 patchlevel 72)

class A
define_method(:f) { |x, &block|
puts "A#f argument: #{x}"
block.call(88)
}
end

A.new.f(99) { |t|
puts "block called with: #{t}"
}
# => A#f argument: 99
# block called with: 88

Now if you want default parameters, you'll need Ara's example again.
Unless you use 1.9...

% ruby --version
ruby 1.9.0 (2008-09-15 revision 19346)

class A
t = ->(a = 11, b = 22) { a + b }
define_method(:g, &t)
end

a = A.new
p a.g # => 33
p a.g(33) # => 55
p a.g(33, 44) # => 77

From what I gathered, -> was introduced because

lambda { |a = 11, b = 22| a + b }

was too difficult or ambiguous to parse. My feeling is that -> should
be avoided if at all possible, no matter how difficult.

To me, -> is a step toward ruby jumping the shark. I want to yell,
"Fonzie, don't do it!" (Excuse the Americanisms.)
--
Posted via http://www.ruby-....