|| explanation in ruby... in pseudolanguage

T

Tuka Opaleye

Hi,

I am trying to get my head around the || symbol used extensively in
ruby. To me it is somewhat foreign still and I am trying a few exercise
to make it click. Can anyone suggest a phrase (pseudolanguage) that
accurately expresses the possible expressions using || ?

For example, see the comments and please correct me if I am wrong. Could
you add other cases that I may not have caught here ?

input.each_byte do |b|
case b
when ?\C-c; puts 'Control-C: stopped a process?'
when ?\C-z; puts 'Control-Z: suspended a process?'
when ?\n; puts 'Newline.'
when ?\M-x; puts 'Meta-x: using Emacs?'
end
for each byte in input, assign it to b...



Ex 2:
open('smiley.html', 'wb') do |f|
f << '<meta http-equiv="Content-Type"
content="text/html;charset=UTF-8">'
f << "\xe2\x98\xBA"
end

Sugestions ?.....


Ex 3:
octal = "\000\001\010\020"
octal.each_byte { |x| puts x }
for each byte in octal, assign an x...

TIA,
Tuka
 
T

Timothy Hunter

Tuka said:
Hi,

I am trying to get my head around the || symbol used extensively in
ruby. To me it is somewhat foreign still and I am trying a few exercise
to make it click. Can anyone suggest a phrase (pseudolanguage) that
accurately expresses the possible expressions using || ?

For example, see the comments and please correct me if I am wrong. Could
you add other cases that I may not have caught here ?

input.each_byte do |b|
case b
when ?\C-c; puts 'Control-C: stopped a process?'
when ?\C-z; puts 'Control-Z: suspended a process?'
when ?\n; puts 'Newline.'
when ?\M-x; puts 'Meta-x: using Emacs?'
end
for each byte in input, assign it to b...



Ex 2:
open('smiley.html', 'wb') do |f|
f << '<meta http-equiv="Content-Type"
content="text/html;charset=UTF-8">'
f << "\xe2\x98\xBA"
end

Sugestions ?.....


Ex 3:
octal = "\000\001\010\020"
octal.each_byte { |x| puts x }
for each byte in octal, assign an x...

TIA,
Tuka
In these examples the || delimit the argument list to the block, similar
to the way parentheses delimit the argument list in a method definition.
When the method yields to the block it passes some value or values from
the method to the block:

yield(arg1, arg2, arg3)

and these values become the block arguments:

obj.meth { |a, b, c| ....}

In the above case arg1 is the 'a' argument, 'arg2' is the 'b' argument,
and 'arg3' is the 'c' argument. A method may yield multiple times,
passing a new set of arguments each time, as each_byte does in examples
1 and 3, or it may yield only once, as in example 2.
 
D

Dave Burt

Tuka said:
I am trying to get my head around the || symbol used extensively in
ruby. To me it is somewhat foreign still and I am trying a few exercise
to make it click. Can anyone suggest a phrase (pseudolanguage) that
accurately expresses the possible expressions using || ?

input.each_byte do |b|
case b
...
end
for each byte in input, assign it to b...

You're right, assignment is correct. Imagine a special variable
yielded_values; the block could be expressed like this:

do
b = *yielded_values
case b
...
end
end

Implicit in this is that you can use full assignment semantics, as in
this idiom:

my_hash.inject(initial_value) do |memo, (key, value)|
...
end

It works this way: inject yields a [memo, whatever_each_yields] pair,
and Hash#each yields a [key, value] pair. This is the analogous assignment:

yielded_values = [:memo, [:key, :value]]
memo, (key, value) = *yielded_values

How would you say this in English? Inject is problematic this way; I
don't understand how to explain it naturally using the word "inject" at
all. But perhaps you could use a general form such as "call inject with
the parameter initial_value and a block taking parameters memo, key and
value."
Ex 2:
open('smiley.html', 'wb') do |f|
f << ...
end

Sugestions ?.....

*With* an open binary-write mode file handle to "smiley.html" *as* f...

What a block means depends on the method. You've looked at iteration and
scope-of-an-opened-object examples, which are probably the most common,
but there are others (e.g. Markaby).

Cheers,
Dave
 
T

Tuka Opaleye

Thanks for the input guys. This really helps.

Sorry about the confusion with OR, I forgot that || actually means OR in
most languages.

I have heard |var| called goal-post notation (I think it was in a ROR
podcast...) - is that what you call it ? I owuld guess another valid
name is something with the word "pipes".

Cheers,
Tuka


Dave said:
Tuka said:
I am trying to get my head around the || symbol used extensively in
ruby. To me it is somewhat foreign still and I am trying a few exercise
to make it click. Can anyone suggest a phrase (pseudolanguage) that
accurately expresses the possible expressions using || ?

input.each_byte do |b|
case b
...
end
for each byte in input, assign it to b...

You're right, assignment is correct. Imagine a special variable
yielded_values; the block could be expressed like this:

do
b = *yielded_values
case b
...
end
end

Implicit in this is that you can use full assignment semantics, as in
this idiom:

