subject: Re: Need help with Python scoping rules

text:
On Thursday 27 August 2009 11:14:41 Steven D'Aprano wrote:

It was intended to help the OP out of the mental hole he finds himself in.

Most of the classes I use fall directly into such a classification - they are
useless until an instance is created.  And I would be so bold as to say that
_all_  gui classes are like that.

This is the pattern I am talking about:

class thing(object):
    def __init__(self,foo,bar):
        stuff to do things with foo and bar,
        creating or modifying attributes of
        the instance.

    def somemethod(self,baz,bling):
        instance method to do further operations on
        the attributes of the instance

Now kindly explain to me how a class like that is usefull before an instance
of it is created, and I might agree with you that what I said is "totally
incorrect"

8< --trivial examples showing that there is something there ------------

*nods* yes this would make sense - but it is not quite what either the OP or I
was on about.

nice.  now try doing it with object:

thing = object()

After that, thing will exist, but it is a bit like write only memory -
completely useless, until you have done some more work with it.

The yes was in there to make the man feel a bit better, and because from where
he stood, it _was_ the recursion that did him in.   : - )

Right -  I can see that you are reading that to mean that there must be an
instance.  That is not what I intended to bring across.  I was talking about
the lack of a reference that is his original problem, which he only
encountered with recursion.

two points:

Of what earthly use is a bare class like that - except possibly as a container
for all the good stuff those functions produced out of nothing?   - You might
as well use a list, or better a dict, to keep the results of such functions,
unless the functions are procedures, doing things by side effect - and if
that is the case, why bother putting them in a class?

Secondly:

Now what you have done is carefully avoided the OP's original problem, which
arises when the function in the class is called, and tries to call itself at
the time of execution of the class suite, and fails, for the reasons so
nicely explained by a lot of people.  So the OP had a point when he
complained that python does not like recursion, because, until he understands
what is happening, the simplest theory that fits his observed facts is that
the failure is caused by the recursion. - a completely rational conclusion
based on Occam's razor.   It just happens to be wrong in this case.  This was
the source for my "Yes" above.

This should also work for the OP - I cannot recall if it has been shown:

class Demo(object):
    def fact(x,f):
        if x < 2:
            return 1
        else:
            return x*f(x-1,f)

    thing = fact(42,fact)

I still think it is stupid, though - thing should simply be set to
1405006117752879898543142606244511569936384000000000L
and that would be the end of it for this use case, without the bother of a
function and the concomitant waste of time.

- Hendrik


author: Hendrik van Rooyen

subject: Re: Need help with Python scoping rules

text:
On Thursday 27 August 2009 11:31:41 Steven D'Aprano wrote:

8< ---------- Complicated Table Example -------------------------------

Me?  - never!  I am just an assembler programmer.  I would not touch a thing
like that with a barge pole.  Unless of course, I have to.

It is a hell of a thing if it needs recursion to calculate - If it was really
that complex, I would calculate it, check it (if I can), document it and put
it in a module of its own, with "This side up", "Fragile", and other warning
stickers all over it.

- Hendrik


author: Jan Kaliszewski

subject: Re: Need help with Python scoping rules

text:
14:17:15 Steven D'Aprano <[email]> wrote:

s/from inside nested functions/from inside nested scopes

Besides that detail, I fully agree.

*j


author: Miles Kaufmann

subject: Re: Need help with Python scoping rules

text:
On Aug 26, 2009, at 1:11 PM, kj wrote:

Guido's design justifications:
http://mail.python.org/pipermail/python-dev/2000-November/010598.html


subject: Re: Need help with Python scoping rules

text:
On Aug 27, 2009, at 4:49 PM, kj wrote:

I just checked the python-dev archives around the time that PEP 227
was written.

You're right, of course.  If I had been thinking properly, I would
have posted this:

... the suite namespace and the class namespace would get out of sync
when different objects were assigned to the class namespace:

    # In a hypothetical Python with nested class suite scoping:
    class C:
        x = 1
        @classmethod
        def foo(cls):
            print x
            print cls.x

    1
    1
    1
    2

With your example, the result is at least easily explainable: self.x
is originally 1 because the object namespace inherits from the class
namespace, but running 'o.x = 2' rebinds 'x' in the object namespace
(without affecting the class namespace).  It's a distinction that
sometimes trips up newbies (and me, apparently ;) ), but it's
straightforward to comprehend once explained.  But the distinction
between the class suite namespace and the class namespace is far more
subtle; extending the lifetime of the first so that it still exists
after the second is created is, IMO, asking for trouble (and trying to
unify the two double so).

-Miles


author: kj

subject: Re: Need help with Python scoping rules

text:
In <[email]> "Diez B. Roggisch" <[email]> writes:

This looks to me like a major wart, on two counts.

First, one of the goals of OO is encapsulation, not only at the
level of instances, but also at the level of classes.  Your comment
suggests that Python does not fully support class-level encapsulation.

Second, my example shows that Python puts some peculiar restrictions
on recursion.  Recursion!  One of the central concepts in the theory
of functions!  This is shown most clearly by the following elaboration
of my original example:

class Demo(object):
    def fact_rec(n):
        if n < 2:
            return 1
        else:
            return n * fact_rec(n - 1)

    def fact_iter(n):
        ret = 1
        for i in range(1, n + 1):
            ret *= i
        return ret

    classvar1 = fact_iter(5)
    classvar2 = fact_rec(5)

This code won't compile as shown, but it does compile if the last
line (the call to the recursive fact_rec) is commented out.  There
is no justification for discriminating against recursive functions
in this context.  Recursive functions should be OK wherever functions
are OK.  I can't think of any other language that allows recursion
but not anywhere.

Is there any good reason (from the point of view of Python's overall
design) for not fixing this?

kynn


author: Carl Banks

subject: Re: Need help with Python scoping rules

text:
On Aug 26, 3:57 am, kj <[email]> wrote:

Class statements *are* scopes, they are just not accessible from
scopes nested within them.

I can't answer this, I don't even know what you are talking about.
The OO notion of encapsulation that I'm familar means that an object
can seal off access to private data.  This has nothing to do with
class statement scoping.

Inside class statements are not the place for this kind of thing.
Define functions like fact_rec outside the class statement.

I suspect that no reason, however profound, would satisfy you.
Therefore I will merely answer your question without fanfare, and you
can take it as you will.

1. One of the key aspects of Python's design is that attributes must
be accessed explicitly with dot notation.  Accessing class scopes from
nested functions would (seemingly) allow access to class attributes
without the dotted notation.  Therefore it is not allowed.

2. This is considered more important that your ability to define
recursive functions in the class statement.

Carl Banks


subject: Re: Need help with Python scoping rules

text:
On Aug 26, 7:09 am, kj <[email]> wrote:

Nope, you're wrong.  Class variables are accessible wherever a class
exists.  The apparent silliness of this is because you are confusing
classes with class statements.

You know that the class isn't created until the class statement exits,
don't you?

Yeah, it's a little surprising that you can't access class scope from
a function, but that has nothing to do with encapsulation.

