Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > Scope problem (?) in implementing Design Patterns in Ruby

Reply
Thread Tools

Scope problem (?) in implementing Design Patterns in Ruby

 
 
RichardOnRails
Guest
Posts: n/a
 
      05-11-2011
Hi,

I'm hoping that employing "Design Patterns in Ruby" will lead to less
coding errors and more easily maintained code. I'm stuck with the Not
pattern in the File Finding pattern in Chapter 15.

I've posted my code and output in http://www.pastie.org/1889586 and
http://www.pastie.org/188968, respectively. Any idea about the cause
of the reported syntax error?

Thanks in Advance,
Richard
 
Reply With Quote
 
 
 
 
David Jacobs
Guest
Posts: n/a
 
      05-11-2011
[Note: parts of this message were removed to make it a legal post.]

I think the second link points to the wrong pastie.

I can see a couple of problems with the code, first of which is that you are
setting up Expression.new to require an argument but not passing it an
argument when you call All_basic.new, etc.

More than design patterns (which I think are a little much here), I would
suggest looking into Ruby's higher order functions like reduce and map. They
make your code a lot simpler. This is an alternate implementation I did. Let
me know what you think:

http://www.pastie.org/1889838

On Wed, May 11, 2011 at 1:20 PM, RichardOnRails <
http://www.velocityreviews.com/forums/(E-Mail Removed)> wrote:

> Hi,
>
> I'm hoping that employing "Design Patterns in Ruby" will lead to less
> coding errors and more easily maintained code. I'm stuck with the Not
> pattern in the File Finding pattern in Chapter 15.
>
> I've posted my code and output in http://www.pastie.org/1889586 and
> http://www.pastie.org/188968, respectively. Any idea about the cause
> of the reported syntax error?
>
> Thanks in Advance,
> Richard
>
>


 
Reply With Quote
 
 
 
 
David Jacobs
Guest
Posts: n/a
 
      05-11-2011
[Note: parts of this message were removed to make it a legal post.]

Correction: My bad, your version of All_basic doesn't inherit from
Expression like I thought it would from the pattern it follows.

On Wed, May 11, 2011 at 1:51 PM, David Jacobs <(E-Mail Removed)> wrote:

> I think the second link points to the wrong pastie.
>
> I can see a couple of problems with the code, first of which is that you
> are setting up Expression.new to require an argument but not passing it an
> argument when you call All_basic.new, etc.
>
> More than design patterns (which I think are a little much here), I would
> suggest looking into Ruby's higher order functions like reduce and map. They
> make your code a lot simpler. This is an alternate implementation I did. Let
> me know what you think:
>
> http://www.pastie.org/1889838
>
> On Wed, May 11, 2011 at 1:20 PM, RichardOnRails <
> (E-Mail Removed)> wrote:
>
>> Hi,
>>
>> I'm hoping that employing "Design Patterns in Ruby" will lead to less
>> coding errors and more easily maintained code. I'm stuck with the Not
>> pattern in the File Finding pattern in Chapter 15.
>>
>> I've posted my code and output in http://www.pastie.org/1889586 and
>> http://www.pastie.org/188968, respectively. Any idea about the cause
>> of the reported syntax error?
>>
>> Thanks in Advance,
>> Richard
>>
>>

>


 
Reply With Quote
 
David Jacobs
Guest
Posts: n/a
 
      05-11-2011
[Note: parts of this message were removed to make it a legal post.]

One more suggestion: if you're going to build a hierarchy, might as well
work the parent as much as possible. My final implementation would probably
look something like this:

http://www.pastie.org/1889969

On Wed, May 11, 2011 at 1:51 PM, David Jacobs <(E-Mail Removed)> wrote:

> I think the second link points to the wrong pastie.
>
> I can see a couple of problems with the code, first of which is that you
> are setting up Expression.new to require an argument but not passing it an
> argument when you call All_basic.new, etc.
>
> More than design patterns (which I think are a little much here), I would
> suggest looking into Ruby's higher order functions like reduce and map. They
> make your code a lot simpler. This is an alternate implementation I did. Let
> me know what you think:
>
> http://www.pastie.org/1889838
>
> On Wed, May 11, 2011 at 1:20 PM, RichardOnRails <
> (E-Mail Removed)> wrote:
>
>> Hi,
>>
>> I'm hoping that employing "Design Patterns in Ruby" will lead to less
>> coding errors and more easily maintained code. I'm stuck with the Not
>> pattern in the File Finding pattern in Chapter 15.
>>
>> I've posted my code and output in http://www.pastie.org/1889586 and
>> http://www.pastie.org/188968, respectively. Any idea about the cause
>> of the reported syntax error?
>>
>> Thanks in Advance,
>> Richard
>>
>>

