how to be cool with map

G

Giles Bowkett

So I've got this file-checking script:

def check
ok = true
for_every_app do |app,app_info|
ok = File.exists?(app_info[:root])
end
ok
end

And it has a bug, which is that if it evaluates a good file after a
bad file, it'll return true for the whole list.

So here's my suggested change:

def check
ok = true
for_every_app.values.each do |app_info|
ok = File.exists?(app_info[:root]) if ok
end
ok
end

Because if we have one false value, then the whole test is
unnecessary. It's basically like a short-circuit operator.

But I think there's a better way to do it with map.

Something like

File.exists?(for_every_app.values.map{|x| x}

I think I'm way off, though. How do I get that right?

--
Giles Bowkett

Blog: http://gilesbowkett.blogspot.com
Portfolio: http://www.gilesgoatboy.org
Tumblelog: http://giles.tumblr.com/
 
D

David A. Black

Hi --

So I've got this file-checking script:

def check
ok = true
for_every_app do |app,app_info|

Do you mean for there to be an .each in there?
ok = File.exists?(app_info[:root])
end
ok
end

And it has a bug, which is that if it evaluates a good file after a
bad file, it'll return true for the whole list.

So here's my suggested change:

def check
ok = true
for_every_app.values.each do |app_info|
ok = File.exists?(app_info[:root]) if ok
end
ok
end

Because if we have one false value, then the whole test is
unnecessary. It's basically like a short-circuit operator.

But I think there's a better way to do it with map.

Something like

File.exists?(for_every_app.values.map{|x| x}

I think I'm way off, though. How do I get that right?

You could do:

def check
for_every_app.all? {|app,info| File.exists?(info[:root])}
end


David

--
* Books:
RAILS ROUTING (new! http://www.awprofessional.com/title/0321509242)
RUBY FOR RAILS (http://www.manning.com/black)
* Ruby/Rails training
& consulting: Ruby Power and Light, LLC (http://www.rubypal.com)
 
E

Erik Veenstra

Faster, because it breaks the loop as soon as possible, and
less LOC:

def check
for_every_app.values.find do |app_info|
not File.exists?(app_info[:root])
end ? false : true
end

You may want to skip the "? false : true" part, but that breaks
the encapsulation.

gegroet,
Erik V. - http://www.erikveen.dds.nl/
 
S

Stefano Crocco

Alle mercoled=EC 22 agosto 2007, Erik Veenstra ha scritto:
Faster, because it breaks the loop as soon as possible, and
less LOC:

def check
for_every_app.values.find do |app_info|
not File.exists?(app_info[:root])
end ? false : true
end

You may want to skip the "? false : true" part, but that breaks
the encapsulation.

gegroet,
Erik V. - http://www.erikveen.dds.nl/

This is shorter, and breaks as soon as a non-existing file is found

def check
!for_every_app.values.any?{|f| !File.exist?(f)}
end

Stefano
 
K

Kaldrenon

So I've got this file-checking script:

def check
ok = true
for_every_app do |app,app_info|
ok = File.exists?(app_info[:root])
end
ok
end

And it has a bug, which is that if it evaluates a good file after a
bad file, it'll return true for the whole list.

So here's my suggested change:

def check
ok = true
for_every_app.values.each do |app_info|
ok = File.exists?(app_info[:root]) if ok
end
ok
end

Because if we have one false value, then the whole test is
unnecessary. It's basically like a short-circuit operator.

But I think there's a better way to do it with map.

Something like

File.exists?(for_every_app.values.map{|x| x}

I think I'm way off, though. How do I get that right?

--
Giles Bowkett

Blog:http://gilesbowkett.blogspot.com
Portfolio:http://www.gilesgoatboy.org
Tumblelog:http://giles.tumblr.com/

How about inject?

for_every_app.inject(true) {|good,x| good = File.exists?(x) if good}
 
D

David A. Black

--1926193751-1852195539-1187816098=:25922
Content-Type: MULTIPART/MIXED; BOUNDARY="1926193751-1852195539-1187816098=:25922"

This message is in MIME format. The first part should be readable text,
while the remaining parts are likely unreadable without MIME-aware tools.

--1926193751-1852195539-1187816098=:25922
Content-Type: TEXT/PLAIN; charset=X-UNKNOWN; format=flowed
Content-Transfer-Encoding: QUOTED-PRINTABLE

Hi --

Alle mercoled=EC 22 agosto 2007, Erik Veenstra ha scritto:
Faster, because it breaks the loop as soon as possible, and
less LOC:

def check
for_every_app.values.find do |app_info|
not File.exists?(app_info[:root])
end ? false : true
end

You may want to skip the "? false : true" part, but that breaks
the encapsulation.

gegroet,
Erik V. - http://www.erikveen.dds.nl/

This is shorter, and breaks as soon as a non-existing file is found

def check
!for_every_app.values.any?{|f| !File.exist?(f)}
end

You can save yourself the double negative:

for_every_app.values.all?{|f| File.exist?(f)}

And even save the creation of an intermediate array of values:

for_every_app.all?{|a,b| File.exist?(b)}

But I repeat myself :) (See my earlier post.)


David

--=20
* Books:
RAILS ROUTING (new! http://www.awprofessional.com/title/0321509242)
RUBY FOR RAILS (http://www.manning.com/black)
* Ruby/Rails training
& consulting: Ruby Power and Light, LLC (http://www.rubypal.com)
--1926193751-1852195539-1187816098=:25922--
--1926193751-1852195539-1187816098=:25922--
 
K

Kaldrenon

So I've got this file-checking script:
def check
ok = true
for_every_app do |app,app_info|
ok = File.exists?(app_info[:root])
end
ok
end
And it has a bug, which is that if it evaluates a good file after a
bad file, it'll return true for the whole list.
So here's my suggested change:
def check
ok = true
for_every_app.values.each do |app_info|
ok = File.exists?(app_info[:root]) if ok
end
ok
end
Because if we have one false value, then the whole test is
unnecessary. It's basically like a short-circuit operator.
But I think there's a better way to do it with map.
Something like
File.exists?(for_every_app.values.map{|x| x}
I think I'm way off, though. How do I get that right?

How about inject?

for_every_app.inject(true) {|good,x| good = File.exists?(x) if good}

I guess this would be for_every_app.values.inject(true) {|good,x| good
= File.exists?(x) if good}

But I think the idea was clear.
 
S

Stefano Crocco

Alle mercoled=EC 22 agosto 2007, David A. Black ha scritto:
You can save yourself the double negative:

=A0 =A0for_every_app.values.all?{|f| File.exist?(f)}

And even save the creation of an intermediate array of values:

=A0 =A0for_every_app.all?{|a,b| File.exist?(b)}

But I repeat myself :) =A0(See my earlier post.)


David

You're right. Somehow, I thought that all? needed to iterate over all the=20
values and any? didn't. Of course, now I realized that, just as any? will=20
stop at the first positive result, all? will stop at the first negative=20
result.

Stefano
 
A

ara.t.howard

So I've got this file-checking script:

def check
ok = true
for_every_app do |app,app_info|
ok = File.exists?(app_info[:root])
end
ok
end

this sends alarm bells ringing to me. i would expect, from that
small sample of code, that i could do

a_ok = apps.all?{|app| app.info.root.exist?}

which is to say apps is a method or collection, an app knows it's
info, an info object knows it's root, and that root is a Pathname
object so therefore has an exist method. which would obviate the
need for a method ;-)

2cts.

a @ http://drawohara.com/
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,231
Members
46,820
Latest member
GilbertoA5

Latest Threads

Top