Class: Python::PyObject

Inherits:
Hash
  • Object
show all
Defined in:
lib/python/pyobject.rb

Instance Method Summary collapse

Constructor Details

#initialize(attr = {}) ⇒ PyObject

Returns a new instance of PyObject.



3
4
5
# File 'lib/python/pyobject.rb', line 3

def initialize(attr={})
  self.merge!(attr)
end

Instance Method Details

#base_traverse(&proc) ⇒ Object



105
106
107
108
109
110
111
112
113
114
115
# File 'lib/python/pyobject.rb', line 105

def base_traverse(&proc)
  queue = [self]
  until queue.empty?
    cls = queue.pop
    if judge = proc.call(cls)
      return cls
    end
    queue += (cls[:bases] || [])
  end
  return nil
end

#call(*args) ⇒ Object



15
16
17
18
19
20
21
# File 'lib/python/pyobject.rb', line 15

def call(*args)
  if self[:entity] && self[:entity].is_a?(Proc)
    self[:entity].call(*args)
  else
    call_special_method("__call__", *args)
  end
end

#call_special_method(method_name, *args) ⇒ Object



23
24
25
# File 'lib/python/pyobject.rb', line 23

def call_special_method(method_name, *args)
  get_special_attr(method_name).call(*args)
end

#datadescriptor?Boolean

Returns:

  • (Boolean)


101
102
103
# File 'lib/python/pyobject.rb', line 101

def datadescriptor?
  descriptor? && self[:class].base_traverse{|cls| cls["__set__"] || cls["__delete__"]}
end

#descriptor?Boolean

Returns:

  • (Boolean)


88
89
90
# File 'lib/python/pyobject.rb', line 88

def descriptor?
  self[:class] && self[:class].base_traverse{|cls| cls["__get__"]}
end

#entityObject



11
12
13
# File 'lib/python/pyobject.rb', line 11

def entity
  self[:entity]
end

#get_attr(name) ⇒ Object



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/python/pyobject.rb', line 49

def get_attr(name)
  if !self[:class]
    raise "failed to get attr #{name} from #{self}: #{self} doesn't have class"
  elsif cls = self[:class].base_traverse{|cls| cls[name] && cls[name].datadescriptor?}
    cls[name].get_get_method.call(cls[name], self, self[:class])
  elsif owner = self.base_traverse{|owner| owner[name]}
    owner[name]
  elsif cls = self[:class].base_traverse{|cls| cls[name]}
    if cls[name].descriptor?
      cls[name].get_get_method.call(cls[name], self, self[:class])
    else
      cls[name]
    end
  else
    raise "failed to get attr #{name} from #{self}: #{name} is not found"
  end
end

#get_get_methodObject



83
84
85
86
# File 'lib/python/pyobject.rb', line 83

def get_get_method
  cls = self[:class].base_traverse{|cls| cls["__get__"]}
  cls["__get__"]
end

#get_set_methodObject



92
93
94
95
96
97
98
99
# File 'lib/python/pyobject.rb', line 92

def get_set_method
  cls = self[:class].base_traverse{|cls| cls["__set__"] || cls["__delete__"]}
  unless cls["__set__"]
    raise "cannot set data on datadescriptor '#{cls}'"
  else
    cls["__set__"]
  end
end

#get_special_attr(name) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/python/pyobject.rb', line 27

def get_special_attr(name)
  if !self[:class]
    raise "failed to get special attr #{name} from #{self}: #{self} doesn't have class"
  elsif cls = self[:class].base_traverse{|cls| cls[name] && cls[name].datadescriptor?}
    cls[name].get_get_method.call(cls[name], self, self[:class])
  elsif cls = self[:class].base_traverse{|cls| cls[name]}
    if cls[name].descriptor?
      cls[name].get_get_method.call(cls[name], self, self[:class])
    else
      cls[name]
    end
  else
    raise "failed to get special attr #{name} from #{self}: #{name} is not found"
  end
end

#has_attr?(name) ⇒ Boolean

Returns:

  • (Boolean)


67
68
69
70
71
# File 'lib/python/pyobject.rb', line 67

def has_attr?(name)
  get_attr(name)
rescue
  nil
end

#has_special_attr?(name) ⇒ Boolean

Returns:

  • (Boolean)


43
44
45
46
47
# File 'lib/python/pyobject.rb', line 43

def has_special_attr?(name)
  get_special_attr(name)
rescue
  nil
end

#inspectObject



117
118
119
120
121
122
123
124
125
126
127
# File 'lib/python/pyobject.rb', line 117

def inspect
  if self[:name]
    self[:name]
  elsif self[:entity]
    self[:entity].to_s
  elsif self[:class] && self[:class][:name]
    "<instance of:#{self[:class][:name]}"
  else
    super
  end
end

#make_instance(entity = nil, &entity_proc) ⇒ Object



7
8
9
# File 'lib/python/pyobject.rb', line 7

def make_instance(entity=nil, &entity_proc)
  PyObject.new(:class => self, :entity => entity || entity_proc)
end

#set_attr(name, pyobj) ⇒ Object



73
74
75
76
77
78
79
80
81
# File 'lib/python/pyobject.rb', line 73

def set_attr(name, pyobj)
  if !self[:class]
    raise "failed to set attr #{name} on #{self}: #{self} doesn't have class"
  elsif cls = self[:class].base_traverse{|cls| cls[name] && cls[name].datadescriptor?}
    cls[name].get_set_method.call(cls[name], self, pyobj)
  else
    self[name] = pyobj
  end
end