Your solution to this "problem" is to add a keyword to Python.
Laughable.  (BTW, it's not trivial.)

Carl Banks


author: Dave Angel

subject: Re: Need help with Python scoping rules

text:
kj wrote:
Why not fix the call?  The correct way to call a method is with either
the class name or an instance object, depending on whether it's a
instance method or not.  By default, a method is unbound, and its first
argument is by convention called self.  If you want to recurse, then add
self in the appropriate places.

As you have it, neither of the methods can be called outside the class:

class Demo(object):
    def fact_rec(n):
        if n < 2:
            return 1
        else:
            return n * fact_rec(n - 1)
     ....

obj = Demo()
print obj.fact_rec(5)

gives error:

Traceback (most recent call last):
  File "M:\Programming\Python\sources\dummy\stuff2.py", line 20, in <module>
    print obj.fact_rec(5)
TypeError: fact_rec() takes exactly 1 argument (2 given)

To fix it, you need to either change the signature (add in 'self'
argument before the n argument) or do some form of decorator to the
function.  If I assume you never intended this method to use 'self'
(ie. it's a static method), then declare it so.  And call it accordingly.

class Demo(object):
    @staticmethod
    def fact(n):
        if n < 2:
            return 1
        else:
            return n * Demo.fact(n - 1)

print Demo.fact(6)

On the other hand, if I assume you're just giving a simple example of
what's really intended to be a normal method (called with an instance,
that it uses), then you'd change it this way.

class Demo2(object):
    def fact(self, n):
        if n<2:
            return 1
        else:
            return n * self.fact(n-1)

obj = Demo2()
print obj.fact(5)

Now the only real restriction, as opposed to all these red-herrings, is
that the class may not be used before it's complete.  That only comes to
play when class attributes (non-instance "variables") are defined in
terms of class methods.  So if you have such attributes to define, move
them outside of the class, perhaps immediately after it.

class Demo(object):
    @staticmethod
    def fact(n):
        if n < 2:
            return 1
        else:
            return n * Demo.fact(n - 1)
Demo._classvar = Demo.fact(5)

Sure it will compile.  It just won't run.  You get the error after
compiling the function when *calling* it from the classvar* line.  But
at that time the class is not defined, and not everything is ready for use.

You can probably work around this by replacing the staticmethod
decorator with an equivalent function call:.

class Demo9(object):
    def fact(n):
        if n < 2:
            return 1
        else:
            return n * Demo.fact(n - 1)

    _classvar = fact(5)
    fact = staticmethod(fact)

print Demo9._classvar
xx = Demo9()
print xx.fact(6)
print Demo9.fact(8)


subject: Re: Need help with Python scoping rules

text:
On Aug 26, 8:13 am, Dave Angel <[email]> wrote:

This won't work normally.  It only worked for you because you made a
typo.

Carl Banks


subject: Re: Need help with Python scoping rules

text:
On Aug 26, 8:36 am, kj <[email]> wrote:

Oh well, I guess that sucks for you.

Carl Banks


author: Terry Reedy

subject: Re: Need help with Python scoping rules

text:
kj wrote:

Classes are objects.  In particular, they are (by default) instances of
class 'type'. Unless 'scopes' were instances of some other metaclass,
the statement has to be true. I understand 'scope' as referring to a
section of code, as opposed to a runtime object.

Class statements introduce a new local namespace used to define the
class.  Whether one considers that as introducing a new 'scope' depends,
I suppose, on one's exact definition of scope.

It is a 'wart' that a Python object is not a 'scope', whatever that is
to you? I have trouble comprehending that claim.

I really do not see how your claim follows from the comment. The irony
of your 'two counts' is that the example of 'count 2' fails precisely
because of the encapsulation that you claim does not exist as 'count 1'.

I claim it does not. Name-based recursion inherently requires that a
function be able to access itself by name at the time it is called. This
can be a bit tricky, especially in a language with dynamic rather than
static name binding and resolution, as it requires that code within the
function be able to access a scope outside itself in which the function
name is defined. In other words, it requires that function code *not* be
completely encapsulated. It also require that the appropriate name be
used when there is one. Neither of these is a 'peculiar restriction'
imposed by Python.

This function is just a function. It is not an instance method. It is
not even a class method. It does not belong here and should not be here.

If you insist on putting it where it does not belong, then you have to
call it by a name that works.  If you only call it after the class
statement has finished, then 'Demo.fact_rec' works, as I believe someone
else pointed out.

If you want to call the function during class creation, before (in this
case) Demo exists, then binding it to a local name works. With 3.1

class Demo:
    def f1(n):
       if n < 2: return 1
       else:     return n * Demo.f1(n - 1)

    def f2(n,f):
       if n < 2: return 1
       else:     return n * f(n - 1, f)

    cvar = f2(5, f2)

print(Demo.f1(5), Demo.cvar, Demo.f2(5,Demo.f2))

# prints
120 120 120

Iteration can and has been viewed as within-frame recursion. When
iterative rather than recursive syntax is used, the naming issue is
avoided.

After reading the above, what, if anything, do you think still needs to
be fixed?

Before 2.2, Python functions were more encapsulated than they are today
in that they could only access local and global namespaces but not outer
function namespaces.  It would be possible to further de-encapsulate
them by giving them direct access to lexically surrounding class
namespaces, but this would increase the problem of name clashes without
solving any real problems in proper Python code. It could also break the
intentional design principle that function code should mean the same
thing whether placed within or without a class statement. This principle
allows functions to be added to existing classes as attributes and work
as methods that same as if they had been defined with the class.

Terry Jan Reedy


subject: Re: Need help with Python scoping rules

text:
Carl Banks wrote:
Sorry about the typo.  I was trying out several different versions of
the class in the same module, and forgot to include to change Demo to
Demo9 in the recursive call.

I didn't like that approach anyway, as it smacked of taking advantage of
some implementation accident.  The other approaches are more
straightforward.

DaveA


subject: Re: Need help with Python scoping rules

text:
In <[email]> "Diez B. Roggisch" <[email]> writes:

Thanks for this.  I think this is the most straightforward workaround.

kynn


author: Ulrich Eckhardt

subject: Re: Need help with Python scoping rules

text:
Jean-Michel Pichavant wrote:

class Color:
    ...

setattrib(Color, "BLACK", Color(0,0,0))

Uli


subject: Re: Need help with Python scoping rules

text:
Ulrich Eckhardt wrote:
Or instead of setattrib,

Color.BLACK = Color(0,0,0)

DaveA


author: Diez B. Roggisch

subject: Re: Need help with Python scoping rules

text:
Jean-Michel Pichavant wrote:

Nope. Because then a lot of people would write something like this:

class Foo(object):

   def bar(self):
       bar() # note the missing self.

And this would lead to errors because self was missing from the call
to "bar".

And you'd need a disambiguation for methodname/global-name-clashes. The
global-statement would work, but then code could break when all  of a
sudden a subclass defines a method that hitherto was only known as global.
So via subclassing, you introduce *arbitray* and hard to debug errors.

No. I'm certain, not a good idea.

Diez


subject: Re: Need help with Python scoping rules

text:
On Aug 25, 7:26 pm, Dave Angel <[email]> wrote:

An "argument" is something that is specified in the the function
call.  I assume you are trying to state something like, "fact() is not
defined with a parameter variable named self".  However, that has
never been a requirement in python:

class A(object):

    def fact(n):
        print n

    fact("hello")

a = A()
a.fact()

--output:--
hello
<__main__.A object at 0x7faf0>


subject: Re: Need help with Python scoping rules

text:
7stud wrote:
You're good at nitpicking.  I concede the distinction between argument
and formal parameter.   And self is a convention, not a requirement.
But the fact is that the method as written would never have worked, when
called from outside the class, since you'd have to call it with either
the class name or an instance, and in either case, the method was then
trying to do arithmetic on one of those.

Thanks for diluting my point.  The OP is chasing the wrong problem.  Who
cares whether a class initializer can call a method, if the method
doesn't meet its original requirements, to be callable outside the class?

And the arguments about how recursion is restricted are ridiculous.
Nothing wrong with a method calling itself, once it's got a proper
signature.  You just have to make the call agree with the signature.
The problem is only that the method may not be actually called until the
class definition is complete.

DaveA


subject: Re: Need help with Python scoping rules

text:
In <[email]> Dave Angel <[email]> writes:

No, the fact() function here represents an internal "helper"
function.  It is meant to be called only once to help initialize
a class variable that would be inconvenient to initialize otherwise;
this helper function is not meant to be called from outside the
class statement.  Granted, in the example I gave, the "helper"
function (factorial) is a bit silly, but that was just intended as
a simple and familiar example of a recursive function.  The actual
function that motivated this post would be considerably more
difficult to explain and would have obscured the point of the post.

kynn


subject: Re: Need help with Python scoping rules

text:
In <02a54597$0$20629$[email]> Steven D'Aprano <[email]> writes:

Because, as I've explained elsewhere, it is not a method: it's a
"helper" function, meant to be called only once, within the class
statement itself.

Well, this is not strictly true, because the function is recursive,
so it will also call itself a few times.  But still, all these
calls happen (loosely speaking) "within the class statement".

In fact the only reason to use a function for such initialization
work is when one needs recursion; otherwise there's no point in
defining a function that will only be invoked exactly once.

kynn


subject: Re: Need help with Python scoping rules

text:
In <02a54597$0$20629$[email]> Steven D'Aprano <[email]> writes:

Thanks!

kynn


subject: Re: Need help with Python scoping rules

text:
In <[email]> Ethan Furman <[email]> writes:

Thanks, this is instructive.

I think I understand the answers well enough.  What I *really*
don't understand is why this particular "feature" of Python (i.e.
that functions defined within a class statement are forbidden from
"seeing" other identifiers defined within the class statement) is
generally considered to be perfectly OK.  IMO it's a bizarre,
inexplicable blindspot (which, among other things, gives rise to
a certain worry about what other similar craziness lurks under
Python's image of rationality).  I have never seen even a half-hearted
justification, from a language design point of view, for why this
particular "feature" is worth having.  Maybe some day the BDFL will
deign to give one.

kynn


author: Ethan Furman

subject: Re: Need help with Python scoping rules

text:
kj wrote:

You keep using that word.  I do not think it means what you think it
means.  :)

Keep studying.  Listen.  Learn how it *is*.  Understanding may come later.

~Ethan~


subject: Re: Need help with Python scoping rules

text:
kj wrote:

I attempted to give an explanation in my previous post.


author: Jean-Michel Pichavant

subject: Re: Need help with Python scoping rules

text:
kj wrote:

I think I got your point.
I guess many people may not be receptive to your question, cause guess
what, we're all python fans :o)

in foo.py:

a = 5
b = a # works fine

class A:
    c = 5
    d = c # broken
    d = A.c # broken either

    def foo(self):
       e = 5
       f = e  #works fine

We should all acknowledge that any newcomer to python will not expect
such behavior. There are plenty of good answers to that thread
explaining why the fact that classes are not scopes is much better.
Still this design fails at one point : insight.
It may be solved by creating the class upon the "class" statement. If
the class A object is created, then c is added as a property of that
object, there's no problem accession one object property with A.c.

JM


subject: Re: Need help with Python scoping rules

text:
In <02a6427a$0$15633$[email]> Steven D'Aprano <[email]> writes:

Thank you!

kynn


author: Martin P. Hellwig

subject: Re: Need help with Python scoping rules

text:
kj wrote:
<cut>
Who says?
Anyway, you could be right (I am not capable to judge it) and Python
should change on this issue but from what I gathered, Pythons OO is
inspired by the following:
- Don't repeat yourself
- Containing code into logical units makes it easier to understand and
maintain.

Note the absence of 'OO is defined as X so we are going to do X without
thinking if X is actually the best way to do it'

Probably right too, but being intrigued, why is that necessary, and
given an example is that the best way to do it?

<cut>
It is also one of the best ways to shoot yourself in the foot, but I ask
you again, is the reason why you encountered this 'limitation' actually
the best way to solve your problem?

Please forgive my incompetence if this reply sounds harsh and patronizing.


author: Mel

subject: Re: Need help with Python scoping rules

text:
kj wrote:

Python is not a compiled language, in the sense that a compiler can go back
and forth over the program, filling in the details that make the program
runnable.  Python is an interpreted language in a sense that makes a `class`
statement an executable statement, with a start time and an end time.
Before the start time, the affected class doesn't exist.  After the start
time, the class does exist.  In between, while the `class` statement is
executing, it's best to make no promises so as not to constrain present and
future implementations.

	Mel.


author: D'Arcy J.M. Cain

subject: Re: Need help with Python scoping rules

text:
On Thu, 27 Aug 2009 09:10:46 +0100
Stephen Fairchild <[email]> wrote:

That should be "class".

I suppose you mean "del fact".


subject: Re: Need help with Python scoping rules

text:
In <[email]> Carl Banks <[email]> writes:

Yes, you do.  As I said in another post, Python offers some degree
of class-level encapsulation (e.g. class variables).  But it is
limited by the fact that these class-encapsulated elements can't
always be accessed from within the class itself, which is kind of
silly.

It would be trivial to define a keyword (e.g. this, or if you
prefer, __this__), valid only within a class statement, and that
the interpreter would recognize as "the current class", even before
this class is full defined.

kynn


subject: Re: Need help with Python scoping rules

text:
In <[email]> Carl Banks <[email]> writes:

Repeating an earlier example (though I've switched the order of
the two internal functions):

class Demo(object):
    def fact_iter(n):
        ret = 1
        for i in range(1, n + 1):
            ret *= i
        return ret

    def fact_rec(n):
        if n < 2:
            return 1
        else:
            return n * fact_rec(n - 1)

    classvar1 = fact_iter(5)
    classvar2 = fact_rec(5)

In the initialization of classvar1, fact_iter is invoked without
any problem even though the class is not yet created: no need to
qualify it with the name of the class.  This is completely inconsistent
with the requirement that fact_rec be so qualified when invoked
within fact_rec.

kynn


subject: Re: Need help with Python scoping rules

text:
In <[email]> Carl Banks <[email]> writes:

It does: it thwarts encapsulation.  The helper function in my
example is one that clearly rightfully belongs nowhere else than
the class itself, i.e. encapsulated within the class.  It is only
this silly prohibition against recursive functions in a class
statement that forces one to put it outside the class statement.

kynn


subject: Re: Need help with Python scoping rules

text:
Ulrich Eckhardt wrote:

Apart from it being "setattr" and not "setattrib", a simple

  Color.BLACK = Color(0,0,0)

should have done the job here. However, what I had in mind was this:

  class Color:
      _colors = [ ("BLACK", (0,0,0)),
                  ("WHITE", (1,1,1))
                ]

      def __str__(self):
          # try to locate a name
          for name, rgb in Color._colors:
              if self.rgb==rgb:
                  return name
          # no name found, just format as a triplet
          return "(%s, %s, %s)" % self.rgb

  # add symbolic names
  for name, rgb in Color._colors:
      setattr(Colors, name, Color(rgb))

...which I got as suggestion on my question how to model C enumeration
lookalikes.

Uli


subject: Re: Need help with Python scoping rules

text:
Ulrich Eckhardt wrote:

Obviously ... I'll remember that.

JM


subject: Re: Need help with Python scoping rules

text:
In <[email]> Dave Angel <[email]> writes:

As I described at length in another reply, the function in question
is not intended to be "callable outside the class".  And yes,
recursive functions in Python *are* restricted in ways that
non-recursive functions aren't.  The examples I've posted prove
this point unambiguously.

At this point the only defense for this restriction is to claim
that it is somehow negligible.  But I disagree.  It's easy to come
up with equally negligible, and equally indefensible, restrictions
to the language would be found quite unacceptable by most users.
E.g. suppose that Python's specification prohibited the use of
upper case X in an identifier.  That's certainly a negligible
restriction: it is not harder at all to write great software without
the services of the letter X than with them.  Still, I think most
users would find this restriction infuriatingly idiotic.  Which
pretty much captures what I feel about Python's prohibition of
recursive functions within class statements.

kynn


author: greg

subject: Re: Need help with Python scoping rules

text:
kj wrote:

That, to me, is an excellent indication that the function
does *not* belong inside the class!

The only things that belong inside the class are things
that users of the class will need to use, or that instances
of the class will need to do their job.

Your helper function belongs outside the class, in the
module where the class is defined.


author: Piet van Oostrum