>


 
Reply With Quote
 
7stud --
Guest
Posts: n/a
 
      05-11-2011
RichardOnRails wrote in post #998059:
>


1) Your case statement syntax doesn't work in ruby 1.9.2:

prog.rb:4: syntax error, unexpected ':', expecting keyword_then or ','
or ';' or '\n'

You have to use 'then' in place of a colon.

2) Next, I get this error:

prog.rb:67:in `evaluate': uninitialized constant Not::All (NameError)
from prog.rb:74:in `<main>'

which relates to this code:

class Not < Expression
def initialize(expression)
@expression = expression
end

def evaluate(dir)
all = All.new.evaluate(dir)
other = @expression.evaluate(dir)
all - other
end
end

In ruby, constants are looked up like directories and files. When you
are inside the Not class (which is a module), the 'directory' you are in
for constant lookups is the 'Not' directory. When you write All.new,
because the name All is not preceded by a directory name, ruby looks in
the current 'directory' for the constant All. The current directory is
Not, so ruby is looking for Not::All, i.e. the 'file' All in the
'directory' Not. However, All is not defined inside Not, so you get an
error. In fact, there is not constant named All defined anywhere in
your program.

--
Posted via http://www.ruby-forum.com/.

 
Reply With Quote
 
7stud --
Guest
Posts: n/a
 
      05-11-2011
7stud -- wrote in post #998081:
> RichardOnRails wrote in post #998059:
>>

>
> 1) Your case statement syntax doesn't work in ruby 1.9.2:
>
> prog.rb:4: syntax error, unexpected ':', expecting keyword_then or ','
> or ';' or '\n'
>
> You have to use 'then' in place of a colon.
>
> 2) Next, I get this error:
>
> prog.rb:67:in `evaluate': uninitialized constant Not::All (NameError)
> from prog.rb:74:in `<main>'
>
> which relates to this code:
>
> class Not < Expression
> def initialize(expression)
> @expression = expression
> end
>
> def evaluate(dir)
> all = All.new.evaluate(dir)
> other = @expression.evaluate(dir)
> all - other
> end
> end
>
> In ruby, constants are looked up like directories and files (or if you
> prefer constants are 'lexically scoped'). When you
> are inside the Not class (which is a module), the 'directory' you are in
> for constant lookups is the 'Not' directory. When you write All.new,
> because the name All is not preceded by a directory name, ruby looks in
> the current 'directory' for the constant All. The current directory is
> Not, so ruby is looking for Not::All, i.e. the 'file' All in the
> 'directory' Not. However, All is not defined inside Not, so you get an
> error. In fact, there is no constant named All defined anywhere in
> your program, so the error is more serious than a scope problem.
>
> If you are inside a class/module and you need to access a class at the
> top level, you do this:
>
> class All
> def greet
> puts 'hi'
> end
> end
>
>
> class Dog
> def do_stuff
> ::All.new.greet #<*****
> end
> end
>
> Dog.new.do_stuff #=>hi
>


In fact, that is unnecessary:

class All
def greet
puts 'hi'
end
end


class Dog
def do_stuff
All.new.greet #<*****
end
end

Dog.new.do_stuff #=>hi


I guess the lookup actually starts at the toplevel. So your error is a
result of not defining the constant All at the toplevel, and ruby
obfuscates the error by telling you that All is not defined inside the
Not module, giving you the error message: Not::All doesn't exist.

--
Posted via http://www.ruby-forum.com/.

 
Reply With Quote
 
David Jacobs
Guest
Posts: n/a
 
      05-11-2011
[Note: parts of this message were removed to make it a legal post.]

I think the lookup starts at the innermost scope but since All isn't defined
in Not, it reaches the top-level.

On Wed, May 11, 2011 at 4:23 PM, 7stud -- <(E-Mail Removed)> wrote:

> 7stud -- wrote in post #998081:
> > RichardOnRails wrote in post #998059:
> >>

