Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > [SOLUTION] metakoans.rb (#67)

Reply
Thread Tools

[SOLUTION] metakoans.rb (#67)

 
 
Florian Groß
Guest
Posts: n/a
 
      02-19-2006
--------------060908050001010004030905
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit

Ruby Quiz wrote:

> # metakoans.rb is an arduous set of exercises designed to stretch
> # meta-programming muscle. the focus is on a single method 'attribute' which
> # behaves much like the built-in 'attr', but whose properties require delving
> # deep into the depths of meta-ruby.


Here we go then.

I have a golfed (8 lines) and a regular solution (21 lines) and
generally do the simplest thing that makes the tests work.

Got it to run in two tries by the way. I failed the fourtytwo test at
first. After that everything worked fine.

And thanks for a great quiz. Being able to do things test first rules!

--
http://flgr.0x42.net/

--------------060908050001010004030905
Content-Type: application/x-ruby;
name="flgr-metakoans-golfed.rb"
Content-Transfer-Encoding: base64
Content-Disposition: inline;
filename="flgr-metakoans-golfed.rb"

Y2xhc3MgTW9kdWxlOyBkZWYgYXR0cmlidXRlKG5hbWUsICZibG 9jaykNCiAgbmFtZSwgZGVm
YXVsdCA9ICpuYW1lLnNoaWZ0IGlmIG5hbWUuaXNfYT8oSGFzaC kNCiAgaXZhciwgZGVmYXVs
dF9sYW1iZGEgPSAiQCN7bmFtZX0iLCBibG9jayB8fCBsYW1iZG EgeyBkZWZhdWx0IH0NCiAg
ZGVmaW5lX21ldGhvZCg6IiN7bmFtZX09IikgeyB8dmFsfCBpbn N0YW5jZV92YXJpYWJsZV9z
ZXQoaXZhciwgdmFsKSB9DQogIGRlZmluZV9tZXRob2QobmFtZS kgeyBpbnN0YW5jZV92YXJp
YWJsZXMuaW5jbHVkZT8oaXZhcikgPw0KICAgIGluc3RhbmNlX3 ZhcmlhYmxlX2dldChpdmFy
KSA6IGluc3RhbmNlX2V2YWwoJmRlZmF1bHRfbGFtYmRhKSB9DQ ogIGFsaWFzX21ldGhvZCg6
IiN7bmFtZX0/IiwgbmFtZSkNCmVuZDsgZW5kDQo=
--------------060908050001010004030905
Content-Type: application/x-ruby;
name="flgr-metakoans.rb"
Content-Transfer-Encoding: base64
Content-Disposition: inline;
filename="flgr-metakoans.rb"

Y2xhc3MgTW9kdWxlDQogIGRlZiBhdHRyaWJ1dGUobmFtZSwgJm Jsb2NrKQ0KICAgIG5hbWUs
IGRlZmF1bHQgPSAqbmFtZS5zaGlmdCBpZiBuYW1lLmlzX2E/KEhhc2gpDQogICAgZGVmYXVs
dF9sYW1iZGEgPSBibG9jayB8fCBsYW1iZGEgeyBkZWZhdWx0IH 0NCiAgICBpdmFyID0gIkAj
e25hbWV9Ig0KDQogICAgZGVmaW5lX21ldGhvZCg6IiN7bmFtZX 09IikgZG8gfG5ld192YWx1
ZXwNCiAgICAgIGluc3RhbmNlX3ZhcmlhYmxlX3NldChpdmFyLC BuZXdfdmFsdWUpDQogICAg
ZW5kDQoNCiAgICBkZWZpbmVfbWV0aG9kKG5hbWUpIGRvDQogIC AgICBpZiBpbnN0YW5jZV92
YXJpYWJsZXMuaW5jbHVkZT8oaXZhcikgdGhlbg0KICAgICAgIC BpbnN0YW5jZV92YXJpYWJs
ZV9nZXQoaXZhcikNCiAgICAgIGVsc2UNCiAgICAgICAgaW5zdG FuY2VfZXZhbCgmZGVmYXVs
dF9sYW1iZGEpDQogICAgICBlbmQNCiAgICBlbmQNCg0KICAgIG FsaWFzX21ldGhvZCg6IiN7
bmFtZX0/IiwgbmFtZSkNCiAgZW5kDQplbmQNCg==
--------------060908050001010004030905--


 
Reply With Quote
 
 
 
 
James Edward Gray II
Guest
Posts: n/a
 
      02-19-2006
On Feb 19, 2006, at 8:21 AM, Florian Gro=DF wrote:

> Ruby Quiz wrote:
>
>> # metakoans.rb is an arduous set of exercises designed to =

stretch
>> # meta-programming muscle. the focus is on a single method =20
>> 'attribute' which
>> # behaves much like the built-in 'attr', but whose properties =20=


>> require delving
>> # deep into the depths of meta-ruby.

>
> Here we go then.


Here's what I coded up, back when Ara sent me the quiz. Everyone =20
else found much prettier code though.

James Edward Gray II

#!/usr/local/bin/ruby -w

class Module
def attribute( name, &block )
if name.is_a? Hash
name.each do |attr_name, default|
define_method(attr_name) do
if instance_variables.include?("@#{attr_name}")
instance_variable_get("@#{attr_name}")
else
default
end
end

define_method("#{attr_name}=3D") do |value|
instance_variable_set("@#{attr_name}", value)
end

define_method("#{attr_name}?") do
send(attr_name) ? true : false
end
end
elsif block
define_method(name) do
if instance_variables.include?("@#{name}")
instance_variable_get("@#{name}")
else
instance_eval(&block)
end
end

define_method("#{name}=3D") do |value|
instance_variable_set("@#{name}", value)
end

define_method("#{name}?") do
send(name) ? true : false
end
else
define_method(name) do
instance_variable_get("@#{name}")
end

define_method("#{name}=3D") do |value|
instance_variable_set("@#{name}", value)
end

define_method("#{name}?") do
send(name) ? true : false
end
end
end
end



 
Reply With Quote
 
 
 
 
Ryan Leavengood
Guest
Posts: n/a
 
      02-19-2006
Here is mine. Nothing too extraordinary or different than other
solutions, but it is fairly short and readable.

class Module
def attribute(x, &block)
name, value =3D x.to_a[0] # produces a warning is x is a symbol
ivar =3D "@#{name}"
define_method(name) do
if instance_variables.include?(ivar)
instance_variable_get(ivar)
else
value || (instance_eval &block if block)
end
end
attr_writer name
define_method("#{name}?") { !!send(name) }
end
end

As others have said, this was a cool quiz. While the meta-programming
part was interesting, I think this quiz is a better advertisement for
test-first coding than anything! Very cool and fun test suite. Thanks
Ara.

Ryan


 
Reply With Quote
 
Michael Ulm
Guest
Posts: n/a
 
      02-20-2006
Christian Neukirchen wrote:

> Florian Gro=DF <> writes:
>=20
>=20
>>Ruby Quiz wrote:
>>
>>
>>> # metakoans.rb is an arduous set of exercises designed to stretch
>>> # meta-programming muscle. the focus is on a single method 'attribut=

e' which
>>> # behaves much like the built-in 'attr', but whose properties require=

delving
>>> # deep into the depths of meta-ruby.

>>
>>Here we go then.
>>
>>I have a golfed (8 lines) and a regular solution (21 lines) and
>>generally do the simplest thing that makes the tests work.
>>
>>Got it to run in two tries by the way. I failed the fourtytwo test at
>>first. After that everything worked fine.

>=20
>=20
> Here's my solution, done in two tries too. Took about 15 minutes, I
> think.
>=20
>=20
> class Module
> def attribute(a, &block)
> if a.kind_of? Hash
> a, default =3D a.to_a.first
> else
> default =3D nil
> end
>=20
> a =3D a.to_sym
> ivar =3D "@#{a}"
>=20
> define_method(a) {
> if instance_variables.include? ivar
> instance_variable_get ivar
> else
> block ? instance_eval(&block) : default
> end
> }
> define_method("#{a}=3D") { |v| instance_variable_set ivar, v }
> define_method("#{a}?") { !!__send__(a) }
> end
> end
>=20


This demonstrates a problem I have with many solutions -- taking
Florians as an example.

class Test
attribute 'a'
end

tst.a? # =3D> false OK
tst.a =3D false # =3D> false OK
tst.a? # =3D> false This should be true


Regards,

Michael

--=20
Michael Ulm
R&D Team
ISIS Information Systems Austria
tel: +43 2236 27551-219, fax: +43 2236 21081
e-mail:
Visit our Website: www.isis-papyrus.com

---------------------------------------------------------------
This e-mail is only intended for the recipient and not legally
binding. Unauthorised use, publication, reproduction or
disclosure of the content of this e-mail is not permitted.
This email has been checked for known viruses, but ISIS accepts
no responsibility for malicious or inappropriate content.
---------------------------------------------------------------


 
Reply With Quote
 
Michael Ulm
Guest
Posts: n/a
 
      02-20-2006
Michael Ulm wrote:

--snip--
>
> This demonstrates a problem I have with many solutions -- taking
> Florians as an example.
>

--snip--

s/Florian/Christian/

So sorry,

Michael


--
Michael Ulm
R&D Team
ISIS Information Systems Austria
tel: +43 2236 27551-219, fax: +43 2236 21081
e-mail:
Visit our Website: www.isis-papyrus.com

---------------------------------------------------------------
This e-mail is only intended for the recipient and not legally
binding. Unauthorised use, publication, reproduction or
disclosure of the content of this e-mail is not permitted.
This email has been checked for known viruses, but ISIS accepts
no responsibility for malicious or inappropriate content.
---------------------------------------------------------------


 
Reply With Quote
 
James Edward Gray II
Guest
Posts: n/a
 
      02-20-2006
On Feb 20, 2006, at 8:38 AM, Michael Ulm wrote:

> This demonstrates a problem I have with many solutions -- taking
> Florians as an example.
>
> class Test
> attribute 'a'
> end
>
> tst.a? # => false OK
> tst.a = false # => false OK
> tst.a? # => false This should be true


I believe you are making the mistake that you expect attr_meth?() to
tell you if an attribute is set. That's not the intention. attr_meth
() returns true if the attribute holds a true value.

I know this because I made the exact same mistake and Ara corrected
me.

James Edward Gray II


 
Reply With Quote
 
Michael Ulm
Guest
Posts: n/a
 
      02-20-2006
James Edward Gray II wrote:

> On Feb 20, 2006, at 8:38 AM, Michael Ulm wrote:
>
>> This demonstrates a problem I have with many solutions -- taking
>> Florians as an example.
>>
>> class Test
>> attribute 'a'
>> end
>>
>> tst.a? # => false OK
>> tst.a = false # => false OK
>> tst.a? # => false This should be true

>
>
> I believe you are making the mistake that you expect attr_meth?() to
> tell you if an attribute is set. That's not the intention. attr_meth
> () returns true if the attribute holds a true value.
>
> I know this because I made the exact same mistake and Ara corrected
> me.


I just checked the metakoans.rb file, and see that you are right:

# o.a? # query - true if @a

Had I defined the interface, this would behave differently. I guess
this shows that I am not enlightened yet.

Regards,

Michael


--
Michael Ulm
R&D Team
ISIS Information Systems Austria
tel: +43 2236 27551-219, fax: +43 2236 21081
e-mail:
Visit our Website: www.isis-papyrus.com

---------------------------------------------------------------
This e-mail is only intended for the recipient and not legally
binding. Unauthorised use, publication, reproduction or
disclosure of the content of this e-mail is not permitted.
This email has been checked for known viruses, but ISIS accepts
no responsibility for malicious or inappropriate content.
---------------------------------------------------------------


 
Reply With Quote
 
Jeremy Hinegardner
Guest
Posts: n/a
 
      02-21-2006
--huq684BweRXVnRxX
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Great quiz Ara, and here's my solution. For some reason I wasn't using
instance_eval correctly, so I ended up defining an initalizer method for
the attribute. Also, I seem to have implemented the attr? method in a
manner different than most folks.

enjoy,

-jeremy

--
================================================== ======================
Jeremy Hinegardner


--huq684BweRXVnRxX
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="ruby-quiz_67.rb"


# ruby quiz #67 - knowledge.rb
#
# Jeremy Hinegardner

class Module

def _make_attribute(name,value=nil)
at = "@#{name}"
sym = at.to_sym
name_init = "_#{name}_init"

if value.respond_to?("call") then
define_method(name_init,value)
end

define_method(name) do
if not self.instance_variables.include?(at) then
initial_value = value
if self.methods.include?(name_init) then
initial_value = self.send(name_init)
end
self.instance_variable_set(sym,initial_value)
end
self.instance_variable_get(sym)
end

define_method("#{name}=") { |val| self.instance_variable_set(sym,val) }
define_method("#{name}?") { not [false, nil].include?(self.instance_variable_get(sym)) }
end

def attribute(*args, &block)
args.each do |arg|
if arg.kind_of?(Hash) then
arg.each_pair do |k,v|
if block_given? then
_make_attribute(k,block)
else
_make_attribute(k,v)
end
end
else
_make_attribute(arg,block)
end
end
end
end


--huq684BweRXVnRxX--


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off




Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57