subject: Re: Need help with Python scoping rules

text:
Classes don't have helper functions; they have methods. Instance
methods, static methods or class methods. Your's isn't either of these.
Methods are to be called like `something.method(...)'.


subject: Re: Need help with Python scoping rules

text:
kj wrote:

This is not the same thing, and definitely not exactly the same thing.
In your example you are explicitly stating whether you want the original
class variable, or the current, and possibly different, instance
variable.  Further, the instance variable will not be different from the
class variable, even after C.x = whatever, unless the instance has had
that variable set specifically for it.

In [1]: class C(object):
    ...:     x = 9
    ...:     def doit(self):
    ...:         print C.x
    ...:         print self.x
    ...:

In [2]: test = C()

In [3]: test.doit()
9
9

In [4]: C.x = 10

In [5]: test.doit()
10
10

In [6]: test.x = 7

In [7]: test.doit()
10
7

~Ethan~


author: Stephen Fairchild

subject: Re: Need help with Python scoping rules

text:
kj wrote:

So why didn't you delete it after you were done with it?

Class Demo(object):
    def fact(x):
        ...

    _classvar = fact(5)
    del fact()


subject: Re: Need help with Python scoping rules

text:
In <[email]> Jean-Michel Pichavant <[email]> writes:

Thanks!  I was beginning to think I'd gone crazy.

kynn


subject: Re: Need help with Python scoping rules

text:
In <[email]> Jean-Michel Pichavant <[email]> writes:

I thought one could implement something like

class A:
    c = 5
    d = __thisclass__.c

But apparently this is a *huge* deal.  I'm not sure if the reason
it is a huge deal is that it is technically difficult to implement,
or that there is an implicit "lie" in having something (__thisclass__)
standing for something else that doesn't yet exist (and the potential
errors that may arise from this "lie" in sufficiently unfortunate
code).  Or maybe something else beyond my noobish ken altogether.

kynn


author: Bruno Desthuilliers

subject: Re: Need help with Python scoping rules

text:
Jean-Michel Pichavant a ï¿½crit :

Err... Did you actually tried this ?

...     c = 5
...     d = c
...
5
5

Not "broken" : the class doesn't yet exists, nor is it bound to global
name 'A'. FWIW, *this* works (for some definitions of 'works') juts fine:

...     c = 42
...
...     d = A.c
...
42

Any newcomer to any language should aknowledge that her expectations
based on previous experience with any other language should be kept
aside or just plain abandoned, and start by learning the new language.

The only thing one is entitled to expect when learning a new language is
that the language's implementation follows the language specs.

Oh, really ?

Please, write a pep...


subject: Re: Need help with Python scoping rules

text:
In <[email]> "Martin P. Hellwig" <[email]> writes:

Python itself: it already offers a limited form of class encapsulation
(e.g. class variables).  It would be nice if it went all the way
and gave classes their own bona fide scope.  (But I hasten to add:
I *still* don't understand the Python scope model, and not for lack
of trying.  I've only succeeded in finding fragments of this model
explained here and there, like pottery shards: a bit lost in a
tutorial, or some comment in a newsgroup thread, etc.  Maybe the
full, authoritative documentation of Python's scope model got lost
somewhere, and will be found by archaeologists in the 25th century...)

...except, apparently, when that code is a recursive function, in
which case one's out of luck.

If recursion is so evil, and Python so intent in saving us from
shooting ourselves in the foot, why does it allow recursion at all?

kynn


subject: Re: Need help with Python scoping rules

text:
kj wrote:

Let me take a shot at explaining this, maybe it helps that I'm mostly a C++
guy....

Firstly, if Python sees a name, it looks up that name first in the local
scope and then in the global scope. This is very simple (especially
compared to C++ when adding ADL there...), but it is something most people
can live with. So, even inside a class function (static or member), you
have to qualify a function call like 'ClassName.function_name', because
neither is 'function_name' a local nor is it a global.

Secondly, and that is due to the very dynamic nature of Python's types, the
class doesn't exist until its definition is finished. Therefore, any
attempt (directly or indirectly) to access a class member will usually fail
before that time. The exception is that inside the class definition you can
access the members directly, because they are in the same scope (access to
locals). Note that the scope already seems to exist but that it is not yet
available under any name! Looking at your example, you can not
write 'classvar1 = Demo.fact_iter(42)', because the lookup of 'Demo' will
fail.

Now, what actually causes problems is that 'fact_rec' is not universally
accessible until class 'Demo' is fully defined, but you need this in order
to fully define it. Here comes a drawback of the dynamic nature of Python,
that the declaration phase (compiling) is not separate from the execution.

I fully agree that this case is rather vexing to my (and obviously your)
biased brain. I wouldn't call this a bug before fully understanding why
e.g. you can not access a class before its definition is finished. I think
someone mentioned one or two PEPs, which are the design documents that
explain Python including the rationale, I'd use that as a starting point.

Suggestion: someone mentioned that you should make the function a normal
function. You can mark it as private using an underscore as prefix. If you
want to make it foolproof, you could even delete ("del fact_rec") the
function after use. Other alternatives would be to put it into a separate
baseclass, use a local function as implementation or to add the class
attributes after defining the class. Neither of these provide the 'perfect'
encapsulation of things in a class that you might be used to from e.g.
Java, but they have proven to be very useful nonetheless.

Uli


subject: Re: Need help with Python scoping rules

text:
kj a ï¿½crit :

I don't see what's wrong with having this function at the top-level.
Sorry to have to say it this way, but IMHO you're border on cargo-cult
thinking here. Python is an all-object language (ie : everything is an
object, including functions, classes and modules), but it's by no mean
'pure-object', and module level functions are perfectly ok (and quite
often the right thing).

Now if you really want to "encapsulate" the function and the class
together, you do have simple and and working solutions : using a nested
recursive function (as explained by Diez), or nesting both the class and
function in a factory function, ie:

def Demo():
   def fact(n):
     if n < 2:
       return 1
     else:
       return n * fact(n - 1)
   class Demo(object):
     _classvar = fact(5)
   return Demo

Demo = Demo()

But anyway: this is really a WTF. Python's notion of encapsulation is
very weak (by design), and you're really wasting time trying to fight
the language instead of learning it. Just put that f... helper function
at the top level (prefixing it's name with a '_' to mark it as
implementation detail), and move on to something else !-)

The "prohibition" only happens for recursive functions defined *and*
called in the class statement. And once you get the big picture, it's
certainly not "silly".


subject: Re: Need help with Python scoping rules

text:
Miles Kaufmann <[email]> writes:

Ah!  Clarity!  Thanks!  How did you find this?  Did you know of
this post already?  Or is there some special way to search Guido's
"design justifications"?

But this unfortunate situation is already possible, because one
can already define

class C:
   x = 1
   def foo(self):
       print C.x
       print self.x

which would lead to exactly the same thing.

I need to learn more about metaclasses, though, to fully understand
your post.

Many thanks!

kynn


subject: Re: Need help with Python scoping rules

text:
In <[email]> Ethan Furman <[email]> writes:

Thanks for the clarification!

kynn


subject: Re: Need help with Python scoping rules

text:
In <4a967b2f$0$19301$[email]> Bruno Desthuilliers <[email]> writes:

In fact, the official docs, when they discuss scopes, are off to
a bad start:

  Names refer to objects. Names are introduced by name binding
  operations. Each occurrence of a name in the program text refers
  to the binding of that name established in the innermost function
  block containing the use.

The first paragraph implies that binding can only occur within
functions, which is either incorrect, or presupposes a definition
of "function" that is not what most programmers would recognize.

In general, I found the docs very unclear on the subject of scoping.
PEP 227 is much better, but I wouldn't have thought of it as "the
specs".

kynn


subject: Re: Need help with Python scoping rules

text:
kj a ï¿½crit :

"class variables" - which FWIW include the "methods" - are just
attributes of the class *object* (reminder : Python's classes and
functions *are* objects too). Any name bound at the top level of the
class statement scope becomes an attribute of the class object. IOW,
this "limited form of class encapsulation" is just the ordinary "form of
encapsulation" you'll get with Python objects.

I think that what you should first understand are Python's execution and
object models.

I wrote quite a few recursive functions in Python and never had any
problem.

It's not a restriction on recursion, it's a scoping rule that apply to
any other name. You can't access the class statement's scope from within
a function, period.

Recursion is not evil, and Python doesn't try to prevent anyone from
doing stupid things anyway. FWIW, do you know that you can add / replace
/ remove attributes (including methods) at runtime, both on a
per-instance or per-class basis ? And even dynamically change the class
of an object ?-)


subject: Re: Need help with Python scoping rules

text:
In <[email]> Ulrich Eckhardt <[email]> writes:

Thanks for your reply.

I understand this, what I don't understand is why do it this way.
I've been trying to understand this particular design point for
*literally* years.

I'm reading PEP 227 now, suggested by Steven D'Aprano.  In it I
find statements like the following alert:

    (Note: If a region is contained within a class definition, the
    name bindings that occur in the class block are not visible to
    enclosed functions.)

I've seen this before, but never an explanation for why having this
restriction.  It's just one of life's mysteries.  (Incidentally,
the fact that the author of PEP 227 felt it necessary to add that
parenthetical remark suggests that the expectation it warns against
is not so crazy after all.)

But I'm still not done with PEP 227.  Maybe I'll see the light by
the time I'm done.

kynn


subject: Re: Need help with Python scoping rules

text:
Ulrich Eckhardt a écrit :
(snip)

It is. You can manually compile a module, remove the source .py and
still import (or execute) the compiled .pyc.

The "problem" here is not with compilation, but with the fact that
'class' (and 'def') statements are *executable* statements. IOW, the
class statement is executed when encountered, that is, usually (most
class statements being top-level statements), when the module is first
loaded.

Nor why it's a GoodThing(tm) for quite a lot of use case - while the
OP's problem is in the splitting-hairs category - only a problem if yoçu
insist in imposing your views on the language instead of learning how to
use it.

(snip)

Someone (Diez Roggisch IIRC) also mentionned a simple solution that
mostly fulfills the OP's desires: use a nested function.


subject: Re: Need help with Python scoping rules

text:
kj wrote:

How is this a problem? There is no ambiguity between the global scope and
the local from within foo.


subject: Re: Need help with Python scoping rules

text:
kj a ï¿½crit :

Indeed, and you're right to point it. I strongly suggest you submit a
ticket to the doc maintainers.

Well, here again, it sure would help to make clear that peps (and
release specific "what's new") *are* part of the doc. But for sure, what
used to be a simple and clear reference is now a bit of a mess, despite
the hard work of the doc team. Side-effect of the rapid growth of the
language I guess...


subject: Re: Need help with Python scoping rules

text:
kj a ï¿½crit :
(snip)

It's quitye simple: 'class' is an executable statement that creates a
class object (yes, all this happens at runtime) and bind it in the
current namespace. So until the class statement is executed, the class
object doesn't exist and it's name is not bound.

Now if you don't understand why it's a GoodThing(tm) that all this
happens at runtime, have a look at metaclasses, how they are used in
most major Python frameworks, and how this allows to vastly reduce the
amount of needed boring and erreor-prone boilerplate code one cand find
elsewhere.

You should re-read Carl Bank's answers more carefully then.

It's not so crazy for someone coming from a more static language.
Python's object model is indeed a bit peculiar, and it can take some
times getting the big picture, but be sure it has been carefully
designed, and is incredibly powerfull once you start understanding the
whole thing.

My 2 cents : learn about metaclasses, attributes lookup rules, and the
descriptor protocol (and some practical applications of these features).
Then you might decide that the few resulting restrictions are really
worth the price.


author: Ron Garret

subject: WSGI question: reading headers before message body has been read

text:
I'm writing a WSGI application and I would like to check the content-
length header before reading the content to make sure that the content
is not too big in order to prevent denial-of-service attacks.  So I do
something like this:

def application(environ, start_response):
    status = "200 OK"
    headers = [('Content-Type', 'text/html'), ]
    start_response(status, headers)
    if int(environ['CONTENT_LENGTH'])>1000: return 'File too big'

But this doesn't seem to work.  If I upload a huge file it still waits
until the entire file has been uploaded before complaining that it's
too big.

Is it possible to read the HTTP headers in WSGI before the request
body has been read?

Thanks,
rg


subject: Re: WSGI question: reading headers before message body has been read

text:
Ron Garret schrieb:

AFAIK that is nothing that WSGI defines - it's an implementation-detail
of your server. Which one do you use?

Diez


author: Petite Abeille

text:
On Jan 18, 2009, at 8:01 PM, Ron Garret wrote:

How would that work for chunked transfer-encoding?

Cheers,


text:
On Jan 18, 11:29 am, "Diez B. Roggisch" <[email]> wrote:

Apache at the moment, with lighttpd as a contender to replace it.

rg


text:
On Jan 18, 11:43 am, Petite Abeille <[email]> wrote:

It wouldn't.  But many clients don't use chunked-transfer-encoding
when uploading files whose size is known.  In that case it would be
nice to let users know that their upload is going to fail BEFORE they
waste hours waiting for 10GB of data to go down the wire.

rg


text:
On Jan 18, 12:40 pm, "Diez B. Roggisch" <[email]> wrote:

Yes.  (Is there any other way to run WSGI apps under Apache?)

rg


author: Graham Dumpleton

text:
On Jan 19, 6:01 am, Ron Garret <[email]> wrote:

You should be returning 413 (Request Entity Too Large) error status
for that specific case, not a 200 response.

You should not be returning a string as response content as it is very
inefficient, wrap it in an array.

Yes.

The issue is that in order to avoid the client sending the data the
client needs to actually make use of HTTP/1.1 headers to indicate it
is expecting a 100-continue response before sending data. You don't
need to handle that as Apache/mod_wsgi does it for you, but the only
web browser I know of that supports 100-continue is Opera browser.
Clients like curl do also support it as well though. In other words,
if people use IE, Firefox or Safari, the request content will be sent
regardless anyway.

There is though still more to this though. First off is that if you
are going to handle 413 errors in your own WSGI application and you
are using mod_wsgi daemon mode, then request content is still sent by
browser regardless, even if using Opera. This is because the act of
transferring content across to mod_wsgi daemon process triggers return
of 100-continue to client and so it sends data. There is a ticket for
mod_wsgi to implement proper 100-continue support for daemon mode, but
will be a while before that happens.

Rather than have WSGI application handle 413 error cases, you are
better off letting Apache/mod_wsgi handle it for you. To do that all
you need to do is use the Apache 'LimitRequestBody' directive. This
will check the content length for you and send 413 response without
the WSGI application even being called. When using daemon mode, this
is done in Apache child worker processes and for 100-continue case
data will not be read at all and can avoid client sending it if using
Opera.

Only caveat on that is the currently available mod_wsgi has a bug in
it such that 100-continue requests not always working for daemon mode.
You need to apply fix in:

  http://code.google.com/p/modwsgi/issues/detail?id=121

For details on LimitRequestBody directive see:

  http://httpd.apache.org/docs/2.2/mod/core.html#limitrequestbody

Graham


text:
On Jan 19, 6:43 am, Petite Abeille <[email]> wrote:

Chunked transfer encoding on request content is not supported by WSGI
specification as WSGI requires CONTENT_LENGTH be set and disallows
reading more than defined content length, where CONTENT_LENGTH is
supposed to be taken as 0 if not provided.

If using Apache/mod_wsgi 3.0 (currently in development, so need to use
subversion copy), you can step outside what WSGI strictly allows and
still handle chunked transfer encoding on request content, but you
still don't have a CONTENT_LENGTH so as to check in advance if more
data than expected is going to be sent.

If wanting to know how to handle chunked transfer encoding in
mod_wsgi, better off asking on mod_wsgi list.

Graham


text:
On Jan 18, 1:21 pm, Graham Dumpleton <[email]>
wrote:

Thanks for the detailed response!

rg


text:
Ron Garret schrieb:

Well, not so easy, but of course you can work with mod_python or even
CGI/fastcgi to eventually invoke a WSGI-application.

However, the original question - that's a tough one.

According to this, it seems one can use an apache-directive to prevent
mod_wsgi to even pass a request to the application if it exceeds a
certain size.

http://code.google.com/p/modwsgi/wiki/ConfigurationGuidelines

Search for "Limiting Request Content"

However, I'm not sure how early that happens. I can only suggest you try
& contact Graham Dumpleton directly, he is very responsive.

Diez


author: Harry Putnam

subject: no ssh get thru - how to debug

text:
My setup:

   RedHat linux 7.1 - openssh-3.1p1-5
   Redhat linux 7.3 - openssh-3.1p1-6
   NETGEAR FR314 router/firewall/switch

My hookup looks like the diagram below.  It is a little odd but
affords a way for me to tinker with network stuff behind the relative
saftey of a firewall:

      INTERNET
         |
        ---(dsl modem)
         |
         | -- static IP
   -------------------------
       (STATIC internet IP)
    (NETGEAR ROUTER)
      (192.168.0.1 static lan IP)
   _________________________
    |              |
    | 192.168.0.7  |192.168.0.5
  rh7.3           rh7.1(set up to ipmasquerade for those behind)
    | 192.168.1.5  |
    |______________|
                   |
                   |
              _____|______ (Netgear hub)
              |    |     |
             m3   m4    m5
            (these machines are all 192.168.1.x)

As shown, machine rh7.3 has an extra wire on 192.168.0.x that goes
direct to router/firewall.. Its not actually used except for tests or
tinkerage.

Machine rh7.1 is setup to ipmasquerade for the m machines on
192.168.1.x and the 192.168.1.x cable from rh7.3

( I hope NAT is the correct term here)

I want to set machine rh7.3 as a NATed ssh server/client reachable
from the internet.  That kind of thing can be done on the NETGEAR
router by specifying the internal address to NAT to.

However if I set 192.168.1.5 or 192.168.0.7 (eth1 or eth0 on rh7.3)
as the server, it cannot be reached from the internet.  Setting
192.168.0.5 (eth0 on rh7.1) works fine.

Further, rh7.3 can ssh out to the internet or to any internal machine.
rh7.1  can ssh to rh7.3 on 192.168.0.7 or 192.168.1.5, as well as out
to internet.

Setting 192.168.1.5 (rh7.3 eth1) as the NATted server:
Trying ssh -vv for diagnostics from a remote internet host to static
IP address of firewall gives me a hung session like this:

  $ ssh -vv [email]
  OpenSSH_3.4p1, SSH protocols 1.5/2.0, OpenSSL 0x0090602f
  debug1: Reading configuration data /etc/ssh/ssh_config
  debug1: Applying options for *
  debug1: Rhosts Authentication disabled, originating port will not be trusted.
  debug1: ssh_connect: needpriv 0
  debug1: Connecting to xxx.xxx.xxx [xxx.xxx.xxx] port 22.
[ very lengthy pause ]
ssh: connect to address xxx.xxx.xxx port 22: Connection timed out
=====

If I set 192.168.0.5 (rh7.1 eth0 above) as NATted server then it
works from that same internet client.

What else can I do to determine what is blocking this?
(There are  no log messages appearing on the firewall itself or on
the client where the session is being run)


author: all mail refused

subject: Re: no ssh get thru - how to debug

text:
In article <[email]>, Harry Putnam wrote:

I think the above is what you should do.

Also arrange that the sshd on rh7.1 listens only on the other interface in
order to leave 192.168.0.5:22 vacant.

Then get rh7.1 to forward with NAT to the inner address of rh7.3.
I'm still using ipchains rather than iptables so I will not suggest syntax.

While talking to rh7.3 Internet traffic will have been NAT-ed twice: once
to 192.168.0.5 by the router then again by rh7.1.


subject: Re: no ssh get thru - how to debug

text:
[email] (all mail refused) writes:

Thanks for the suggestion.  I'm presently unable to implement it
since I'm not longer at the (now) remote location.  And afraid to
change anything form a remote connection for fear of locking myself
out.

I'll try it when I next return home.


author: Bertrand Meyer

subject: Re: What is wrong with OO ?

text:
Chris Bitmead wrote:

[Quoting me, quotation abridged:]

[...]

[Chris Bitmead:]

Sorry, sloppy wording on my part. I meant "called from many different
places in the code", which  does tend to correlate with the numbers of
times the routine will be called, although of course this is not always
true (as with a routine that is called from just one place, but that
place is in a loop). Just one criterion among others. Thanks for noting
the incongruity in my original message.


author: Enzo Benvenuti

subject: PDF Printing (many files)

text:
Pdf printing [vo28.sp1]

I need to print a lot of pdf files togheter and sometimes many copies,
.....
apdffiles := {sPDFILE_1, sPDFILE_2, sPDFILE_3, ....... ,sPDFILE_50}

for i := 1 upto alen(apdffiles)
  for j := 1 upto nNumberofcopies
     ShellExecute(self:Handle(), psz("print"), psz(aPDFFiles[i]), null_psz,
null_psz, SW_HIDE)
  next
next
.....

but I have some problems whit printer spoler:
1) it changes printer order.
2) it loses some documents.
My problems is bigger if nNumberofCopies > 1

I have tried to modify printer spooler whithout results;
I have tried to substitute ShellExecute whith the following function:

FUNCTION PrintPDF(oOwner as OBJECT, cPDFFile as STRING) as void PASCAL
LOCAL ExecInfo as _winSHELLEXECUTEINFO
LOCAL hWnd as ptr
ExecInfo:=MemAlloc(_sizeof(_winSHELLEXECUTEINFO))
ExecInfo.cbSize:=_sizeof(_winSHELLEXECUTEINFO)
ExecInfo.lpVerb:=psz("print")
ExecInfo.lpFile:=psz(cPDFFile)
ExecInfo.nShow:=SW_SHOWMINIMIZED
IF ShellExecuteEx(ExecInfo)
   oOwner:Pointer:=Pointer{POINTERHOURGLASS}
   DO WHILE (hWnd:=FindWindow(null_psz, psz("Adobe Reader")))=null_ptr
 DoEvents()
 Sleep(500)  // Sleep(3000)
   ENDDO
   PostMessage(hWnd, WM_CLOSE, 0, 0)
   oOwner:Pointer:=Pointer{POINTERARROW}
ENDIF
MemFree(ExecInfo)
return

My problems remain and i have no more ideas.

Thank you to all.

Enzo Benvenuti


subject: Thanks to all... here to you my solution

text:
Function PrOpFiles() can print to all printers (also fax) or shows a PDF
file.

.....
apdffiles := {sPDFILE_1, sPDFILE_2, sPDFILE_3, ....... ,sPDFILE_50}

for i := 1 upto alen(apdffiles)
  for j := 1 upto nNumberofcopies
     PrOpFile(self, aPDFFiles[i], true)
  next
next
.....

function PrOpFile(oOwner as object, sDocFile as string, lPrint as logic) as
void pascal //(27-01-2008)
local ExecInfo as _winSHELLEXECUTEINFO
local hWnd as ptr

// Allocate structure memory
ExecInfo  := MemAlloc(_sizeof(_winSHELLEXECUTEINFO))

// Structure params
ExecInfo.cbSize := _sizeof(_winSHELLEXECUTEINFO)
ExecInfo.lpVerb := psz(iif(lPrint,"print","open"))
ExecInfo.lpFile := psz(sDocFile)
ExecInfo.nShow  := iif(lPrint, SW_SHOWMINIMIZED, SW_SHOWNORMAL)

// Printing or showing...
if ShellExecuteEx(ExecInfo)
   // Looking for the "Adobe Reader" caption...
   // If it's a NULL_PTR, it is still printing...
   do while (hWnd := FindWindow(null_psz, psz("Adobe Reader"))) = null_ptr
  Sleep(500)
 enddo
 // Waiting to avoid crashes (like a loop)...
 Sleep(iif(lPrint, 5000, 500))

 // Close
 if lPrint
    PostMessage(hWnd, WM_CLOSE, 0, 0)
 endif
endif

// Clean up
MemFree(ExecInfo)

return


author: Alessandro Antonangeli

subject: Re: PDF Printing (many files)

text:
Ciao
As you already supposed, the problem is that with the first way, you cannot
be sure about the order they are processed.
The second one would be correct if FindWindow would work, but as it writte
it would not, becaus as you call Adobe with a file name it's caption will
change accordingly to the file name, so findwindow will always return null
This is a piece of code to substitute to findwindow (i get here somewhere
and adapted)

Just call MyFindWindow("Adobe Reader") until it return TRUE, when it return
false, means no window found
Keep in mind that if you call it immediately after ShellExecuteEx, it may be
tha it will return false because adobe didnt still started
so could be
ShellExecuteEx (....
do while !MyFindWindow("Adobe Reader")
...
enddo

do while MyFindWindow("Adobe Reader")
...
enddo
now it should have finished


author: Michael Haensch

subject: Re: PDF Printing (many files)

text:
Hallo Enzo,

I had the same problem some time ago, tried a few ways, but found no
solution.

Now I merge the PDFs in one PDF-file (with QuickPDF) and print or
preview this PDF with ShellExecute.

Michael

I tried with
Enzo Benvenuti legte dieses als Verknï¿œpfung auf seinen Bildschirm :


author: John Martens

subject: Re: PDF Printing (many files)

text:
Maybe it helps to change the loops. This gives Windows and or Reader to
close the old file and open a new one that was not involved in opening.

   for j := 1 upto nNumberofcopies
     for i := 1 upto alen(apdffiles)
       ShellExecute(self:Handle(), psz("print"), psz(aPDFFiles[i]),
null_psz, null_psz, SW_HIDE)
     next
   next

John

Enzo Benvenuti schreef:


subject: Re: This is the right function

text:
function PrOpFile(oOwner as object, sDocFile as string, lPrint as logic) as
void pascal //(27-01-2008)
local ExecInfo as _winSHELLEXECUTEINFO
local hWnd as ptr

// Allocate structure memory
ExecInfo  := MemAlloc(_sizeof(_winSHELLEXECUTEINFO))

// Structure params
ExecInfo.cbSize := _sizeof(_winSHELLEXECUTEINFO)
ExecInfo.lpVerb := psz(iif(lPrint,"print","open"))
ExecInfo.lpFile := psz(sDocFile)
ExecInfo.nShow  := iif(lPrint, SW_SHOWMINIMIZED, SW_SHOWNORMAL)

// Printing or showing...
if ShellExecuteEx(ExecInfo)
 if lPrint
    // Looking for the "Adobe Reader" caption...
    // If it's a NULL_PTR, it is still printing...
    do while (hWnd := FindWindow(null_psz, psz("Adobe Reader"))) = null_ptr
   Sleep(500)
  enddo
  Sleep(5000)

  // Close
    PostMessage(hWnd, WM_CLOSE, 0, 0)
 endif
endif

// Clean up
MemFree(ExecInfo)

return


author: [redacted]

subject: Re: PDF Printing (many files)

text:
Enzo

first question is did you try and set the printer to handle the number
of copies, as that would remove one loop.

just remember to set it back after - but of course if its a network
one - disasters might abound.

i have also had problems in trying to CLOSE adobe after using it to
print.

here is the code i have for printing attachments..
METHOD PrintAttachment(cDocName) CLASS MailPrint
	LOCAL ExecInfo IS _winSHELLEXECUTEINFO
	LOCAL hProc AS PTR

//	works but leaves app open
//	ShellExecute(NULL, String2Psz("print"), String2Psz(cDocName), NULL,
NULL, SW_HIDE )

//	does NOT print for windows picture and fax viewer
	ExecInfo.cbSize  := _SIZEOF( _WINShellExecuteInfo )
	ExecInfo.hwnd    := SysObject():Handle()
	ExecInfo.lpVerb  := String2Psz("print")
	ExecInfo.lpFile  := String2Psz( cDocName )
	ExecInfo.lpParameters := NULL
	ExecInfo.nShow   := SW_HIDE
 	ExecInfo.fMask   := SEE_MASK_NOCLOSEPROCESS + SEE_MASK_FLAG_DDEWAIT

	IF ShellExecuteEx( @ExecInfo )  // works
		// Wait while its printing
		hProc := ExecInfo.hProcess

		DO WHILE WaitForSingleObject( hProc, 0 ) = WAIT_OBJECT_0 //
WAIT_TIMEOUT
			Sleep(500)
		ENDDO

        // Close it.
        SendMessage(hProc, WM_CLOSE, 0, 0)  // whats the difference
between send and post ?
        SendMessage(hProc, WM_QUIT,  0, 0)  // whats the difference
between send and post ?
        PostMessage(hProc, WM_CLOSE, 0, 0)  // whats the difference
between send and post ?
        PostMessage(hProc, WM_QUIT,  0, 0)  // whats the difference
between send and post ?

    ELSE
    	TextBox{SELF, 'Error','Error:'  + AsString(ExecInfo.hInstApp) +
CRLF + ;
    						  'Handle:' + AsString(ExecInfo.hWnd) + CRLF + ;
    						  'Class:'  + AsString(ExecInfo.lpClass) + CRLF + ;
    						  'Params:' + AsString(ExecInfo.lpParameters) + CRLF + ;
    						  'Verb:'   + AsString(ExecInfo.lpVerb) + CRLF + ;
    						  'File:'   + AsString(ExecInfo.lpFile) + CRLF + ;
    						  'Mask:'   + AsString(ExecInfo.fMask) + CRLF + ;
    						  'Size:'   + AsString(ExecInfo.cbSize) + CRLF + ;
    						  'Show:'   + AsString(ExecInfo.nShow)}:Show()
	ENDIF

RETURN NIL

// following are code snippets off web.

// this code keeps running while the app is running. not when process
is finished.
/*		lRunning := ( lpExitCode == STILL_ACTIVE )
		DO WHILE lRunning
			GetExitCodeProcess( hProc, @lpExitCode )
			lRunning := ( lpExitCode == STILL_ACTIVE )
			ApplicationExec(EXECWHILEEVENT)
		ENDDO
*/

/*
FUNCTION PrintPDFwithAdobeReader(oOwner AS OBJECT, cPDFFile AS STRING)
AS VOID PASCAL
	LOCAL ExecInfo AS _winSHELLEXECUTEINFO
	LOCAL hWnd AS PTR

	// Allocate structure memory
	ExecInfo:=MemAlloc(_SizeOf(_winSHELLEXECUTEINFO))

	// Structure params
	ExecInfo.cbSize:=_SizeOf(_winSHELLEXECUTEINFO)
	ExecInfo.fMask:=_Or(SEE_MASK_FLAG_DDEWAIT,
SEE_MASK_NOCLOSEPROCESS)     // not needed ?
	ExecInfo.lpVerb:=PSZ("print")
	ExecInfo.lpFile:=PSZ(cPDFFile)
	ExecInfo.nShow:=SW_SHOWMINIMIZED  // no effect ??? // SW_HIDE

	// Do it
	IF ShellExecuteEx(ExecInfo)
		oOwner:Pointer:=Pointer{POINTERHOURGLASS}

        // Looking for the "Adobe Reader" caption...
        // If it's a NULL_PTR, it is still printing...
        DO WHILE (hWnd:=FindWindow(NULL_PSZ, PSZ("Adobe
Reader")))=NULL_PTR
            DoEvents()
            Sleep(100)
        ENDDO

        // Close it.
        PostMessage(hWnd, WM_CLOSE, 0, 0)

        oOwner:Pointer:=Pointer{POINTERARROW}
	ENDIF
	// Clean up
	MemFree(ExecInfo)
*/

/*
METHOD OpenAndWait( cFile ) CLASS IMSDirectory
	LOCAL lpShellInfo IS _winShellExecuteInfo
	LOCAL lRet AS LOGIC
	LOCAL hProc AS PTR

	Default( @cFile, SELF:cFilePath+SELF:FileName )

	IF Empty( cFile )
		SELF:lErrorFlag := TRUE
		SELF:cErrorMessage := "Keinen Dateinamen erhalten!"
	ENDIF

	lpShellInfo.cbSize := _SizeOf( _winShellExecuteInfo )
	lpShellInfo.hwnd := SELF:Owner:Handle()
	lpShellInfo.lpVerb := String2Psz("open")
	lpShellInfo.lpFile := String2Psz( cFile )
	lpShellInfo.nShow := SW_ShowNormal
	lpShellInfo.fMask := SEE_MASK_NOCLOSEPROCESS + SEE_MASK_FLAG_DDEWAIT

	lRet := ShellExecuteEx( @lpShellInfo )

	IF lRet
		hProc := lpShellInfo.hProcess
		WHILE WaitForSingleObject( hProc, 0 ) = WAIT_TIMEOUT
		Sleep(500)
		ENDDO
	ENDIF

RETURN
*/


author: Devon T. Sowell

subject: Waiting to Upgrade

text:
Every year I wait longer and longer before I upgrade to the newest version. All my customers wait too.

It's really nice not to be frustrated by buggy software and praying that "SP01" will fix all the problems.

Real View? Come on, where's the productivity increase?

Best Regards,
Devon T. Sowell
www.3-ddesignsolutions.com


author: Sporkman

subject: Re: Waiting to Upgrade

text:
Ditto, Devon.  Except that I can't say I'm not frustrated by the bugs in
SW2003 SP5.0.  Maybe 5.1 which somebody says is just released will be
the answer to my prayers for the time being, but I'm not going to pass
out from holding my breath if it isn't.  (I might faint from surprise if
it IS though.)

To be fair, I actually (so far) have waited longer to upgrade to 2003
from 2001+ and from 2000 to 2001+ (I just about skipped that POS called
2001 entirely, and would have been happier if I had).  Let's see, when
was 2003 released?  November of 2002 or so?  And I went to 2003 from
2001+ in June of this year . . . and none too late I warrant.

'Sporky'


author: Kman

subject: Re: Waiting to Upgrade

text:
Remember the promise of improved SP quality as one of the reasons given for
reducing the number of SP's per year.  Actual results: Less SP's but it
still takes the same amount of time to reach stability (still waiting).
Suppose now SW will be claiming less SP's to stability as a marketing
gimmick.

Kman

"Devon T. Sowell" <[email]> wrote in message
news:fzRBb.12298$[email]...
Every year I wait longer and longer before I upgrade to the newest version.
All my customers wait too.

It's really nice not to be frustrated by buggy software and praying that
"SP01" will fix all the problems.

Real View? Come on, where's the productivity increase?

Best Regards,
Devon T. Sowell
www.3-ddesignsolutions.com


author: Larry Gagnon

subject: Thunderbird not talking to Firefox

text:
I recently installed Thunderbird email client v1.0.2 on my VectorLinux
v5.0 box, which has Firefox v1.0 already installed. Everything went
smoothly and all works, except highlighted web links in Thunderbird do not
boot up my default browser (firefox), nor any browser for that matter.
Env variable $BROWSER is set to "firefox". I have browsed through the
.thunderbird home directory and its config files and cannot see anything
obvious.

Any ideas on what to do appreciated.

Larry Gagnon


author: Michael Perry

subject: Re: Thunderbird not talking to Firefox

text:
You can add lines to prefs.js in thunderbird that will make firefox
open links from thunderbird something like this:

user_pref("network.protocol-handler.app.ftp",
"/usr/local/bin/firefox");
user_pref("network.protocol-handler.app.http",
"/usr/local/bin/firefox");
user_pref("network.protocol-handler.app.https",
"/usr/local/bin/firefox");

may have to change the last line to where firefox is located and also
make sure that thunderbird is closed when you do this.


subject: Re: Thunderbird not talking to Firefox

text:
On Wed, 15 Jun 2005 11:36:06 -0700, Michael  Perry wrote:

Thanks! Worked wonderfully...

Larry


author: Dan Waylonis

subject: Explorer Module programming help needed...

text:
Hi,

I'm in the process of slapping together a module to aid in animation whilist
using the mighty SGI Explorer.  I need to read a 3d curvilinear grid file (once)
and then <n> "frames" of <i> x <j> x <k> float values (one at a time).  I
would like to read the grid once, allocate space for the lattice structure,
and continue reading/replacing the data values.

One parameter to my module is a cxLattice* called lattice.

In the .mdw.c file, I changed the declaration from:

	cxLattice *lattice;

to

	static cxLattice *lattice = NULL;

Within my code, I call cxLatNew to allocate space for the lattice iff the
variable "lattice" is NULL, which should happen only once, when the module
is first called.

Nope.  I get passed "NULL" every time (I am passing the address of *lattice
to my routine).

Any Explorer gurus out there who can help?  Anyone from SGI?

Thanks,
Dan


author: Robert Skinner

subject: Re: Explorer Module programming help needed...

text:
In article <[email]>, [email] (Dan Waylonis) writes:
|> Hi,
|>
|> I'm in the process of slapping together a module to aid in animation whilist
|> using the mighty SGI Explorer.  I need to read a 3d curvilinear grid file (once)
|> and then <n> "frames" of <i> x <j> x <k> float values (one at a time).  I
|> would like to read the grid once, allocate space for the lattice structure,
|> and continue reading/replacing the data values.
|>
|> One parameter to my module is a cxLattice* called lattice.
|>
|> In the .mdw.c file, I changed the declaration from:
|>
|> 	cxLattice *lattice;
|>
|> to
|>
|> 	static cxLattice *lattice = NULL;
|>
|> Within my code, I call cxLatNew to allocate space for the lattice iff the
|> variable "lattice" is NULL, which should happen only once, when the module
|> is first called.
|>
|> Nope.  I get passed "NULL" every time (I am passing the address of *lattice
|> to my routine).
|>
|> Any Explorer gurus out there who can help?  Anyone from SGI?
|>
|> Thanks,
|> Dan
|> --
|> Dan Waylonis -- Minnesota Supercomputer Center -- Home
|> Graphics Guy    1200 Washington Ave So            1414 Laurel Ave, Apt 105
|> DoD: 370        Minneapolis MN 55415              Minneapolis MN 55403-1243
|> (91 6oof2)      (612) 626-0340                    (612) 673-9420

First of all, never edit the .mdw.c file.  It is automatically
generated from the module resource (.mres) file.

I take it from your description that you want your module to
fire once, but output N lattices.  If so, you must call cxOutputDataFlush.
The Module Builder can't assist you in doing the output portion, so
you don't need output parameters in the user function, or connections
from the user function to the outputs.

What you want to do is create a new lattice for each frame, but have
those lattices share the coordinates.  Here is how you do that:

	cxLattice	*lat;
	cxData		*data;
	cxCoord		*coords;
	float		*fdata;
	int		*outPort;

	/*
	 *  create the coordinates you want shared between each lattice
	 */
	coords = cxCoordNew( n, dims, 3, cx_coord_curvilinear );
	if( cxDataAllocErrorGet() ) return;	/* out of memory */

	/*
	 * ... read curv coordinates,
	 *	into coords->c.cx_coord_curvilinear.values
	 */

	outPort = cxOutputPortOpen( "(whatever your output port name is)" );

	for( i=0; i<N; i++ ) {
		/*
		 *  make a lattice with new data, but no coordinates
		 */
		lat = cxLatDataNew( n, dims, nDataVar, primType );
		if( cxDataAllocErrorGet() ) return;	/*this is a tough one */

		cxLatPtrGet( lat, 0, (void **)&fdata, 0, 0 );
		... read frame N data into *fdata ...

		/* make new lat share common coords */
		cxLatPtrSet( lat, 0, 0, coords, 0 );

		/*
		 *  put this lattice into output port
		 *	and cause it to be sent NOW
		 */
		cxOutputDataSet( outPort, lat );
		cxOutputDataFlush( outPort );
	}

All Explorer data types are reference counted.  'coords' reference
count gets incremented each time you put it into a new lattice, so it
will be N when you finish.  Or maybe < N, if downstream modules have
consumed some of the lattices.  In any event the coords will be
deleted when all of the lattices have been consumed.

The Module Builder normally does the cxOutputPortOpen and
cxOutputDataSet calls for you, but it can't do multiple
cxOutputDataSet's and the cxOutputDataFlush that you need in this
case.

Hope this helps,

Robert Skinner
[email]

	Sesame Street was brought to you today by the letter 'Q'
 	and the number 3.1415


author: Jeffrey Thingvold -Visualization

text:
In article <[email]>, [email] (Dan Waylonis) writes:

Are you sure that the .mdw.c file isn't being rebuilt every time you
install the module?  As of the beta release of Explorer I haven't been able to
keep cxmb from writing over my changes to the .mdw.c files.

A simple alternative would be to keep track of the static data yourself
and access the port directly. I.e.:

static cxLattice *output_lattice = NULL;

void module_function()
{
    long	index;

    /* Body of module */

    index = cxOutputPortOpen( "Output_Lattice");
    cxOutputDataSet( index, output_lattice );
}

Jeff


text:
Robert says:

Yeah, well in the earliest versions of Explorer the .mdw.c files were
wrong, so I got used to editing them.  They're also a good place
to start if you want to learn how write your own data-wrapper code.
For automatically generated code it's reasonably easy to read.  I can
see how a person might want cxmb to generate the data wrapper code and
then modify it themselves.

As it stands, I still have to edit the automatically generated Makefiles
to get some things to build :-(

Jeff


text:
In article <[email]>, [email] (Jeffrey Thingvold -Visualization) writes:
|> In article <[email]>, [email] (Dan Waylonis) writes:
|> >
|> > In the .mdw.c file, I changed the declaration from:
|> >
|> > 	cxLattice *lattice;
|> >
|> > to
|> >
|> > 	static cxLattice *lattice = NULL;
|> >
|>
|> Are you sure that the .mdw.c file isn't being rebuilt every time you
|> install the module?  As of the beta release of Explorer I haven't been able to
|> keep cxmb from writing over my changes to the .mdw.c files.
|>

the .mdw.c file is regenerated when the .mres file is changed.

It is autogenerated code, just like (yacc.y ->) yacc.c and (lex.l ->)
lex.c.  Its not meant to be read by mere mortals (like myself), and any
changes made to it will be lost.  So don't wast your time.

|> A simple alternative would be to keep track of the static data yourself
|> and access the port directly. I.e.:
|>
|> static cxLattice *output_lattice = NULL;
|>
|> void module_function()
|> {
|>     long	index;
|>
|>     /* Body of module */
|>
|>     index = cxOutputPortOpen( "Output_Lattice");
|>     cxOutputDataSet( index, output_lattice );
|> }
|>
|>
|> Jeff

In general, you can't (1) create and init a lattice (or any other
Explorer data type), (2) output that data, (3) modify the data, (4)
output again, etc.  This is because Explorer data is stored in shared
memory.  (Well, data isn't shared on a Cray, but you should write
portable module code, so you have to assume that it is shared.)

There is no way for you to know when downstream modules have consumed
the data you have previously sent.  In all probability they haven't, so
changing the *same* lattice you just sent will overwrite those modules'
input data, possibly *while they are reading it*.

That's why my previous post created a new lattice, with new data, for
each frame, but shared a single cxCoord among them all.

Remember: think shared.


author: Ulric Eriksson

subject: Re: Securing users from seeing directories w/o restricting program access

text:
In article <[email]>, Kevin  <[email]> wrote:

That is correct.

It won't.

Ulric


author: Bjorn Orizand

subject: Re: @home mail

text:
i would like to know what you did, i got the same problem!

"Arthur Ungar" <[email]> wrote in message
news:C9TR5.441153$[email]...
Outlook


author: Thomas. Stephenson

subject: Re: @home mail

text:
"Bjorn Orizand" <[email]> wrote in
<91cu97$q2d$[email]>:

The first thing that comes to mind is the tcp/ip time out.  Use the -z 32
commandline option to create the tcpip debug file.


author: Christopher Jahn

subject: Re: @home mail

text:
And it came to pass that Bjorn Orizand wrote:

In TOOLS|OPTIONS|SENDING MAIL, uncheck "allow 8-bit mime message
encoding"


author: Danny Backx

subject: Re: is a freeware Motif available under Linux?

text:
Paul Lisewski wrote:

Actually that's http://www.hungry.com/products/lesstif

	Danny


subject: Help on mouse in win3.1

text:
Hi friends,

	Got a problem here. It's like thithis.....

	I'm using a laptop with DOS6 & WIN3.1, my mouse seems
to work with any DOS based program but when I run WIN3.1 the mouse
vanishes. Only the "time-Icon" seems to come and then it goes to the
down left corner and doesn't seem to come up on the screen.

	I'm not sure what the problem is, maybe someething to do with
the "mouse-driver".

	Anyway please help me on this. Thanks !

Sunit ....


author: Saulius T. Kondrotas

subject: Re: Help on mouse in win3.1

text:
In article <[email]> ,
[email] writes:

Run windows setup again and choose the correct mouse driver for Windows.


author: Sven Knispel

subject: Re: Help on mouse in win3.1

text:
[email] wrote:
: Hi friends,

: 	Got a problem here. It's like thithis.....

: 	I'm using a laptop with DOS6 & WIN3.1, my mouse seems
: to work with any DOS based program but when I run WIN3.1 the mouse
: vanishes. Only the "time-Icon" seems to come and then it goes to the
: down left corner and doesn't seem to come up on the screen.

: 	I'm not sure what the problem is, maybe someething to do with
: the "mouse-driver".

If fact it seems to be the mouse driver you configured for Windows.
You should try to change it running Windows setup from DOS or windows.

Hope this helps.

 Sven


author: Gregory Shearman

subject: Another Gentoo for Australia!

text:
Pioneering chick arrives on coast

http://www.smh.com.au/queensland/pioneering-chick-arrives-on-coast-20111215-1ovo4.html

A pioneering chick has arrived on the Gold Coast and is set to attract
plenty of attention.

The Gentoo penguin hatched last week at Sea World - a first for the
theme park.

Senior penguin keeper Katrina Krygger said it would be two months before
the staff could determine whether it was a boy or a girl.

..........

It's good to see more gentoo in Australia.

--
Regards,
Gregory.
Gentoo Linux - Penguin Power


author: Homer

subject: Re: Another Gentoo for Australia!

text:
Verily I say unto thee that chris spake thusly:

That's good to know, however it's academic anyway, since I intend
feeding the HD audio and TOSLINK to an older AV amp without HDMI,
so I won't actually need HDMI audio at all. It may turn out to be
useful in the future though.

--
K.                           | "UNIX is basically a simple operating
http://slated.org            |  system, but you have to be a genius
Fedora 8 (Werewolf) on šky   |  to understand the simplicity"
kernel 2.6.31.5, up 206 days |     ~ Dennis Ritchie


subject: Re: Another Gentoo for Australia!

text:
On 2011-12-15, Frank The Wank <[email]> wrote:

That explains why you hang around here so much... you think we're all
gay!

Mystery solved.

--
Regards,
Gregory.
Gentoo Linux - Penguin Power


subject: Re: Flatish the closet gay

text:
On 2011-12-15, Frank The Wank <[email]> wrote:

... The lady doth protest too much, methinks!

--
Regards,
Gregory.
Gentoo Linux - Penguin Power


author: Hardon

subject: Flatish the closet gay

text:
On Thu, 15 Dec 2011 08:59:59 -0500, Frank The Wank wrote:

Oh look, the homophobic Gary Stewart, aka flatfish of the 1,000 nyms,
just can't miss an opportunity to expose his homosexuality. Come out
of the closet Gary. You know you want to.


subject: Re: Another Gentoo for Australia!

text:
On Thu, 15 Dec 2011 11:27:47 +0000, Gregory Shearman wrote:

Now who's going to explain the facts of life to the likes of Hadron,
snit, ...?


subject: Re: Flatish the closet gay

text:
Verily I say unto thee that Hardon spake thusly:

He does seem to know an awful lot on the subject, doesn't he?

Bigots are so transparent.

--
K.                           | "UNIX is basically a simple operating
http://slated.org            |  system, but you have to be a genius
Fedora 8 (Werewolf) on šky   |  to understand the simplicity"
kernel 2.6.31.5, up 206 days |     ~ Dennis Ritchie


subject: Re: Another Gentoo for Australia!

text:
Verily I say unto thee that chrisv spake thusly:

If only they could be the last of their vile breed, but alas vermin
always seem to be the most resilient.

--
K.                           | "UNIX is basically a simple operating
http://slated.org            |  system, but you have to be a genius
Fedora 8 (Werewolf) on šky   |  to understand the simplicity"
kernel 2.6.31.5, up 206 days |     ~ Dennis Ritchie


subject: Re: Another Gentoo for Australia!

text:
Verily I say unto thee that Gregory Shearman spake thusly:
[...]

Lulz.

I've got more Gentoo here too. I just fired up my new AMD Fusion box
with the Gentoo 11.2 Live DVD (still waiting for the HDDs).

Oh, and yeah, everything "just works" (although apparently I need to
use the proprietary fglrx driver to get audio over HDMI, for now).

--
K.                           | "UNIX is basically a simple operating
http://slated.org            |  system, but you have to be a genius
Fedora 8 (Werewolf) on šky   |  to understand the simplicity"
kernel 2.6.31.5, up 206 days |     ~ Dennis Ritchie


author: Frank The Wank

subject: Re: Another Gentoo for Australia!

text:
On 15 Dec 2011 11:27:47 GMT, Gregory Shearman wrote:

That's because penguins have a propensity toward homosexuality.
Another reason why the Penguin is the perfect mascot for Linux
because so do Linux users!


author: William Poaster

subject: Re: Flatish the closet gay

text:
On Thu, 15 Dec 2011 16:40:41 +0000, Hardon wrote:

As sh/h/it is a wintroll, perhaps they should join the gay website
"Gay.com" that Bill Gates invested in. After all, they worship everything
else M$ does:

Bill Gates Among Investors with $26 Million Share in Homosexual Activist
Publishing Company.
http://beforeitsnews.com/story/392/886/Bill_Gates_and_the_Pansexual_Agenda.html

And as the wintrolls are *so* fond of telling us, that Windows has 95% of
desktops usage, it's *most* likely that the *majority* of the gay
community use that OS.
The stupid wintroll kinda shot itself in the foot there.


subject: Re: Flatish the closet gay

text:
On 15 Dec 2011 16:40:41 GMT, Hardon wrote:

Yet you, Roy Culley, are the one who feels the need to start a new
thread about your gayness.
You're already out of the closet, but like most homosexuals, you are
always on the move seeking new partners.

http://abcnews.go.com/blogs/technology/2011/12/toronto-zoos-gay-penguins-attracted-to-new-female-partners/

http://emperor-penguin.com/gay-penguins.html


author: chrisv

subject: Re: Another Gentoo for Australia!

text:
Hardon wrote:

Hopefully no one.  As long as they stick to circle-jerks and
leg-humping, they will not reproduce.


subject: Re: Flatish the closet gay

text:
On Thu, 15 Dec 2011 17:17:35 +0000, Homer wrote:

What's to know?
Sticking a penis up another man's ass is not normal.
It's disgusting.

And homosexual behavior is repulsive.


author: chris

subject: Re: Another Gentoo for Australia!

text:
Homer wrote:

...

Just use some development versions:

http://zajec.net/blog/view/2011-evergreen-hdmi-audio

http://lists.freedesktop.org/archives/dri-devel/2011-December/017098.html


author: Foster

subject: Re: Another Gentoo for Australia!

text:
On Thu, 15 Dec 2011 13:32:54 +0000, Homer wrote:

Hypocrite.

--
foster


author: sutaka

subject: Re: "chrisv" turd gives "Hardon" Another leg-hump and jerk-off!

text:
dog shit "chrisv" <[email]> wrote in message
news:[email]...

the leg humping and circle jerks a turd like you does with "Hardon" is tough
to beat.

a turd like you and "Hardon" who you love to slurp are the queens of jerking
off.

"chrisv" is a liar. "chrisv" is a piece of shit.


author: [redacted]

subject: networking

text: can you use a router to build a network or do you have to have a hub


author: Alex Taylor

subject: Re: networking

text:
On Mon, 29 Jan 2001 19:30:06 -0000, [email] <[email]> wrote:

Generally you need a hub.
(Although it's possible to get by without under certain configurations,
e.g. using BNC+coax media instead of RJ-45+twisted pair).

A router (which is much more complicated and expensive a piece of
machinery) is for connecting two or more networks (or network segments)
together.  Many routers are also hubs, of course.

But your question can't really be answered properly unless you describe
what KIND of network you're trying to set up, i.e. what is it for and how
will it be used?


author: Erick Andrews

subject: Re: networking

text:
On Mon, 29 Jan 2001 19:30:06, <[email]> wrote:

Actually, you don't need either one if you want to go with Thin Wire Ethernet
(Coaxial cable, RJ 58/U, with 10BASE2 connectors and NIC's).  It's a
lot cheaper and gives you a couple dozen stations "daisy chained" along
600+ feet of cable.

It's my choice, but I'm biased because I did some original development
on Ethernet before shielded and unshield twisted pair came along.

If you decide to go this route, get good cable, at least 90% braid coverage.


author: Clive Dove

subject: Re: networking

text:
If you are using a 4 port or 8 port router such as the LinkSys BEFSR41
or BEFSR81, it includes a built-in hub.
The one port version (BEFSR11) does not include a hub so if you want to
connect more than one machine to it, you will need to use a hub
connected to its LAN port.
The difference in price between the 1 port router and the 4 port hub is
small enough that I would use the 4 port router even if my system had
only one computer.
You can build a network using terminated thin coax cable and ethernet
cards with thin coax connectors, but the proce of routers or passive
hubs are sufficiently  low that it is not worth the effort.  Also, it is
much easier and cheaper to get ethernet cards with RJ45 connectors than
those with coax connectors.

On Mon, 29 Jan 2001 19:30:06, <[email]> wrote:


subject: Re: networking

text:
Hardware routers once were expensive and complicated, but no longer.
Several companies are providing 4 port routers at prices between
US$100.00 and US$150.00
I am using the LinkSys 4 Port Cable/DSL Router (BEFSR41).
It is a delight to set-up using my Netscape to access its firware.
Usually it simply involves connecting it in between the broadband modem
and one of your computers, accessing its local ip address and answering
a few questions.  If your service provider is using DHCP, the defaults
are already set up for it. If PPPoE, you will have to choose PPPoE and
answer 2 questions.  You can then add computers by simply plugging them
in and letting the router's DHCP daemon assign them local ip addresses.

I am told the Dlink router is also very easy to use.

At the prices of routers these days, it is simply no longer worth the
trouble to set up one of your computers to act as a router.

On Tue, 30 Jan 2001 15:08:08, [email] (Alex Taylor)
wrote:


author: Al Savage

subject: Re: networking

text:
On Mon, 29 Jan 2001 20:00:54, [email] (Erick Andrews) wrote:

10base2 (daisy chain topology) is nice if you've only got a couple of
computers, or you have a *really* tight budget.  In the past, 10baseT
hubs were not inexpensive, and even a low-end four-port could run
several hundred dollars, so going 10base2 made a lot of sense.  The
downsides: a break in any segment of the cable takes the whole network
down.  If you move a box that's in the "middle" of the chain, you have
to run two sets of cable to it, which doubles the line length change.

10baseT hubs (star topology) are now very cheap.  Good hubs can
partition/exclude a port connected to a malfunctioning node, isolating
it and allowing the rest of the network to continue normal ops.  Moving
a box does not affect other boxes' cabling, and a broken cable or cable
connection does not affect other nodes.


subject: Re: networking

text:
On Tue, 30 Jan 2001 16:24:36 GMT, Clive Dove <[email]> wrote:

The only one I've seen for sale in Canada was the LinkSys one at $300 Cdn.


subject: Re: networking

text:
I don't disagree with you, provided you have an old 486 box lying
around.

Additionally, you can select the Server installation option when
installing Linux.   It will occupy the whole drive but is explicitly
configured as a server so most of the set-up work is done for you.

Still, plugging in a LinkSys router and using its DHCP daemon to assign
ip addresses is much simpler for the average home user.

Remember that whatever box you use as a router will have to be kept
running 24/7 and dedicated so that any machine on the private net can
use it at any time.  If you are using the same box for other purposes,
you are sacrificing speed and capacity on that box.

On Wed, 31 Jan 2001 15:20:29, [email] (Alex Taylor)
wrote:


subject: Re: networking

text:
On Wed, 31 Jan 2001 17:48:36 GMT, Clive Dove <[email]> wrote:

True.

Actually, what I did for my parents was this:

 - I had some old 486 parts lying around, mostly acquired in bargain bins
   at parts stores.  I managed to assemble them into a working PC - no
   case, just the boards, drives, and a bare power supply sitting on a
   shelf under the desk.  :)

 - I installed a spare copy of Warp Connect on it.  (People keep giving me
   copies of OS/2... it's uncanny.)

 - I bought a Netgear home network kit - two NE2000 ISA cards and a
   four-port hub for about $70 Cdn.

 - I bought a license to InJoy Firewall for about the same price.

 - Set it all up, installed Warp Connect, latest FixPaks, InJoy, plugged
   the cable modem into one NIC, the hub into the other, their Win98 PC
   into the hub, turned it on, and told them "Congratulations, you're now
   protected by a firewall."

Since I already had the parts (I can be a bit of a pack rat when it comes
to computer parts, I'm afraid), total cost was probably under $150 Cdn.

I chose an OS/2 solution for them rather than Linux (which is what I use
myself) because if they ever have to go into that machine or reboot it,
OS/2 is far easier.  (I also had that spare copy of Warp Connect sitting
around looking lonely, so I thought I'd put it to good use.)  Also, fewer
crackers probably know how to break into an OS/2 box...

However, I would have recommended the LinkSys all-in-one if they'd been
setting it up themselves.  Indeed, I considered it anyway, but since I was
paying, the price was a bit steep.

Still, it's just a few circuit boards sitting on a shelf with some cables
running out; they keep it up all the time and are barely aware of it,
AFAIK.  The only significant potential problem is that the cat might start
playing with the network cables where they emerge...


author: Bruce M. Axtens

subject: Compiler?

text:
G'day everyone

Has there ever been a Logo compiler? One capable of being used to write
standard DLLs and even COM DLLs?

Kind regards,
Bruce.

-- Posted on news://freenews.netfront.net - Complaints to [email] --


author: Brian Harvey

subject: Re: Compiler?

text:
"Bruce M. Axtens" <[email]> writes:

Here you go:

http://liogo.sourceforge.net/


subject: Re: Compiler?

text:
On Mon, 18 Aug 2008 04:59:22 +0000 (UTC), Brian Harvey wrote:

Thanks, Brian, very much.

Bruce.

-- Posted on news://freenews.netfront.net - Complaints to [email] --


author: Jack Trades

subject: Boehm GC - undefined reference to `GC_malloc'

