Access to undefined member variables when exposing a class in boost python - boost-python

I'm struggling with some unwanted side effects of exposing a class in boost.python. It seems that in Python, it is legal to assign to a member variable that was never defined in the original class. So in the example below I define a class with a member 'a', but also writing to a member 'b' works in Python. This has the (in my case negative) side effect that I can't detect typos when accessing class members, since myClass.complicatedObjectName=1 works and myclass.complicatedObjectname=1 works as well, even if the latter variable is never defined. As illustration, when exposing a class like this
#include <boost/python.hpp>
using namespace boost::python;
class A {
public:
A() : a(1) {}
int a;
};
BOOST_PYTHON_MODULE(liba) {
class_<A>("A", init<>())
.def_readonly("a", &A::a);
}
and trying to acces A.a and A.b
import liba
myA = liba.A()
print "a", myA.a
myA.b = 1
print "b", myA.b
generates the output:
a 1
b 1
I would prefer the assignment 'myA.B = 1' to fail. Is there a way to make boost.python behave like this?
I'm sorry if this question is already asked somewhere, but I couldn't find an answer. Thanks for pointing me to existing answers if there is one.
I'm working with the standard boost libraries (v 1.54) on Ubuntu 14.04.

In python you can override _setattr_ to only allow attribute names from a defined list. Here is how to do that: https://stackoverflow.com/questions/3079306/how-to-protect-againt-typos-when-setting-value-for-class-members.
Then some ideas how to achieve the same in C++: How to override __setattr__ in a wrapped class (from C++)? and Catch creation of instance attributes of boost::python-wrapped classes from c++.

Related

Can powershell call subclasses from external C# dll

