Re: Non-declared Variables

"Wolfram Fenske" <int2k@gmx.net>
17 Oct 2006 01:05:37 -0400

          From comp.compilers

Related articles
Non-declared Variables acampbellb@hotmail.com (Avatar) (2006-10-16)
Re: Non-declared Variables int2k@gmx.net (Wolfram Fenske) (2006-10-17)
Re: Non-declared Variables gnorik@gmail.com (2006-10-24)
Re: Non-declared Variables Peter_Flass@Yahoo.com (Peter Flass) (2006-10-26)
Re: Non-declared Variables pjb@informatimago.com (Pascal Bourguignon) (2006-10-28)
Re: Non-declared Variables ArarghMail610@Arargh.com (2006-10-28)
Re: Non-declared Variables genew@ocis.net (Gene Wirchenko) (2007-01-28)
| List of all articles for this month |

From: "Wolfram Fenske" <int2k@gmx.net>
Newsgroups: comp.compilers
Date: 17 Oct 2006 01:05:37 -0400
Organization: Compilers Central
References: 06-10-064
Keywords: design
Posted-Date: 17 Oct 2006 01:05:37 EDT

"Avatar" <acampbellb@hotmail.com> writes:


> I would like to hear people's opinions on the ability to use variables
> without declaring them in dynamic languages like Ruby.
>
> It would seem to me that an argument for non-declared local variables
> that typically occupy a small scope could be made. But, class
> variables? What is the benefit in allowing for runtime definition of
> class variables?
>
> Are there real tangible benefits that non-declared, dynamically typed
> (at binding time) variables provide? Or do dynamic variables simply
> create less compile time errors and more (harder to catch) runtime
> errors?
>
> Thoughts?


You could use this to support functionality that resembles the factory
pattern. Instead of writing a bunch of boiler plate code, you supply
a description of the class you want to create and the factory method
takes care of defining the actual attributes and methods of the class.
Plone, a web-based content management framework written in Python does
that. Here's an example (sorry if it's a bit long):


--8<---------------cut here---------------start------------->8---
# -*- coding: iso-8859-1 -*-
#
# $Id: ECQBaseQuestion.py,v 1.2 2006/08/14 11:39:14 wfenske Exp $
#
# Copyright 2004 Otto-von-Guericke-Universitt Magdeburg
#
# This file is part of ECQuiz.
#
# ECQuiz is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# ECQuiz is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with ECQuiz; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA


[...] (snipped imports)


class ECQBaseQuestion(ECQFolder):
        """ A very basic question type without any evaluation functions.


                A question is basically a question text and a set of possible
                answers to this question or, in Plone terms, a folder with
                some additional properties such as the question text.
        """


        schema = ECQFolder.schema.copy() + Schema((
                        StringField('title',
                                required=False,
                                searchable=True,
                                default='Question',
                                widget=StringWidget(
                                        label_msgid='label_title',
                                        description_msgid='title',
                                        i18n_domain='plone'),
                                read_permission=PERMISSION_STUDENT,
                        ),
                        InlineTextField('question',
                                searchable=True,
                                required=True,
                                primary=True,
                                allowable_content_types=('text/plain',
                                        'text/structured',
                                        'text/restructured',
                                        'text/html',),
                                default_output_type='text/html',
                                widget=TextAreaWidget(
                                        label='Question',
                                        label_msgid='question_label',
                                        description='The question text. This is what the '
                                        'candidate will see.',
                                        description_msgid='question_tool_tip',
                                        i18n_domain=I18N_DOMAIN,
                                        rows=10,
                                        ),
                                validators=('isXML',),
                                read_permission=PERMISSION_STUDENT,
                        ),
                ),
        )


        # Use a custom page template for viewing.
        suppl_views = None
        default_view = immediate_view = 'ecq_basequestion_view'


        aliases = updateAliases(ECQFolder, {
                'view': default_view,
                })


        # This prevents the Questions from showing up as a portal content
type
        global_allow = False
        # Only Answer objects may be put into this folder.
        allowed_content_types = (ECQBaseAnswer.portal_type,)


        meta_type = 'ECQBaseQuestion' # zope type name
        portal_type = meta_type # plone type name
        archetype_name = 'Base Question' # friendly type name


        content_icon = 'ecq_question.png'


        security = ClassSecurityInfo()


        #security.declareProtected(PERMISSION_INTERROGATOR,
'contentValues')
        #security.declareProtected(PERMISSION_INTERROGATOR,
'listFolderContents')
        # Declaring "folderlistingFolderContents" as protected prevents
        # the answers from being listed if someone without
        # PERMISSION_INTERROGATOR tries to call the "base_view" template
        # for a question.
        security.declareProtected(PERMISSION_INTERROGATOR,
                                                            'folderlistingFolderContents')


        security.declareProtected(PERMISSION_STUDENT, 'UID')


        security.declarePrivate('makeNewTest')
        def makeNewTest(self, candidateResult, suMode):
                """generate a new quiz"""
                # This is just to register the question with result object
                candidateResult.setSuggestedAnswer(self, None)




        security.declareProtected(PERMISSION_STUDENT,
'haveCandidateAnswer')
        def haveCandidateAnswer(self, result):
                """
                @param result A Result object
                """
                return result.haveCandidateAnswer(self)


# Register this type in Zope
registerATCTLogged(ECQBaseQuestion)
--8<---------------cut here---------------end--------------->8---


The important part is the "schema" attribute of the class. It is the
main definition of the class. When this class definition is
registered in the system (via "registerATCTLogged") it gets new
instance attributes called "title", "question" and the corresponding
getters and setter, "getTitle", "setQuestion" etc., among other
things. Plone is a web-based CMF, so instances of this class can be
displayed in a browser. The way it'll look is also defined in the
schema. E. g., when you edit the "question" attribute, a
"TextAreaWidget" with 10 rows will be used and the input will be
validated using the "isXML"-validator (which is imported from another
file). There is other stuff I could explain, but I think you get the
idea.


IMO this is way better and less error-prone than having to write lots
of boring code by hand. But I have a hunch that it is mostly a
work-around for Python's lack of Lisp-style macros. I havn't
completely thought this through but the idea is this: the class
definition is in fact known statically, it just doesn't follow
Python's syntax. In Lisp I could write a macro that tranforms the
schema-syntax into a class definition that Lisp understands. This
transformation could happen at compile-time. But Python doesn't have
a macro mechanism so the transformation has to be done at runtime, by
dynamically adding attributes and methods. If Python didn't allow
that, Plone's schema-mechanism would probably be impossible to
implement. There may be other scenarios where adding attributes and
methods to classes at runtime would be useful, ones that can't be
covered by Lisp macros, but I havn't encountered them so far (which
doesn't say much). Maybe somebody else knows an example.




Wolfram


Post a followup to this message

Return to the comp.compilers page.
Search the comp.compilers archives again.