I can use get to get primitive function, like:
get('$')
.Primitive("$")
However, mget failed:
mget('$')
Error: value for ‘$’ not found
Why? How to fix this?
The default for get is to use inherits = TRUE (I think, based on the docs, for historical reasons), while the default for mget is inherits = FALSE. So using inherits = TRUE should make it work like get.
If you'd like a really detailed (but also very very good) dive into exactly what's happening here read this. Or just skip to the "Map of the World" section, and remember that $, being a primitive function, is in the environment of the of the base namespace (package:base, essentially).
Related
I am new to Julia, so this might be trivial.
I have a function definition within a module that looks like (using URIParser):
function add!(graph::Graph,
subject::URI,
predicate::URI,
object::URI)
...
end
Outside of the module, I call:
add!(g, URIParser.URI("http://test.org/1"), URIParser.URI("http://test.org/2"), URIParser.URI("http://test.org/1"))
Which gives me this error:
ERROR: no method add!(Graph,URI,URI,URI)
in include at boot.jl:238
in include_from_node1 at loading.jl:114
at /Users/jbaran/src/RDF/src/RDF.jl:79
Weird. Because when I can see a matching signature:
julia> methods(RDF.add!)
# 4 methods for generic function "add!":
add!(graph::Graph,subject::URI,predicate::URI,object::Number) at /Users/jbaran/src/RDF/src/RDF.jl:29
add!(graph::Graph,subject::URI,predicate::URI,object::String) at /Users/jbaran/src/RDF/src/RDF.jl:36
add!(graph::Graph,subject::URI,predicate::URI,object::URI) at /Users/jbaran/src/RDF/src/RDF.jl:43
add!(graph::Graph,statement::Statement) at /Users/jbaran/src/RDF/src/RDF.jl:68
At first I thought it was my use of object::Union(...), but even when I define three functions with Number, String, and URI, I get this error.
Is there something obvious that I am missing? I am using Julia 0.2.1 x86_64-apple-darwin12.5.0, by the way.
Thanks,
Kim
This looks like you may be getting bit by the very slight difference between method extension and function shadowing.
Here's the short of it. When you write function add!(::Graph, ...); …; end;, Julia looks at just your local scope and sees if add! is defined. If it is, then it will extend that function with this new method signature. But if it's not already defined locally, then Julia creates a new local variable add! for that function.
As JMW's comment suggests, I bet that you have two independent add! functions. Base.add! and RDF.add!. In your RDF module, you're shadowing the definition of Base.add!. This is similar to how you can name a local variable pi = 3 without affecting the real Base.pi in other scopes. But in this case, you want to merge your methods with the Base.add! function and let multiple dispatch take care of the resolution.
There are two ways to get the method extension behavior:
Within your module RDF scope, say import Base: add!. This explicitly brings Base.add! into your local scope as add!, allowing method extension.
Explicitly define your methods as function Base.add!(graph::Graph, …). I like this form as it more explicitly documents your intentions to extend the Base function at the definition site.
This could definitely be better documented. There's a short reference to this in the Modules section, and there's currently a pull request that should be merged soon that will help.
In many cases being aware of missing data is crucial and ignoring them can seriously impair your analysis.
Therefore I'd like to set the useNA = "ifany" as default for table(). Ideally similar to options(stringsAsFactors = FALSE)
I found an ugly hack below, but it must go better and without defining a function.
https://stat.ethz.ch/pipermail/r-help/2010-January/223871.html
tableNA<-function(x) {
varname<-deparse(substitute(x))
assign(varname,x)
tabNA<-table(get(varname),useNA="always")
names(attr(tabNA,"dimnames"))<-varname
return(tabNA)
}
Well you do need to define a function1 but you can reuse the existing name (and make the definition much leaner):
table = function (..., useNA = 'ifany') base::table(..., useNA = useNA)
This will make the new functionality available under the old name – but only in your code, so it’s “safe” (i.e. it doesn’t change packages’ use of table).
We use ... to allow arbitrary arguments to be passed, and we give useNA the desired default value of 'ifany'. Inside the function, we just call the “real” table function. But in order to avoid calling ourselves, we specify the namespace in which it’s found: base. And we just pass all the arguments untouched.
1 Just look at the source code of table – it doesn’t query any option in setting the argument, so there can be no way of determining the setting of that argument via an option.
Suppose I have a function that has multiple returned values (shown below). However, this output is not informative as users do not know what each value stands for unless they look up the function definition. So I would like to use println() to print the results with appropriate names to the screen, while suppressing the the actual returned values from being printed on the screen. In R, the function invisible() does that, but how do you do the same thing in Julia?
function trimci(x::Array; tr=0.2, alpha=0.05, nullvalue=0)
se=sqrt(winvar(x,tr=tr))./((1-2.*tr)*sqrt(length(x)))
ci=cell(2)
df=length(x)-2.*floor(tr.*length(x))-1
ci=[tmean(x, tr=tr)-qt(1-alpha./2, df).*se, tmean(x, tr=tr)+qt(1-alpha./2, df).*se]
test=(tmean(x,tr=tr)-nullvalue)./se
sig=2.*(1-pt(abs(test),df))
return ci, tmean(x, tr=tr), test, se, sig
end
In addition to what Harlan and Stefan said, let me share an example from the ODBC.jl package (source here).
One of my favorite features of Julia over other languages is how dead simple it is to create custom types (and without performance issues either!). Here's a custom type, Metadata, that simply holds several fields of data that describe an executed query. This doesn't necessarily need its own type, but it makes it more convenient passing all this data between functions as well as allowing custom formatting of its output by overloading the Base.show() function.
type Metadata
querystring::String
cols::Int
rows::Int
colnames::Array{ASCIIString}
coltypes::Array{(String,Int16)}
colsizes::Array{Int}
coldigits::Array{Int16}
colnulls::Array{Int16}
end
function show(io::IO,meta::Metadata)
if meta == null_meta
print(io,"No metadata")
else
println(io,"Resultset metadata for executed query")
println(io,"------------------------------------")
println(io,"Columns: $(meta.cols)")
println(io,"Rows: $(meta.rows)")
println(io,"Column Names: $(meta.colnames)")
println(io,"Column Types: $(meta.coltypes)")
println(io,"Column Sizes: $(meta.colsizes)")
println(io,"Column Digits: $(meta.coldigits)")
println(io,"Column Nullable: $(meta.colnulls)")
print(io,"Query: $(meta.querystring)")
end
end
Again, nothing fancy, but illustrates how easy it really is to define a custom type and produce custom output along with it.
Cheers.
One thing you could do would be to define a new type for the return value for this function, call it TrimCIResult or something. Then you could define appropriate methods to show that object in the REPL. Or you may be able to generalize that solution with a type hierarchy that could be used for storing the results from and displaying any statistical test.
The value nothing is how you return a value that won't print: the repl specifically checks for the value nothing and prints nothing if that's the value returned by an expression. What you're looking to do is to return a bunch of values and not print them, which strikes me as rather odd. If a function returns some stuff, I want to know about it – having the repl lie to users seems like a bad idea. Harlan's suggesting would work though: define a type for this value with the values you don't want to expose to the user as fields and customize its printing so that the fields you don't want to show people aren't printed.
I'm not that much of an OOP guy, so could someone please explain this simple concept in layman terms.
When I call foo.child from the foo.parent function, it seems to pass the A=7 argument
down into the foo.child object and overrides or takes precedence over the A=3 default argument in foo.child as I would expect.
foo.parent <- function(A=7) foo.child(A)
foo.child <- function(A=3) 2+A
foo.parent(A=7)
#[1] 9
But when I instantiate it inside of foo.parent, the parameter A=7 does pass down or force the instantiated object to use A=7; instead it uses the child object's parameter of A=3
foo.child<-function(A=3) 2+A
foo.parent <- function(A=7){
foo.child(A=3)
}
foo.parent(A=7)
#[1] 5
Why does that happen? And what terminology would I use to describe the differences?
In your second example you do not give a value to A (At least not in such a way as you might thought). Try
foo.child<-function(A=3) 2+A
foo.parent<-function(A=7){
foo.child(A=A)
}
foo.parent(A=7)
foo.parent()
instead. So, you mix here two different As. The =sign within a function call defines, what happens if you do not give a value for that variable in the function call.
I think your problem is you don't quite understand how default arguments work. So
foo.child = function(A=1) 2+A
defines the function foo.child that has a default argument A=1. So,
foo.child()
gives 3. Now in this function
foo.parent = function(A=3){
foo.child(A=4)
}
you are always passing the value A=4 to the function foo.child, hence,
foo.parent(A=7)
# 6
Also, when you are trying to figure out what is happening, it's helpful to have different values of A
I'm a bit confused on global variable assignments after reading quite a lot of stack overflow questions. I have gone through
Global variables in R and other similar questions
I have the following situation. I have 2 global variables current_idx and previous_idx. These 2 global variables are being set by a method in a reference class.
Essentially, using <<- assignment operator should work right ? But, I get this warning
Non-local assignment to non-field names (possibly misspelled?)
Where am I going wrong ?
EDIT
Using assign(current_idx, index, envir = .GlobalEnv) works i.e. I do not get the warning. Can some one shed some light on this.
You are confusing "global variables" and Reference Classes which are a type of environment. Executing <<- will assign to a variable with that name in the parent.frame of the function. If you are only one level down from the .GlobalEnv, it will do the same thing as your assign statement.
If you have a Reference Class item you can assign items inside it by name with:
ref_item$varname <- value
Easier said than done, though. First you need to set up the ReferenceClass properly:
http://www.inside-r.org/r-doc/methods/ReferenceClasses
This is happening because the default method for modifying fields of a reference class from within a reference class method is to use <<-. For example, in:
setRefClass(
"myClass",
fields=list(a="integer"),
methods=list(setA=function(x) a <<- x)
)
You can modify the a field of your reference class via the setA method. Because this is the canonical way of setting fields via methods in reference classes, R assumes that any other use of <<- within a reference method is a mistake. So if you try to assign to a variable that exists in an environment other than the reference class, R "helpfully" warns you that maybe you have a typo since it thinks the only probably use of <<- in a reference method is to modify a reference field.
You can still just assign to global objects with <<-. The warning is just a warning that maybe you are doing something you didn't intend to do. If you intended to write to an object in the global environment, then the warning doesn't apply.
By using assign you are bypassing the check that reference methods carry out to make sure you are not accidentally typoing a field name in an assignment within the reference method, so you don't get the warning. Also, note that assign actually targets the environment you supply, whereas <<- will just find the first object of that name in the lexical search path.
All this said, there are really rare instances where you actually want a reference method do be writing directly to the global environment. You may need to rethink what you are doing. You should ask yourself why those two variables are not just fields in the reference class instead of global variables.