> >
> > 1) Your case statement syntax doesn't work in ruby 1.9.2:
> >
> > prog.rb:4: syntax error, unexpected ':', expecting keyword_then or ','
> > or ';' or '\n'
> >
> > You have to use 'then' in place of a colon.
> >
> > 2) Next, I get this error:
> >
> > prog.rb:67:in `evaluate': uninitialized constant Not::All (NameError)
> > from prog.rb:74:in `<main>'
> >
> > which relates to this code:
> >
> > class Not < Expression
> > def initialize(expression)
> > @expression = expression
> > end
> >
> > def evaluate(dir)
> > all = All.new.evaluate(dir)
> > other = @expression.evaluate(dir)
> > all - other
> > end
> > end
> >
> > In ruby, constants are looked up like directories and files (or if you
> > prefer constants are 'lexically scoped'). When you
> > are inside the Not class (which is a module), the 'directory' you are in
> > for constant lookups is the 'Not' directory. When you write All.new,
> > because the name All is not preceded by a directory name, ruby looks in
> > the current 'directory' for the constant All. The current directory is
> > Not, so ruby is looking for Not::All, i.e. the 'file' All in the
> > 'directory' Not. However, All is not defined inside Not, so you get an
> > error. In fact, there is no constant named All defined anywhere in
> > your program, so the error is more serious than a scope problem.
> >
> > If you are inside a class/module and you need to access a class at the
> > top level, you do this:
> >
> > class All
> > def greet
> > puts 'hi'
> > end
> > end
> >
> >
> > class Dog
> > def do_stuff
> > ::All.new.greet #<*****
> > end
> > end
> >
> > Dog.new.do_stuff #=>hi
> >

>
> In fact, that is unnecessary:
>
> class All
> def greet
> puts 'hi'
> end
> end
>
>
> class Dog
> def do_stuff
> All.new.greet #<*****
> end
> end
>
> Dog.new.do_stuff #=>hi
>
>
> I guess the lookup actually starts at the toplevel. So your error is a
> result of not defining the constant All at the toplevel, and ruby
> obfuscates the error by telling you that All is not defined inside the
> Not module, giving you the error message: Not::All doesn't exist.
>
> --
> Posted via http://www.ruby-forum.com/.
>
>


 
Reply With Quote
 
7stud --
Guest
Posts: n/a
 
      05-11-2011
7stud -- wrote in post #998090:
>
> I guess the lookup actually starts at the toplevel.


Well, that's not true either. If I define two All classes: one at the
top level and one inside a module,

class All
def greet
puts 'All#greet'
end
end

module C
class All
def greet
puts "C::All#greet"
end
end

class Dog
def do_stuff
All.new.greet #<*****
end
end

end

C:og.new.do_stuff

--output:--
C::All#greet


Then if I delete C::All:

class All
def greet
puts 'All#greet'
end
end

module C
class Dog
def do_stuff
All.new.greet #<*****
end
end
end

C:og.new.do_stuff

--output:--
All#greet


...which doesn't seem like that should work.

--
Posted via http://www.ruby-forum.com/.

 
Reply With Quote
 
7stud --
Guest
Posts: n/a
 
      05-11-2011
David Jacobs wrote in post #998093:
> I think the lookup starts at the innermost scope but since All isn't
> defined
> in Not, it reaches the top-level.


Yes, you are right:

1)
===
Constants defined within a class or module may be accessed unadorned
anywhere within the class or module.

(Programming Ruby)
===

2)
===
Constants declared outside of a class or module are assigned global
scope.

(http://www.techotopia.com/index.php/...Constant_Scope)
===

So it's a case of the inner All hiding the global All. And you can use
the :: prefix to leap over an inner scope constant that hides a toplevel
constant:

class All
def greet
puts 'All#greet'
end
end

module C
class All
def greet
puts "C::All#greet"
end
end

class Dog
def do_stuff
::All.new.greet #<*****
end
end

end

C:og.new.do_stuff

--output:--
All#greet

--
Posted via http://www.ruby-forum.com/.

 
Reply With Quote
 
David Jacobs
Guest
Posts: n/a
 
      05-11-2011
[Note: parts of this message were removed to make it a legal post.]

>
> ...which doesn't seem like that should work.



Why not?

 
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


Similar Threads
Thread Thread Starter Forum Replies Last Post
Has anybody here read Design Patterns Explained: A New Perspective on Object-Oriented Design John Java 0 06-01-2007 02:45 PM
Return Codes in Perl: Question on implementing good patterns Matt_Pettis Perl Misc 2 04-27-2005 06:12 PM
Design Pattern Relationship Diagram - Design Patterns - Gang of Four Tim Smith C++ 2 12-15-2004 05:22 PM
where to find good patterns and sources of patterns (was Re: singletons) crichmon C++ 4 07-07-2004 10:02 PM
(German) Article about Design Patterns in Ruby online Markus Jais Ruby 0 08-12-2003 07:09 AM



Advertisments