From Robert.McGehee at geodecapital.com  Fri Jan 14 19:09:03 2005
From: Robert.McGehee at geodecapital.com (McGehee, Robert)
Date: Fri Jan 14 19:09:15 2005
Subject: [Rd] RE: [R] as.character methods
Message-ID: <67DCA285A2D7754280D3B8E88EB5480206741E16@MSGBOSCLB2WIN.DMN1.FMR.COM>

Thank you for your replies. I greatly appreciate the wealth of
documentation on this subject and the time spent by the John Chambers
and the R Core Team making object-orient programming in R a reality. I
hope to be able to give code (not just bug reports) back to the R
community as my projects advance.

I hoping to generalize my as.character question to a real-life
as.character / print method example that is causing more problems than
I'd like to admit, and that I hope I could get feedback from.

Briefly, I'm looking to extend the "name" class into a new class I call
"newName" which performs just as "name" does except that when a
"newName" object is printed that has been initialized without a value,
it prints NULL to the screen instead of `<UNDEFINED>`. I chose the
"name" class as I am using extensions of name, call, and expression to
create syntactically correct R expressions that are then parsed by a
non-R parser. Thus I want to be able use R to check for syntax and
"translate" code from one language into another.

My problem is that I have been unable to make the print method work
correctly on the "name" class, despite success for other classes, and my
best implementation only sometimes works (sometimes it prints, sometimes
it errors out). The below code produces the behavior that the first time
we try to print the object we get an error, the second time it prints
correctly, and the third and fourth time it prints, but without quotes.
To run the following code to reproduce my problem, you may need to
restart R to see exactly the same behavior that I am seeing on Windows /
Linux 2.0.1. As always, I'd appreciate any help in creating this method,
or comments on my approach, as I effectively want to hide the
`<UNDEFINED>` initialization of this new object.

######################
## First create the class as extension of "name"
setClass("newName",
         representation("name"))

## Write a generator function for this class
newName <- function(value) {
    if (missing(value) || is.null(value))
      x <- new("name")
    else
      x <- as.name(value)
    class(x) <- "newName"
    x
}

## as.character method for printing:
as.character.newName <- function(x, ...) {
    ## If x is the same as an uninitialized "newName" object, then
return NULL
    if(x == new("newName"))
      return(NULL)
    else
      as.character(as.name(x))
}

## The print method should just reference the 
## as.character method
print.newName <- function(x, ...) {
    as.character(x, ...)
}

## Now create the object.
a <- newName("abc")
## Thus "a" has class of "newName" and holds the symbol `abc`

############
## Now let's try to look at this object using print()
############
> a
Error in print(abc) : Object "abc" not found
## Fails! Let's try calling print() explicitly

> print(a)
[1] "abc"
## That worked, let's try looking at the object again

> a
abc
## This time it printed! (without the quotes)

## Let's try printing the object again
> print(a)
abc 
## Again, printed without the quotes

If I create formal methods for print, show, and/or as.character, I still
have similar problems, and in no case can I get this to work
(consistently at least). Should I abandon trying to extend the "name"
class at all? Or is there some problems in my code above that would
cause this behavior. I have not had any similar trouble when extending
the "call" and "expression" classes, and apologies for the technical
nature of this post.

Thanks,
Robert


-----Original Message-----
From: John Chambers [mailto:jmc@r-project.org] 
Sent: Friday, January 14, 2005 10:36 AM
To: Prof Brian Ripley
Cc: McGehee, Robert; r-devel@stat.math.ethz.ch
Subject: Re: [Rd] RE: [R] as.character methods




Prof Brian Ripley wrote:
 > Please use R-devel not R-help for esoteric programming questions: I
have
 > moved this there.  [See the posting guide.]  Anything involving the
 > methods package is definitely not for R-help: I doubt if 1% of the
 > readership of R-help have knowingly used it.

I believe the general guidelines for what goes in r-help and what in 
r-devel are clear enough without actively discouraging discussion of 
classes and methods.  It's the nature of the question, not a litmus test

for discussing this or that package that is the helpful distinction.


....

>         if (is.primitive(baseDef)) {
>             value <- genericForPrimitive(f)
> 
> and it seems John Chambers has defined an S4 generic for as.character 
> with one arg, "x".  Had he not done so it would have been (x, ...).
My 
> guess is that this is because in S the arg list is (x) and he
overlooked 
> that it was not in R, but only he knows.

Well, let's say that he usually implemented the S4 generics for 
primitives assuming R might follow the description in the Blue Book. 
Further checking against the R online documentation was done, but 
obviously not often enough.  Life is, however, short.

No intention to create incompatibility between the S4 generic and S3 
code in this case, we should fix that.

There are some cases in which the generic needs extra named arguments to

allow sensible methods, for example "[".  I can't think of any case 
where one would intentionally have _fewer_ arguments in the generic.

> 
> 
> 
......


[Rd] RE: [R] as.character methods
McGehee, Robert