Add all the A tasks
This commit is contained in:
parent
2dd7375f96
commit
051504d65b
1608 changed files with 18584 additions and 0 deletions
|
|
@ -0,0 +1,3 @@
|
|||
Demonstrate how to dynamically add variables to an object (a class instance) at runtime.
|
||||
|
||||
This is useful when the methods/variables of an instance are based on a data file that isn't available until runtime. Hal Fulton gives an example of creating an OO CSV parser at [http://www.devsource.com/article2/0,1759,1928562,00.asp An Exercise in Metaprogramming with Ruby]. This is referred to as "monkeypatching" by Pythonistas and some others.
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
note: Object oriented
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
var object:Object = new Object();
|
||||
object.foo = "bar";
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package
|
||||
{
|
||||
public dynamic class Foo
|
||||
{
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
var foo:Foo = new Foo();
|
||||
foo.bar = "zap";
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
with Ada.Text_IO; use Ada.Text_IO;
|
||||
|
||||
procedure Dynamic is
|
||||
package Abstract_Class is
|
||||
type Class is limited interface;
|
||||
function Boo (X : Class) return String is abstract;
|
||||
end Abstract_Class;
|
||||
use Abstract_Class;
|
||||
|
||||
package Base_Class is
|
||||
type Base is new Class with null record;
|
||||
overriding function Boo (X : Base) return String;
|
||||
end Base_Class;
|
||||
|
||||
package body Base_Class is
|
||||
function Boo (X : Base) return String is
|
||||
begin
|
||||
return "I am Class";
|
||||
end Boo;
|
||||
end Base_Class;
|
||||
use Base_Class;
|
||||
|
||||
E : aliased Base; -- An instance of Base
|
||||
|
||||
begin
|
||||
-- Gone run-time
|
||||
declare
|
||||
type Monkey_Patch (Root : access Base) is new Class with record
|
||||
Foo : Integer := 1;
|
||||
end record;
|
||||
overriding function Boo (X : Monkey_Patch) return String;
|
||||
function Boo (X : Monkey_Patch) return String is
|
||||
begin -- Delegation to the base
|
||||
return X.Root.Boo;
|
||||
end Boo;
|
||||
EE : Monkey_Patch (E'Access); -- Extend E
|
||||
begin
|
||||
Put_Line (EE.Boo & " with" & Integer'Image (EE.Foo));
|
||||
end;
|
||||
end Dynamic;
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
e := {}
|
||||
e.foo := 1
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
# CoffeeScript is dynamic, just like the Javascript it compiles to.
|
||||
# You can dynamically add attributes to objects.
|
||||
|
||||
# First create an object very simply.
|
||||
e = {}
|
||||
e.foo = "bar"
|
||||
e.yo = -> "baz"
|
||||
console.log e.foo, e.yo()
|
||||
|
||||
# CS also has class syntax to instantiate objects, the details of which
|
||||
# aren't shown here. The mechanism to add members is the same, though.
|
||||
class Empty
|
||||
# empty class
|
||||
|
||||
e = new Empty()
|
||||
e.foo = "bar"
|
||||
e.yo = -> "baz"
|
||||
console.log e.foo, e.yo()
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
e = {} // generic object
|
||||
e.foo = 1
|
||||
e["bar"] = 2 // name specified at runtime
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
empty = {}
|
||||
empty.foo = 1
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
class E {};
|
||||
|
||||
$e=new E();
|
||||
|
||||
$e->foo=1;
|
||||
|
||||
$e->{"foo"} = 1; // using a runtime name
|
||||
$x = "foo";
|
||||
$e->$x = 1; // using a runtime name in a variable
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package Empty;
|
||||
|
||||
# Constructor. Object is hash.
|
||||
sub new { return bless {}, shift; }
|
||||
|
||||
package main;
|
||||
|
||||
# Object.
|
||||
my $o = Empty->new;
|
||||
|
||||
# Set runtime variable (key => value).
|
||||
$o->{'foo'} = 1;
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
: (setq MyObject (new '(+MyClass))) # Create some object
|
||||
-> $385605941
|
||||
: (put MyObject 'newvar '(some value)) # Set variable
|
||||
-> (some value)
|
||||
: (show MyObject) # Show the object
|
||||
$385605941 (+MyClass)
|
||||
newvar (some value)
|
||||
-> $385605941
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
class empty(object):
|
||||
pass
|
||||
e = empty()
|
||||
|
|
@ -0,0 +1 @@
|
|||
e.foo = 1
|
||||
|
|
@ -0,0 +1 @@
|
|||
setattr(e, name, value)
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
class empty(object):
|
||||
def __init__(this):
|
||||
this.foo = "whatever"
|
||||
|
||||
def patch_empty(obj):
|
||||
def fn(self=obj):
|
||||
print self.foo
|
||||
obj.print_output = fn
|
||||
|
||||
e = empty()
|
||||
patch_empty(e)
|
||||
e.print_output()
|
||||
# >>> whatever
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
class Empty
|
||||
end
|
||||
|
||||
e = Empty.new
|
||||
class << e
|
||||
attr_accessor :foo
|
||||
end
|
||||
e.foo = 1
|
||||
puts e.foo # output: "1"
|
||||
|
||||
f = Empty.new
|
||||
f.foo = 1 # raises NoMethodError
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
import language.dynamics
|
||||
import scala.collection.mutable.HashMap
|
||||
|
||||
class A extends Dynamic {
|
||||
private val map = new HashMap[String, Any]
|
||||
def selectDynamic(name: String): Any = {
|
||||
return map(name)
|
||||
}
|
||||
def updateDynamic(name:String)(value: Any) = {
|
||||
map(name) = value
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
scala> val a = new A
|
||||
a: A = A@7b20f29d
|
||||
|
||||
scala> a.foo = 42
|
||||
a.foo: Any = 42
|
||||
|
||||
scala> a.foo
|
||||
res10: Any = 42
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
|addSlot p|
|
||||
|
||||
addSlot :=
|
||||
[:obj :slotName |
|
||||
|anonCls newObj|
|
||||
anonCls := obj class
|
||||
subclass:(obj class name,'+') asSymbol
|
||||
instanceVariableNames:slotName
|
||||
classVariableNames:''
|
||||
poolDictionaries:'' category:nil
|
||||
inEnvironment:nil.
|
||||
anonCls compile:('%1 ^ %1' bindWith:slotName).
|
||||
anonCls compile:('%1:v %1 := v' bindWith:slotName).
|
||||
newObj := anonCls cloneFrom:obj.
|
||||
obj become:newObj.
|
||||
].
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
p := Point x:10 y:20.
|
||||
addSlot value:p value:'z'.
|
||||
p z:30.
|
||||
p z.
|
||||
p z:40.
|
||||
p inspect
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
!Object methodsFor:'adding slots'!
|
||||
|
||||
addSlot: slotName
|
||||
|anonCls newObj|
|
||||
|
||||
anonCls := self class
|
||||
subclass:(self class name,'+') asSymbol
|
||||
instanceVariableNames:slotName
|
||||
classVariableNames:''
|
||||
poolDictionaries:'' category:nil
|
||||
inEnvironment:nil.
|
||||
anonCls compile:('%1 ^ %1' bindWith:slotName).
|
||||
anonCls compile:('%1:v %1 := v' bindWith:slotName).
|
||||
newObj := anonCls cloneFrom:self.
|
||||
self become:newObj.
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
p := Point x:10 y:20.
|
||||
p addSlot:'z'.
|
||||
p z:30.
|
||||
p z.
|
||||
p z:40.
|
||||
p inspect
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
Object subclass: #Monkey
|
||||
instanceVariableNames: 'aVar'
|
||||
classVariableNames: ''
|
||||
poolDictionaries: ''
|
||||
category: nil !
|
||||
|
||||
!Monkey class methodsFor: 'new instance'!
|
||||
new
|
||||
| o |
|
||||
o := super new.
|
||||
o init.
|
||||
^o
|
||||
!!
|
||||
|
||||
!Monkey methodsFor: 'init instance'!
|
||||
init
|
||||
aVar := 0
|
||||
!
|
||||
initWith: value
|
||||
aVar := value
|
||||
!!
|
||||
|
||||
!Monkey methodsFor: 'set/get the inst var(s)'!
|
||||
setVar: var
|
||||
aVar := var
|
||||
!
|
||||
getVar
|
||||
^aVar
|
||||
!!
|
||||
|
||||
|
||||
"Create a new instance"
|
||||
Smalltalk at: #aMonkey put: (Monkey new) !
|
||||
|
||||
"set the 'original' instance var to 12"
|
||||
aMonkey setVar: 12 .
|
||||
|
||||
"let's see what's inside"
|
||||
aMonkey inspect .
|
||||
|
||||
"add a new instance var"
|
||||
Monkey addInstVarName: 'x'.
|
||||
|
||||
"let's see what's inside now"
|
||||
aMonkey inspect .
|
||||
|
||||
"let us create a new method for x"
|
||||
!Monkey methodsFor: 'about x'!
|
||||
setX: val
|
||||
x := val
|
||||
!
|
||||
x
|
||||
^x
|
||||
!!
|
||||
|
||||
aMonkey setX: 10 .
|
||||
aMonkey inspect .
|
||||
(aMonkey x) printNl .
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
% package require TclOO
|
||||
% oo::class create summation {
|
||||
constructor {} {
|
||||
variable v 0
|
||||
}
|
||||
method add x {
|
||||
variable v
|
||||
incr v $x
|
||||
}
|
||||
method value {{var v}} {
|
||||
variable $var
|
||||
return [set $var]
|
||||
}
|
||||
destructor {
|
||||
variable v
|
||||
puts "Ended with value $v"
|
||||
}
|
||||
}
|
||||
::summation
|
||||
% set s [summation new]
|
||||
% # Do the monkey patch!
|
||||
% set [info object namespace $s]::time now
|
||||
now
|
||||
% # Prove it's really part of the object...
|
||||
% $s value time
|
||||
now
|
||||
%
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
% oo::class create summation {
|
||||
constructor {} {
|
||||
variable v 0
|
||||
}
|
||||
method add x {
|
||||
variable v
|
||||
incr v $x
|
||||
}
|
||||
method value {{var v}} {
|
||||
variable $var
|
||||
return [set $var]
|
||||
}
|
||||
destructor {
|
||||
variable v
|
||||
puts "Ended with value $v"
|
||||
}
|
||||
}
|
||||
::summation
|
||||
% set s [summation new]
|
||||
% set s2 [summation new]
|
||||
% oo::objdefine $s export varname
|
||||
% # Do the monkey patch...
|
||||
% set [$s varname time] "now"
|
||||
% $s value time
|
||||
now
|
||||
% # Show that it is only in one object...
|
||||
% $s2 value time
|
||||
can't read "time": no such variable
|
||||
Loading…
Add table
Add a link
Reference in a new issue