.each do |foo, bar| what does bar do?
11 Message(s) by 6 Author(s) originally posted in ruby programming
| From: Thufir |
Date: Wednesday, October 24, 2007
|
"
code _words.each do |
real , code|
idea.gsub!( real, code )
end
You see the each
method ? The each method is all over in
Ruby . It's
available for Arrays, Hashes, even Strings. Here, our code_words
dictionary is kept in a Hash. This each method will hurry through all
the pairs of the Hash, one dangerous word matched with its code word,
handing each pair to the gsub! method for the actual replacement."
from page 33 of whys-poignant-guide-to-ruby.pdf
Is this similar to nested for statements? I do not think so. In the
first line, why are both "real" and "code" part of the interation?
From my understanding of a hash , you can iterate through the key s only
and then find the corresponding
bit of the hash.
Why'd this fail:
code_words.each do |real|
idea.gsub!( real, code )
end
would not the corresponding code get looked up by during the
loop ? Or,
how could the above be changed so that it'd work?
thanks,
Thufir
| From: David A. Black |
Date: Wednesday, October 24, 2007
|
Hi --
wrote in message:
"code_words.each do |real, code|
idea.gsub!( real, code )
end
You see the each method? The each method is all over in Ruby. It's
available for Arrays, Hashes, even Strings. Here, our code_words
dictionary is kept in a Hash. This each method will hurry through all
the pairs of the Hash, one dangerous word matched with its code word,
handing each pair to the gsub! method for the actual replacement."
from page 33 of whys-poignant-guide-to-ruby.pdf
Is this similar to nested for statements? I do not think so. In the
first line, why are both "real" and "code" part of the interation?
From my understanding of a hash, you can iterate through the keys only
and then find the corresponding bit of the hash.
Why'd this fail:
code_words.each do |real|
idea.gsub!( real, code )
end
would not the corresponding code get looked up by during the loop? Or,
how could the above be changed so that it'd work?
Hashes yield key,value pairs to #each. So you need two
block params to
pick them up.
If you just want the keys, you can use #each_key.David
--
Upcoming training by David A. Black/Ruby Power and Light, LLC:
* Advancing With Rails, Edison, NJ, November 6-9
* Advancing With Rails, Berlin, Germany, November 19-22
* Intro to Rails, London, UK, December 3-6 (by Skills Matter)
See
http://www.rubypal.com for details!
| From: Ben Giddings |
Date: Wednesday, October 24, 2007
|
wrote in message:
"code_words.each do |real, code|
idea.gsub!( real, code )
end
You see the each method? The each method is all over in Ruby. It's
available for Arrays, Hashes, even Strings. Here, our code_words
dictionary is kept in a Hash. This each method will hurry through all
the pairs of the Hash, one dangerous word matched with its code word,
handing each pair to the gsub! method for the actual replacement."
from page 33 of whys-poignant-guide-to-ruby.pdf
Is this similar to nested for statements? I do not think so. In the
first line, why are both "real" and "code" part of the interation?
>From my understanding of a hash, you can iterate through the keys only
and then find the corresponding bit of the hash.
Why'd this fail:
code_words.each do |real|
idea.gsub!( real, code )
end
What's happening in the first
version of the code is that "real" and
"code" are being assigned from within the "each" method. At some
point within each there's some code that essentially looks like:
"yield(current_hash_key, current_hash_value)". When that code is run,
ruby assigns the
variable (in your scope) real to the value of
"current_hash_key" within the "each" method, and it assigns the
variable "code" to the value of "current_hash_value".
Because "yield" has two arguments, the block you pass each should've
two
parameter s, which it does. If you used this instead:
code_words.each do |foo|
...
end
Foo'd be assigned an
array containing both things sent by "yield",
i.e. foo[0]'d be the same as real, and foo[1]'d be the same as
code.
The key thing here is that not every "each" is the same. Some have a
"yield" that tries to send out one value (like the "each" for arrays),
some pass multiple values (like the "each" for hashes). You need to
know how many variables your "each" wants to assign in a block.
In your example:
code_words.each do |real|
idea.gsub!( real, code )
end
real'd get assigned, but "code" would not have been assigned, so
Ruby would not know what "code" was and'd complain.
Ben
| From: 7stud -- |
Date: Wednesday, October 24, 2007
|
wrote in message:
From my understanding of a hash, you can iterate through the keys only
and then find the corresponding bit of the hash.
Your understanding is incorrect.
in the
first line, why are both "real" and "code" part of the interation?
Ok, let's get some preliminaries straight:
arr = [1, 2]
a, b = arr
puts a,b
--
output :--
1
2
That's a form of what's called 'parallel
assignment ' in ruby.
The each() method for a hash sends an array consisting of a key/value
pair to a block:
h = {"a"=>1, "b"=>2}
h.each do |arr|
p arr
end
--output:--
["a", 1]
["b", 2]The output shows that each() *assigns* an array to the parameter
variable 'arr'. Earlier it was established that parallel assignment can
be used with arrays. So that loop can also be written like this:
h = {"a"=>1, "b"=>2}
h.each do |key, val|
print key, val
puts
end --output:--
a1
b2
As you can see from the output, ruby is perfectly happy to do parallel
assignment when passing that array to the block.> Why'd this fail:
code_words.each do |real|
idea.gsub!( real, code )
end
For the same reason the following
program will fail:
puts code>
would not the corresponding code get looked up by during the loop?
How? In the first instance, you say that it's your understanding that
when examining a hash with each(), each() will only produce the keys,
but then you ask why 'code', which is a value, is not looked up during
the loop. So, what exactly is your understanding?
how could the above be changed so that it'd work?
code_words.each do |arr|
idea.gsub!( arr[0], arr[1] )
end
--
Posted via
http://www.ruby-forum.com/.
| From: 7stud -- |
Date: Wednesday, October 24, 2007
|
wrote in message:
As you can see from the output, ruby is perfectly happy to do parallel
assignment when passing that array to the block.
That should say:
As you can see from the output, ruby is perfectly happy to do parallel
assignment when passing an array to a block.
--
Posted via
http://www.ruby-forum.com/.
| From: Randy Kramer |
Date: Saturday, October 27, 2007
|
wrote in message:
I just can not wrap my mind around *what's* being iterated through. I
guess it's the way that, as you put it, the "yield(current_hash_key,
current_hash_value)" is happening behind the scenes.
Well, let's look at an example hash:
{ "key1"=>"value1", "key2"=>"value2", "cow"=>"bovine", 12=>"dodecine" }
A hash (
literal ) is "a
list of key => value pairs between braces" (from
pickaxe2).
When you iterate through the hash, you are iterating through the key=>value
*pairs*--on the first
iteration you get the values "key1"=>"value1", on the
2nd iteration you get "key2"=>"value2", and so on. Note that you get *two*
values.
Randy Kramer
| From: 7stud -- |
Date: Saturday, October 27, 2007
|
wrote in message:
If you were going to write Hash#each in Ruby, without recourse to
#each, you could write it like this:
class Hash
def each
keys = self.keys # make a 'keys' local variable
I = 0
until I == keys.size
key = keys[i]
yield(key, self[key])
I += 1
end
self
end
end
David
A test run:
h = {"a"=>1, "b"=>2}
h.each do |arr|
p arr
end
--output:--
r5test.rb:2: warning: method redefined; discarding old each
r5test.rb:15: warning: multiple values for a block parameter (2 for 1)
from r5test.rb:7
["a", 1]
r5test.rb:15: warning: multiple values for a block parameter (2 for 1)
from r5test.rb:7
wrote in message:
The each() method for a hash sends an array consisting of a key/value
pair to a block:
h = {"a"=>1, "b"=>2}
h.each do |arr|
p arr
end
--output:--
["a", 1]
["b", 2]
The output shows that each() *assigns* an array to the parameter
variable 'arr'.
--
Posted via
http://www.ruby-forum.com/.
| From: Brian Adkins |
Date: Saturday, October 27, 2007
|
wrote in message:
If you were going to write Hash#each in Ruby, without recourse to
#each, you could write it like this:
class Hash
def each
keys = self.keys # make a 'keys' local variable
I = 0
until I == keys.size
key = keys[i]
yield(key, self[key])
I += 1
end
self
end
end
Or this:
class Hash
def each
each_key {|key| yield key, self[key] }
end
end
I know, you meant w/o recourse to each* :)
| From: David A. Black |
Date: Saturday, October 27, 2007
|
Hi --
wrote in message:
wrote in message:
If you were going to write Hash#each in Ruby, without recourse to
#each, you could write it like this:
class Hash
def each
keys = self.keys # make a 'keys' local variable
I = 0
until I == keys.size
key = keys[i]
yield(key, self[key])
I += 1
end
self
end
end
Or this:
class Hash
def each
each_key {|key| yield key, self[key] }
end
end
I know, you meant w/o recourse to each* :)
Yes -- I do not think each_key uses each but it's definitely out of
bounds for my example :-) Mainly, of course, I wanted to "explode" the
whole thing so that the underlying
logic was brought to the surface.David
--
Upcoming training by David A. Black/Ruby Power and Light, LLC:
* Advancing With Rails, Edison, NJ, November 6-9
* Advancing With Rails, Berlin, Germany, November 19-22
* Intro to Rails, London, UK, December 3-6 (by Skills Matter)
See
http://www.rubypal.com for details!
| From: 7stud -- |
Date: Saturday, October 27, 2007
|
wrote in message:
wrote in message:
I += 1
end
self
end
end
Or this:
class Hash
def each
each_key {|key| yield key, self[key] }
end
end
That suffers the same problem as David Black's example.> I know, you meant w/o recourse to each* :)
My tests show that each_keys() doesn't call Hash#each(), so your
example seems to use fair means to me:
class Hash
alias :orig_each :each
def each(&block)
orig_each(&block)
puts "orig each called"
end
def my_method
each_key {|key| yield key, self[key] }
end
end
h = {"a"=>1, "b"=>2}
#call original each() method for a hash:
h.each do |key, val|
print key, " ", val
puts
end
puts
#call a method that uses each_key():
h.my_method do |key, val|
print key, " ", val
puts
end--output:--
a 1
b 2
orig each called
a 1
b 2
Note that in the last output Hash#each() was not called.
That example has raised a question of my own. Instead of having to
write:
def each(&block)
orig_each(&block)
why can not I relay the block to orig_each() without the second '&', like
this
def each(&block)
orig_each(block)
According to pickaxe2, p56, the '&' method converts the specified block
to a Proc
object and assigns it to the parameter variable 'block'. Why
is the second call to '&' required?
--
Posted via
http://www.ruby-forum.com/.
| From: Brian Adkins |
Date: Saturday, October 27, 2007
|
wrote in message:
...
That suffers the same problem as David Black's example.
...
My tests show that each_keys() doesn't call Hash#each(), so your
example seems to use fair means to me:
You're a literal
type of person, are not you? :)
Next Message: windows-api-0.2.0/lib/windows/api.rb:211: [BUG] Segmentation fault
Blogs related to .each do |foo, bar| what does bar do?
25 new messages in 12 topics - digest
bar _foo baz. What is
foo? a directory? And
bar/_foo/baz, source files in C?
Each one defining a module object, or is there a single module -
foo perhaps? > _foo basically
does some init stuff, nothing much. Thats where the
...
25 new messages in 16 topics - digest
irb(main):014:0> def f1(x) x.
each {|y| py}; py end => nil irb(main):015:0> def f2(x) for y in x; py; end; py end => nil irb(main):016:0> f1 %w{
foo bar baz} "
foo" "
bar" "baz" NameError: undefined local variable or method `y' for main:
...
25 new messages in 15 topics - digest
mod.instance_methods.
each do |meth| undef_method(meth) end end def use_module(mod,&blk) include mod if block_given? blk.call uninclude(mod) end end end. module
Foo def to_foo '
foo' end end. module
Bar def to_bar '
bar'
...
25 new messages in 14 topics - digest
the String methods and did not see a way to
do this. Thanks. > > I think the OP was looking for a method on String itself, but the > whole point of
Ruby is that if the language doesn't have the features
...
25 new messages in 9 topics - digest
require 'benchmark'. REP = 500_000.
Foo = Struct.new :
foo, :
bar. data = "
foo" c1 =
Foo.new data, data c2 = [data, data]. Benchmark.bmbm 15
do |x| x.report 'struct init'
do REP.times {
Foo.new data, data } end. x.report 'array init'
do ...
Fix That Tranny (with a to_ascii method)
The RSpec specification
does a good job of conveying the behavior of
each variation. require File.dirname(__FILE__) + '/../../spec_helper' require 'benchmark' describe String, "to_url_format"
do it "should only include alphanumerics"
do ...