my_hash.inject(initial_value) do |memo, (key, value)|
...
end

It works this way: inject yields a [memo, whatever_each_yields] pair,
and Hash#each yields a [key, value] pair. This is the analogous
assignment:

yielded_values = [:memo, [:key, :value]]
memo, (key, value) = *yielded_values

How would you say this in English? Inject is problematic this way; I
don't understand how to explain it naturally using the word "inject" at
all. But perhaps you could use a general form such as "call inject with
the parameter initial_value and a block taking parameters memo, key and
value."
Ex 2:
open('smiley.html', 'wb') do |f|
f << ...
end

Sugestions ?.....

*With* an open binary-write mode file handle to "smiley.html" *as* f...

What a block means depends on the method. You've looked at iteration and
scope-of-an-opened-object examples, which are probably the most common,
but there are others (e.g. Markaby).

Cheers,
Dave
 
D

Dave Burt

Tuka said:
Thanks for the input guys. This really helps.

You're welcome. Glad to be of service.
Sorry about the confusion with OR, I forgot that || actually means OR in
most languages.

This one, too. "var ||= default" is a common Ruby idiom.
I have heard |var| called goal-post notation (I think it was in a ROR
podcast...) - is that what you call it ? I owuld guess another valid
name is something with the word "pipes".

I haven't referred to them as goal-posts personally, but it's used
around the traps.

I'd just call them "block arguments" or "block parameters."

Why and his cat Trady Blix call the pipes surrounding the argument list
a chute. See the subheading Blocks in Why's (Poignant) Guide to Ruby,
Ch. 4, Sec. 4:

http://www.poignantguide.net/ruby/chapter-4.html#section4

Cheers,
Dave
 
M

Max Muermann

You're welcome. Glad to be of service.

Sorry about not understanding your question right...

Anyway, if it helps, I tend to think of the |var| notation as "with", e.g.

some_list.each do |item| ... end

becomes (at least in my head) some_list each do with item ...

Cheers,
Max
 
T

Tom Armitage

Anyway, if it helps, I tend to think of the |var| notation as "with", e.g.
some_list.each do |item| ... end

becomes (at least in my head) some_list each do with item ...

Interesting - I tend to think of it as "as", which doesn't
transliterate as well, but indicates that the object inside the pipes
is temporary; it's just a name we're giving the iterated objects.
 
D

dblack

Hi --

Interesting - I tend to think of it as "as", which doesn't
transliterate as well, but indicates that the object inside the pipes
is temporary; it's just a name we're giving the iterated objects.

Possibly...

item = 1
[2,3,4].each do |item| end
p item # 4


David

