Hi,
here's what I'd like to do in a silly example:
S = Struct.new :foo, :bar
init = lambda do |a, b|
self.foo = b
self.bar = a + 10
end
s = S.new # or create an instance otherwise
# now comes the fun part which does not work
s.instance_eval(1, 2, &init)
=> #<struct S foo=2, bar=11>
In other words: I like to define a block as an initializer which I can
store away somewhere and invoke that initializer later on in the
context of "self" and pass arguments at the same time. Any ideas how
I can accomplish this elegantly?
Kind regards
robert
--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
|
|
0
|
|
|
|
Reply
|
shortcutter (5780)
|
10/8/2009 4:04:24 PM |
|
On Thu, Oct 8, 2009 at 6:04 PM, Robert Klemme
<shortcutter@googlemail.com> wrote:
> Hi,
>
> here's what I'd like to do in a silly example:
>
> S =3D Struct.new :foo, :bar
>
> init =3D lambda do |a, b|
> =A0self.foo =3D b
> =A0self.bar =3D a + 10
> end
>
> s =3D S.new # or create an instance otherwise
>
> # now comes the fun part which does not work
> s.instance_eval(1, 2, &init)
> =3D> #<struct S foo=3D2, bar=3D11>
>
> In other words: I like to define a block as an initializer which I can
> store away somewhere and invoke that initializer later on in the
> context of "self" and pass arguments at the same time. =A0Any ideas how
> I can accomplish this elegantly?
Probably not exactly what you want (can't make self to not be main
inside the lambda), but what about:
irb(main):001:0> S =3D Struct.new :foo, :bar
=3D> S
irb(main):003:0> s =3D S.new
=3D> #<struct S foo=3Dnil, bar=3Dnil>
irb(main):040:0> def s.init(*args,&blk) #you can put this in a module
and extend s with it, or add it to S
irb(main):041:1> blk[self,*args]
irb(main):042:1> end
irb(main):043:0> init =3D lambda do |o,a,b|
irb(main):044:1* o.foo =3D b
irb(main):045:1> o.bar =3D a + 10
irb(main):046:1> end
=3D> #<Proc:0xb7d78f18@(irb):43>
irb(main):047:0> s.init(1,2,&init)
=3D> 11
irb(main):048:0> s
=3D> #<struct S foo=3D2, bar=3D11>
Don't know if this is good enough.
Jesus.
|
|
0
|
|
|
|
Reply
|
jgabrielygalan (544)
|
10/8/2009 4:52:47 PM
|
|
[Note: parts of this message were removed to make it a legal post.]
On Thu, Oct 8, 2009 at 10:04 AM, Robert Klemme
<shortcutter@googlemail.com>wrote:
> In other words: I like to define a block as an initializer which I can
> store away somewhere and invoke that initializer later on in the
> context of "self" and pass arguments at the same time. Any ideas how
> I can accomplish this elegantly?
>
Sounds like you need instance_exec, which is a 1.9 feature but there are
implementations for 1.8:
http://eigenclass.org/hiki.rb?instance_exec
--
Tony Arcieri
Medioh/Nagravision
|
|
0
|
|
|
|
Reply
|
tony929 (215)
|
10/8/2009 7:21:21 PM
|
|
On 10/08/2009 09:21 PM, Tony Arcieri wrote:
> [Note: parts of this message were removed to make it a legal post.]
>
> On Thu, Oct 8, 2009 at 10:04 AM, Robert Klemme
> <shortcutter@googlemail.com>wrote:
>
>> In other words: I like to define a block as an initializer which I can
>> store away somewhere and invoke that initializer later on in the
>> context of "self" and pass arguments at the same time. Any ideas how
>> I can accomplish this elegantly?
>>
>
> Sounds like you need instance_exec, which is a 1.9 feature but there are
> implementations for 1.8:
>
> http://eigenclass.org/hiki.rb?instance_exec
1.9 is OK.
irb(main):001:0> l = lambda {|a| self + a}
=> #<Proc:0x9f5cfe0@(irb):1 (lambda)>
irb(main):002:0> 1.instance_exec(2,&l)
=> 3
Perfect! This is _exactly_ what I need. Thanks a bunch!
This article is so old, I can't believe I missed this completely.
Amazing: learn something new every day.
Kind regards
robert
--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
|
|
0
|
|
|
|
Reply
|
shortcutter (5780)
|
10/8/2009 8:36:36 PM
|
|
On 10/08/2009 06:52 PM, Jes=FAs Gabriel y Gal=E1n wrote:
> On Thu, Oct 8, 2009 at 6:04 PM, Robert Klemme
> <shortcutter@googlemail.com> wrote:
>> Hi,
>>
>> here's what I'd like to do in a silly example:
>>
>> S =3D Struct.new :foo, :bar
>>
>> init =3D lambda do |a, b|
>> self.foo =3D b
>> self.bar =3D a + 10
>> end
>>
>> s =3D S.new # or create an instance otherwise
>>
>> # now comes the fun part which does not work
>> s.instance_eval(1, 2, &init)
>> =3D> #<struct S foo=3D2, bar=3D11>
>>
>> In other words: I like to define a block as an initializer which I can=
>> store away somewhere and invoke that initializer later on in the
>> context of "self" and pass arguments at the same time. Any ideas how
>> I can accomplish this elegantly?
>=20
> Probably not exactly what you want (can't make self to not be main
> inside the lambda), but what about:
>=20
> irb(main):001:0> S =3D Struct.new :foo, :bar
> =3D> S
> irb(main):003:0> s =3D S.new
> =3D> #<struct S foo=3Dnil, bar=3Dnil>
> irb(main):040:0> def s.init(*args,&blk) #you can put this in a module
> and extend s with it, or add it to S
> irb(main):041:1> blk[self,*args]
> irb(main):042:1> end
> irb(main):043:0> init =3D lambda do |o,a,b|
> irb(main):044:1* o.foo =3D b
> irb(main):045:1> o.bar =3D a + 10
> irb(main):046:1> end
> =3D> #<Proc:0xb7d78f18@(irb):43>
> irb(main):047:0> s.init(1,2,&init)
> =3D> 11
> irb(main):048:0> s
> =3D> #<struct S foo=3D2, bar=3D11>
>=20
> Don't know if this is good enough.
Thank you! Unfortunately I tried to avoid explicit passing of the=20
reference.
Kind regards
robert
--=20
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
|
|
0
|
|
|
|
Reply
|
shortcutter (5780)
|
10/8/2009 8:39:30 PM
|
|
|
4 Replies
20 Views
(page loaded in 0.044 seconds)
|