text:
I've been having some problems using the Boehm Garbage Collector.
Initially I tried...
#include "gc.h"

which failed with a "No such file or directory".  After a bit of
playing around I got it to work with...

#include "/usr/include/gc/gc.h"

While GC_INIT() works now but I get the following error when I try to
use GC_MALLOC or GC_malloc...

/tmp/cc9TT8nq.o: In function `alloc_object':
lispy.c:(.text+0xe): undefined reference to `GC_malloc'
...

I'm using Ubuntu 10.04 and libgc (however it also happens when I
compile the source from http://www.hpl.hp.com/personal/Hans_Boehm/gc/)

Thanks
Jack Trades


author: Keith Thompson

subject: Re: Boehm GC - undefined reference to `GC_malloc'

text:
August Karlstrom <[email]> writes:

Here's the example from upthread that I presume you're referring to:

#include <stdio.h>
#include <gc/gc.h>

void read(void)
{
        char *s;

        puts("read()");
        s = GC_malloc(32);
}

int main(void)
{
        read();

        return 0;
}

It's not 100% clear what "if libgc did include the prototype for
`read' in unistd.h" means.  I presume you mean "if the C source
file that implements part of the gc library and calls read() has
a #include <unistd.h> directive".

In fact, the relevant source file happens to be pthread_support.c,
(which contains the definition of GC_get_nprocs(), which calls read()),
and that source file *does* have a #include <unistd.h>.