--
David A. Black | (e-mail address removed)
Author of "Ruby for Rails" [1] | Ruby/Rails training & consultancy [3]
DABlog (DAB's Weblog) [2] | Co-director, Ruby Central, Inc. [4]
[1] http://www.manning.com/black | [3] http://www.rubypowerandlight.com
[2] http://dablog.rubypal.com | [4] http://www.rubycentral.org
 
Y

Yukihiro Matsumoto

Hi,

In message "Re: || explanation in ruby... in pseudolanguage"
on Tue, 10 Oct 2006 18:15:22 +0900, (e-mail address removed) writes:

|Possibly...
|
| item = 1
| [2,3,4].each do |item| end
| p item # 4

Not in 1.9, where block parameters are local to the block, since
recent change.

matz.
 
A

ara.t.howard

Hi,

In message "Re: || explanation in ruby... in pseudolanguage"
on Tue, 10 Oct 2006 18:15:22 +0900, (e-mail address removed) writes:

|Possibly...
|
| item = 1
| [2,3,4].each do |item| end
| p item # 4

Not in 1.9, where block parameters are local to the block, since
recent change.

i know this has been discussed many times, and block locals definitely makes
sense, but it __is__ a massive change that will break quite a bit of code.
is there somewhere the new scoping rules are spelled out so we can get a heads
up? is there a reccomended approach that will work in both 1.8 and 1.9 so as
to smooth the transition?

regards.

-a
 
Y

Yukihiro Matsumoto

Hi,

In message "Re: || explanation in ruby... in pseudolanguage"
on Tue, 10 Oct 2006 23:16:53 +0900, (e-mail address removed) writes:

|i know this has been discussed many times, and block locals definitely makes
|sense, but it __is__ a massive change that will break quite a bit of code.

Yes.

|is there somewhere the new scoping rules are spelled out so we can get a heads
|up?

Not yet. I am stuck with the idea named local variable propagation,
which upgrades variable scope if it is used outside of the scope (and
within a method), i.e.

def foo
4.times do
a = gets
end
p a # accessing a upgrades its scope.
end

But block parameters and explicitly declared block local variables are
not subject of this upgrading.

|is there a reccomended approach that will work in both 1.8 and 1.9 so as
|to smooth the transition?

Consider block parameters are block local even when you're using 1.8.
It's a good thing in general, I think.

matz.
 
A

ara.t.howard

|is there somewhere the new scoping rules are spelled out so we can get a heads
|up?

Not yet. I am stuck with the idea named local variable propagation, which
upgrades variable scope if it is used outside of the scope (and within a
method), i.e.

def foo
4.times do
a = gets
end
p a # accessing a upgrades its scope.
end

But block parameters and explicitly declared block local variables are not
subject of this upgrading.


hmmm. it's kinda like 'scope coercion'. seems kinda slippery - like

' "1" + 41 '

in perl...

plus it gets tricky when one meant to go 'up' a scope, but it went 'down' one
instead:

i = 42

# 1000 lines of code

n.times do |i|
m.times do |i|
end
end

p i # goes down or up depending on 'i = 42' line way above...


on the otherhand, if all vars in block are local it's tough to get one out!



would a block local var be declared using something like

local x

??

or are all block vars simply local by default?



how about an explicit scope upgrade:

4.times{ export a = gets }

??


another thing which springs to mind is an objectified stack - it could solve
this problem too, working similarly for stack and scope:

stack:

def foo()
context = callstack.first # list of objectified stack objects
context['a'] = 42 # set local var 'a' in binding of caller
end

scope:

def foo()
4.times do
context = scope.first # list of objectified scope objects
context['a'] = 42 # set local var 'a' in first outer scope
end
end

not too mention skinning a bunch of other cats too...

just throwing things out there... the problem of callstack, scope, and
manipulating them in general (setting vars being one instance) seem related,
but i'm no language designer...

|is there a reccomended approach that will work in both 1.8 and 1.9 so as
|to smooth the transition?

Consider block parameters are block local even when you're using 1.8.
It's a good thing in general, I think.

but, if we also consider block locals as, well, local, what's the prefered
method for getting them 'out'? for example,

which = nil
container.each{|elem| break(which = elem) if predicate[elem]}

are there two 'which' vars here (local and top-level)? or will 'which' still
successfully be exported?


kind regards.

-a
 
K

Keith Fahlgren

This seems like a no-brainer to me (it hadn't even occurred to me that
they might not be local), because I always image block vars in a
Scheme-y way, where variable scope is very strictly defined:
container.each{(lambda (elem) ... )}
# no elem out here at all

But Ara raises a good point about the best way to export variables from blocks:

but, if we also consider block locals as, well, local, what's the prefered
method for getting them 'out'? for example,

which = nil
container.each{|elem| break(which = elem) if predicate[elem]}

are there two 'which' vars here (local and top-level)? or will 'which' still
successfully be exported?

Pre-defining a variable is always the way I go, tho it feels a little
ugly, just to make the scope explicit. So, I'd imagine that by
pre-defining which, you're allowed to get elem out by assignment, just
as you have.

That said, I'm no language designer, and perhaps I'm totally wrong.


Keith
 
Y

Yukihiro Matsumoto

Hi,

In message "Re: || explanation in ruby... in pseudolanguage"
on Wed, 11 Oct 2006 00:09:57 +0900, (e-mail address removed) writes:

|hmmm. it's kinda like 'scope coercion'. seems kinda slippery - like
|
| ' "1" + 41 '
|
|in perl...

I think I get the analogy here.

|plus it gets tricky when one meant to go 'up' a scope, but it went 'down' one
|instead:
|
| i = 42
|
| # 1000 lines of code
|
| n.times do |i|
| m.times do |i|
| end
| end
|
| p i # goes down or up depending on 'i = 42' line way above...
|
|on the otherhand, if all vars in block are local it's tough to get one out!

Yes, this is a problem.

|would a block local var be declared using something like
|
| local x
|
|??

No, it's like

n.times do |i; j,k| # j and k only available within the block
...
end

|another thing which springs to mind is an objectified stack - it could solve
|this problem too, working similarly for stack and scope:
|
|stack:
|
| def foo()
| context = callstack.first # list of objectified stack objects
| context['a'] = 42 # set local var 'a' in binding of caller
| end
|
|scope:
|
| def foo()
| 4.times do
| context = scope.first # list of objectified scope objects
| context['a'] = 42 # set local var 'a' in first outer scope
| end
| end
|
|not too mention skinning a bunch of other cats too...

Interesting idea, but it seems to hinder the performance very
severely. There may be a good trick to accomplish performance with
this feature.

|> Consider block parameters are block local even when you're using 1.8.
|> It's a good thing in general, I think.
|
|but, if we also consider block locals as, well, local, what's the prefered
|method for getting them 'out'? for example,
|
| which = nil
| container.each{|elem| break(which = elem) if predicate[elem]}
|
|are there two 'which' vars here (local and top-level)? or will 'which' still
|successfully be exported?

The latter. There's no "which" in the block parameters, nor explicit
block local variables. If you'd like to omit previous assignment
(it's bit ugly), and still want to access "which" after the block, you
need the local variable propagation, that I tried to explain here.

matz.
 
J

Joel VanderWerf

Robert Dober wrote:
...
This discussion almost reminds me of Single vs. Multiple Inheritance.
I feel making all variables scope local and having to revert to instance
variables
for global scope might be a good compromise, for me at least ;)

Instance vars complicate threaded code.
 

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,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top