 |
Forums |
Admin Start New Thread
By: Leon Barrett
RE: I found it! [ reply ] 2005-08-18 19:43
|
That looks good, but it still uses a defined function instead of just a block. Here's how I would do it with just a block. (Notice that func is not declared anywhere.)
#
# recursive walk that lets you pass in
# a function, like Python's os.path.walk
#
DIR = "/home/ruby/Mail" # some dir tree to walk
def walk(top, &block)
names = Dir.entries(top)
names.delete(".")
names.delete("..")
yield(top, names)
names.each{ | name |
name = File.join(top, name)
if File.ftype(name) == "directory"
walk(name,&block) #recurse, passing the same block
end
}
end
walk(DIR) { |*list|
print "dir: "+list[0]+"\n"
list[1].each{ |x|print x + "\n"}
}
|
By: Ruby Dos Zapatas
I found it! [ reply ] 2005-08-18 15:32
|
hey, leon. I finally got it. Here's the walk method in Spirit made general. Muchas gracias.
#
# recursive walk that lets you pass in
# a function, like Python's os.path.walk
#
DIR = "/home/ruby/Mail" # some dir tree to walk
def walk(top, &block)
names = Dir.entries(top)
names.delete(".")
names.delete("..")
yield(top, names)
names.each{ | name |
name = File.join(top, name)
if File.ftype(name) == "directory"
walk(name) { |*list| func(*list) }
end
}
end
def func(*list)
print "dir: "+list[0]+"\n"
list[1].each{ |x|print x + "\n"}
end
walk(DIR) { |*list| func(*list) }
|
By: Leon Barrett
RE: defining a block [ reply ] 2005-08-17 16:45
|
Yes, essentially. However, the block doesn't have to be declared as 'block' before you call 'walk'. The calling conventions are more like this:
walk(parameters) { |block_params| *this is the block* ; code ; more code}
or, using a different syntax to do exactly the same thing:
walk(parameters) do |block_params|
*this is the block
code
more code
end
So, just putting a block after a function passes that block to the function. The function, then, has two ways of accessing the block. It can call 'yield', which calls the block. Or, the function can declare a variable prefixed with &; that ampersand indicates that the block is stored in that variable.
Hmm. I'm not so sure I'm explaining this well. If you're still curious, you can check out a section from the Pragmatic Programmer's guide to Ruby. Read the bit on 'Blocks and Iterators' in http://www.rubycentral.com/book/tut_containers.html
|
By: Ruby Dos Zapatas
RE: defining a block [ reply ] 2005-08-17 15:19
|
gracias, leon,
so what you're saying is I can write a block called block like this
block {
code
more code
}
and then call it in walk with &block?
(I'm actually working this out for myself. But
if we spell it out, maybe we help more gente, no?)
|
By: Leon Barrett
RE: Help Ruby do good Ruby [ reply ] 2005-08-17 05:15
|
Dangit. I really meant to finish that. Suppose you have a function 'subcase' to easily get your subcases. Then this will work:
def walk(top,&block)
block.call(top)
subcases(top).each { |case| walk(case,&block) }
end
To print all subcases, you can do this:
walk("top"){|top| puts(top)}
Or, to upload them all:
walk("top"){|file| upload(file)}
It's really quite handy. (Note: you can use 'yield' to do the same thing as 'block.call', which means you don't have to include the '&block' bit.) However, in a case like this it's more efficient to keep passing the block. Here's the less efficient version:
def walk(top)
yield(top)
subcases(top).each do |case|
walk(case){|newtop|yield(newtop)
end
end
However, this is less efficient because each subcase is called through a whole chain of blocks.
|
By: Ruby Dos Zapatas
Help Ruby do good Ruby [ reply ] 2005-08-02 22:48
|
I know you girls and boys have been working at Ruby longer than I have. I just got tired of Python and came over here where the air is clearer. But some stuff I did in Python, I can't quite figure out in Ruby.
For starters, check out my walk method that I use in my code. I Python, I would make that a little more general because there I can pass, like, the upload or compress methods in as a parameter. How you do that in Ruby?
|
|
 |