No, that doesn't imply that *your* code would get a compilation
error.  Your program and pthread_support.c are compiled separately;
neither directly affects the other.  If there were a #include
<unistd.h> in <gc/gc.h>, then that would affect the compilation of
your source file -- but there isn't.

The problem is this: Your source file depends on gc, which depends
on POSIX.  Your source file defines and uses a function named "read".
POSIX defines another function named "read", and gc calls it.
You've linked together your own object file (generated by compiling
your source file), the gc library, and the POSIX library (probably
part of your system's libc) into an executable, which doesn't work
properly because of the conflicting "read" functions.

The C standard says very little about what happens when you do
something like this (I'm fairly sure the behavior is undefined),
and it's up to you to avoid the problem.  C doesn't provide a way to
have support functions with the same name, and it doesn't require
the implementation to tell you when you've tried to use two such
functions within a program.  If you're lucky, the linker might warn
you about it, but in this case you weren't lucky.


text:
Ian Collins <[email]> writes:

That doesn't help in this case; the function causing the problem is
read(), which isn't in the implementation-reserved namespace.

August's program uses Boehm's GC; it does not intentionally use
POSIX.  But Boehm's GC apparently depends on POSIX *internally*
(it calls read()).  The name quietly leaks from POSIX, to GC,
to the program, because names visible to the linker are all in
one namespace.

It would be nice to be able to avoid this kind of thing (other than
by knowing all the external names in all the libraries you're using,
*either directly or indirectly*).  But C doesn't provide any such
mechanism, and typically implementations seem not to do so either.
That's a great pity, IMHO.

Unless there's some trick I'm missing.  Anyone?

[...]


author: Ben Bacarisse

text:
"BartC" <[email]> writes:

<snip>

No, though there is no reason why some packaging of gcc might not
include it.  It is entirely separate on my Linux system.

<snip>


text:
August Karlstrom <[email]> writes:

Prototypes are visible to the compiler, not to the linker.  The linker
just sees symbols.  The details are *extremely* system-specific.

A POSIX-conforming implementation does provide a prototype for read (in
<unistd.h>).


text:
August Karlstrom <[email]> writes:

Your read() calls GC_malloc(), which calls (via several intermediate
functions) GC_get_nprocs(), which attempts to call the POSIX read().
Apparently, since you've defined your own read() function, it calls that
instead.  (I found this out by running your program under gdb and
getting a stack trace.)

More generally, even if you compile your own code in
standard-compliant mode, that doesn't affect any library code
your program uses.  If your program includes a library that calls
read(), one possibly consequence is that it will call your own
read() function.


text:
Thanks again for all the help.  I put together a minimal example and
found that renaming my 'read' procedure stopped the segfaults.
Apparently it was a namespace issue, but I can't find 'read' defined
in the gc source anywhere.

I'm still getting used to the single namespace of C.  Is there any
utility that will print all the identifiers both defined and imported
in a particular C program?

Thanks
Jack Trades


text:
Jack Trades <[email]> writes:

read() is a POSIX-defined input function.  On Unix-like systems, it's
typically part of the standard library that's loaded by default.

The consequences of defining your own function with the same name
are likely to vary depending on which headers you include and/or
which compiler/linker options you use.  A trivial example I just
tried worked (I named a function "read" and was able to call it),
but I can easily imagine that there might be circumstances where
what appears to be a call to your own read() function instead calls
the system-defined function, or vice versa.

If you specify C standard conforming mode it shouldn't be an issue,
but then you might not be able to use gc.

[...]


text:
Thanks for the replies.  I'm leaving for vacation soon so I'll work on
getting a minimal example this weekend.

Thanks again for the help,
Jack Trades


text:
On Sep 30, 7:15 pm, "BartC" <[email]> wrote:

That's exactly what it was.

Actually refcount is never used.  As for the free() calls, there are
none.  This is my first project with C and only the 3rd interpreter
I've ever written so I wanted to keep it simple and did no memory
management.

I'm not sure exactly what you mean here.  It was my understanding that
union meant "only one of these".  Here's an example of the fixnum
constructor that is used in the code...

object *make_fixnum(long value) {
  object *obj;

  obj = alloc_object();
  obj->type = FIXNUM;
  obj->data.fixnum = value;
  return obj;
}

So I don't think I'm relying on any zero fields.  Though, honestly, I
don't have enough experience with C to know.


text:
Jack Trades <[email]> writes:

Let me draw your attention to BartC's remark in parentheses: "unless
things have already gone badly wrong".  The code you show where you
think the crash happens is very simple.  It is overwhelmingly likely
that the error is somewhere else entirely.  A write through some
indeterminate pointer or an out-of-bounds access or any of the other
pitfalls of C could result in a subsequent allocation failing in the way
you report.

Unless there is a likely candidate (i.e. some code you already have
doubts about) showing selected part of the program probably won't help.
I'd suggest two ways forward:

(a) Use a memory access checker like valgrind.  I don't know how well it
works with GC_MALLOC but you can always arrange for GC_MALLOC to be a
macro that expands to plain malloc.  I can't praise this program highly
enough.

(b) Start to cut down the program until you have a minimal example.
This may be hard because there are cases where it is a sequence of
actions following the original error that provokes the crash.  Removing
any one of them can "fix" the problem but that does not mean the error
is in code you have just cut.  The purpose is only to get the smallest
thing you can so the task of finding the error becomes simpler.

<snip>

It's possible but far more likely that something has gone wrong before
this and the problem only shows up when an allocation is made.

<snip>


text:
Jack Trades <[email]> writes:

The #include directive just tells the compiler where to find the
header that tells it what declarations are available.  It doesn't
tell the linker where to find the code that actually implements
the functionality.  (So why isn't this a problem for most of the
language-defined library?  Because the files containing the code that
implements the standard C library are typically loaded by default.)

The documentation for Boehm GC should tell you how to do this.
On my system, "man GC_malloc" includes a good synopsis at the top
of the page:

    SYNOPSIS
       #include <gc.h>
       void * GC_malloc(size_t size);
       void GC_free(void *ptr);
       void * GC_realloc(void *ptr, size_t size);

       + cc ... -I/usr/include/gc -lgc

The details might vary depending on your system.


author: August Karlstrom

text:
On 2010-09-27 20:17, Jack Trades wrote:

You only need

#include <gc/gc.h>

as /usr/include is in the default include path.

You need to link with the garbage collector by adding -lgc to the gcc
command, e.g.

gcc test.c -lgc

/August


text:
On 2010-10-05 20:40, Keith Thompson wrote:

This is interesting as there is generally no way I could possibly know
of every identifier in the global namespace.

This means I have lost the intellectual control over the program. In my
humble opinion it is a serious flaw in the C language/compiler strategy.

Anyway, thanks Keith for the thorough explanation.

/August


author: Ian Collins

text:
On 10/ 6/10 10:40 AM, Keith Thompson wrote:

I don't think there is.  Another unfortunate trap for the unwary.  The
only standard tool we have is static symbols.

It isn't only C that has this problem, I have bumped into it with C++ as
well.


text:
On 2010-10-05 17:35, Keith Thompson wrote:

OK, so if libgc did include the prototype for `read' in unistd.h I would
get a compilation error with my example.

/August


text:
On 2010-10-05 01:51, Keith Thompson wrote:

Is this caused by the library (libgc in this case) not providing a
prototype for the POSIX function `read'? If it did, a conflict would be
detected by the linker, right?

/August


author: Barry Schwarz

text:
On Sun, 3 Oct 2010 19:41:27 -0700 (PDT), Jack Trades
<[email]> wrote:

The get unused to it.  There are at least four distinct name spaces in
C.  See 6.2.3 for the details.


text:
On 2010-10-04 05:29, Keith Thompson wrote:

I noticed some strange behaviour too with the following test:

$ cat test.c
#include <stdio.h>
#include <gc/gc.h>

void read(void)
{
	char *s;

	puts("read()");
	s = GC_malloc(32);
}

int main(void)
{
	read();

	return 0;
}
$ gcc -Wall -Wextra -ansi -pedantic -O3 test.c -lgc
$ ./a.out
read()
read()

The program outputs `read()' twice and doesn't terminate. What is happening?

/August


author: BartC

text:
"Jack Trades" <[email]> wrote in message
news:[email]...

To summarise then:

You have a program (some sort of interpreter) which works when using
malloc() (and doesn't use free()), but doesn't work when you replace
malloc() by GC_MALLOC().

You think the error is in or around an actual call to GC_MALLOC(). Yet a
simple test program calling GC_MALLOC() once, works. (Perhaps do an extra
check, using 24 instead of 3 (note sizeof(char) is always 1), and repeat the
call in a loop, say a million times, before printing the result.)

Hmm.. I've never used GC either (nor debuggers) and don't have any ideas,
except I would try and pinpoint the exact point of failure. I might try
something like the following:

void* test_malloc(int size) {  /* Forget size_t for this test */
 void* p;
 printf("Calling GC_MALLOC(%d) => ",size);
 p=GC_MALLOC(size);
 printf("%X\n",(int)p);
 return p;
}

and use test_malloc() in place of GC_MALLOC(). This will then show you how
after how many calls GC_MALLOC will fail, and whether it crashes during the
call or not. (Probably a debugger could tell you this too given the right
commands..)

If this goes wrong after many millions of calls though it makes it tricky.
(In this case, perhaps insert a static counter inside test_malloc and only
display the debug code after it's already done a million or whatever calls.)


text:
"Keith Thompson" <[email]> wrote in message
news:[email]...

If this GC supposed to be a standard part of gcc?

On my Mingw gcc 4.5 (which I've just upgraded from 3.4.5 because it didn't
have _make_), there's no trace of it. Yet some other Windows C compilers
seem to have it.