I have some simple code from:
https://www.codeguru.com/csharp/csharp/cs_misc/dllsandexecutables/article.php/c4239/Creating-and-Using-C-DLLs.htm
which generates a dll to do some simple math. I wanted to add a subclass
namespace MathFunctions
{
public class Add : MultiClass
{
public static int MultiplyAndAdd(int a, int b, int c)
{
return (a * b) + c;
}
}
}
Then call it from powershell.
Running powershell against the master classes returns data back without an issue
Import-module("C:\temp\MathFunctions.dll")
[MathFunctions.MultiClass]::Multiply(10, 2)
returns 20 as expected, but I can't figure the format to access the subclass. I've tried variations on:
[MathFunctions.MultiClass.Add]::MultiplyAndAdd(10, 2, 3)
[MathFunctions.MultiClass+Add]::MultiplyAndAdd(10, 2, 3)
[MathFunctions.MultiClass]:Add:MultiplyAndAdd(10, 2, 3)
[MathFunctions.MultiClass]::Add.MultiplyAndAdd(10, 2, 3)
but I always get variations on
Unable to find type [MathFunctions.MultiClass.Add]
I've also looked for the method in powershell via:
[MathFunctions.MultiClass] | get-member -MemberType method
but my subclass isn't listed.
I know I'm accessing it incorrectly. I can't figure out how to access the subclass from powershell.
I'm fairly sure subclasses can be accessed, as the closest example is:
PowerShell IComparable with subclasses
but I don't see how he aliased it.
Thanks
Thank you bluuf who pointed me in the right direction.
I ended up using dotPeek to take the dll apart (now it was public [blush]).
Code is as above and the powershell method is just the subclass name:
[MathFunctions.Add]::MultiplyAndAdd(5,2,3)
which gave an answer - not an error
To explain the confusion in more detail:
You mistakenly thought that class-inheritance relationships must be reflected in a given class' full (namespace-qualified) type name, so you thought that because class Add derives from class MultiClass, MultiClass too must be reflected in the full type name.
In reality, a class' derivation is irrelevant with respect to its full name; all that matter is the namespace in which it is placed.
In other words: to form the full type name for any type (class), use <EnclosingNamespace>.<TypeName>[1], which in your case means:
MathFunctions.Add
Using that as a PowerShell type literal - [MathFunctions.Add] - allows you to access the static MultiplyAndAdd() method via ::, the static-member access operator, as shown in your own answer.
Also, remember that tab-completion can be helpful here, because it works with type names too; in your case, typing [Add<tab> will expand to [MathFunctions.Add, yielding the full type name.
(If multiple available (public) type names start with Add, you may to have to press the tab key repeatedly to cycle through the matches.)
[1] A variation is required to access a nested class, i.e., a class embedded in another class:
<EnclosingNamespace>.<EnclosingTypeName>+<NestedTypeName>, e.g., if your Add class had a nested class named Inner: MathFunctions.Add+Inner

Scala parameters for access modifiers?

What is the difference between
class Test {
private[this] val foo = 0
}
vs
class Test {
private val foo = 0
}
What all can go inside the []? Also, what should I search for when I want to look up the specs of this? I tried Googling various combinations of "scala access modifier arguments/parametrized scala access modifier" and nothing came up.
what should I search for when I want to look up the specs of this?
In The Scala Language Specification it is defined as "access modifier" and "access qualifier" (see BNF in §5.2).
What is the difference between
...
What all can go inside the []?
You can put class name, package name or this there. Here is a relevant quote from language specs that explains this (see §5.2 for more details):
The modifier can be qualified with an identifier C (e.g. private[C ]) that must
denote a class or package enclosing the definition. Members labeled with
such a modifier are accessible respectively only from code inside the package
C or only from code inside the class C and its companion module (§5.4).
An different form of qualification is private[this]. A member M marked
with this modifier is called object-protected; it can be accessed only from
within the object in which it is defined. That is, a selection p.M is only legal if the prefix is this or O.this, for some class O enclosing the reference. In
addition, the restrictions for unqualified private apply.
The first one is private for instance class, second is for class. If you use second version you have access from another instance of Test class (it's usefull for equals method or similiar).

Scala package private with duplicate name in package hierarchy

So I understand that in Scala, you can define something private within the scope of a specific package by adding the modifier private[packagename] where packagename is (obviously) the name of the package that you wish the reference to be private to.
So, for instance, let's say I have a package com.mycompany.usefulname with some class that has a field declared private[mycompany] - this will be accessible within all things in the com.mycompany.usefulname, as well as other things like perhaps com.mycompany.othername (or things simply in the com.mycompany, if for some reason I put something there).
What I'm wondering is this: if I do an awful design, where I have two different levels of my hierarchy using the same name, such as a package com.mycompany.mycompany, is there a way to specify which mycompany I would want something to be private within? Based on Package private modifier in Scala 2.8, it doesn't seem to be valid to specific private[com.mycompany], so how could I specify which one it would be?
Just to be clear, this is purely out of curiosity, and I'm not actually trying to make something with such an ambiguous name in the class hierarchy.
EDIT: To actually see what this does, I implemented the following hierarchy:
mycompany
mycompany
InnerObject.scala
usefulname
InnerObject2.scala
OuterObject.scala
InnerObject.scala is as follows:
object InnerObject {
private val privateVal = 7
private[mycompany] val packagePrivateVal = 8
val regularVal = 9
}
InnerObject2.scala is virtually identical:
object InnerObject2 {
private val privateVal = 7
private[mycompany] val packagePrivateVal = 8
val regularVal = 9
}
from OuterObject, I could reference:
InnerObject.regularVal
InnerObject2.packagePrivateVal
InnerObject2.regularVal
The regularVal isn't surprising, as this is public. The package private seems to be going up the hierarchy until it finds the first instance that matches the declaration of mycompany. So, can anyone tell me if/how to make it reference the outer one, rather than the inner one?
Here is the relevant excerpt (the example under the linked anchor) from the Scala language specification:
The following code illustrates the use of qualified private:
package outerpkg.innerpkg
class Outer {
class Inner {
private[Outer] def f()
private[innerpkg] def g()
private[outerpkg] def h()
}
}
Here, accesses to the method f can appear anywhere within OuterClass, but not outside it. Accesses to method g can appear anywhere within the package outerpkg.innerpkg, as would be the case for package-private methods in Java. Finally, accesses to method h can appear anywhere within package outerpkg, including packages contained in it.
There is no other mention of package-private access modifiers anywhere in the specs, at all. From this, I'd gather there is no way to deal with duplicate path nodes in the package name, and Scala will take the inner-most name that it finds, as you say.
In my opinion, that's a good thing, because duplicate names are redundant and confusing.

Using mixins in Coffeescript

I want to split up a large class by using mixins.
I am using this mixin code from the Little Book
#include: (obj) ->
for key, value of obj when key not in moduleKeywords
# Assign properties to the prototype
#::[key] = value
obj.included?.apply(#)
this
class FooMixin
b: => #something = 2
class Foo extends Module
#include FooMixin
a: => #something = 1
Problem is that # in FooMixin is FooMixin. I want it to be Foo instead.
I have tried adding the line _.bind(#::[key], #) at the end of #include() but it doesn't help. Any suggestions?
Okay, few things I was doing wrong.
1.
#include from the Little Book takes an object not a class. To get it to work with classes you need to write #include FooMixin::. However, I have since begun using objects instead.
2.
When using an object instead of a class, the fat arrow adds a line inside the CoffeeScript wrapper right at the top which reads _this = this. All methods are bound to the global context which is not what we want. To fix we must convert fat arrows to thin arrows, and bind each function to our Foo instance. Using Underscore I added this to the constructor of Foo:
constructor: ->
for fname in _.functions FooMixin
#[fname] = _.bind #[fname], #
super
I tried _.bindAll #, _.functions FooMixin but it gave me an error saying something like At Function.bind, could not run bind of undefined. Weird error, seeing as the code above is pretty much identical to the _.bindAll method.
So now I can split my classes up for better readability and code sharing.
UPDATE: The problem with _.bindAll is that it takes a splat not an array. Fix is to use _.bindAll #, _.functions(FooMixin)....
UPDATE: Found a better solution.
Same as original post. Use classes for mixins.
Use #include FooMixin:: or change #include to operate on a prototype instead of properties.
In the Foo constructor write FooMixin.call # which binds the methods correctly.
This works well and is nice and clean.
The only potential issue is that mixins will be overridden by existing properties. The only way to get around this that I can see is to do something like:
after = ->
_.extend Foo, FooMixin::
class Foo
# define...
after()
Or pass the extend method to _.defer but this is so hacky and probably won't work.

Scala - mixing of packages and variables?

A very strange thing indeed. I have the following project structure:
myproject/one/two
Inside package myproject I have a class:
abstract class A (two: Buffer[Int])
and then, inside package one I have:
object B extends A (Buffer[Int](1, 2, 3)) {
val с = two.map(_ + 1) // ERROR
}
However, the erros says:
object map is not a member of package
myproject/one/two
which is obviously erroneous because it should be perfectly clear that I don't refer to the packages here, but to the local variable... And two also is not shown in context-assist after this. in B, but is shown in A (Scala-IDE). Is this an intended behavior and I am doing something wrong or is it a bug?
UPDATE:
(simultaneously suggested by Nicolas :D ) Been able to resolve the name collision by specifying two as val (making it public). I did not notice at first, but it was private and unavailable in the successor class. Nevertheless I am still wondering, why and how did Scala pick up a package instead of saying that the variable does not exist or is not accessible?
It's not as clear as you might think. Without a modifier, two is private to abstract class A class A. Thus your declaration of a is equivalent to abstract class A (private[this] A). It means that field two can't be seen from object B. A direct consequence is that the compiler look into the only defiition of two visible from B: the package two.