Class: Reality::Entity
- Inherits:
-
Object
- Object
- Reality::Entity
- Defined in:
- lib/reality/entity.rb,
lib/reality/entity/coercion.rb,
lib/reality/entity/wikipedia_type.rb,
lib/reality/entity/wikidata_predicates.rb
Overview
Reality::Entity is a main concept of the library. It represents errr well, some entity from real world. You can think of it as of rough equivalent of Wikipedia article.
Wiki has more details about entity concept and internals.
The easiest way to have an entity is to instantiate is as Entity.load
(also aliased as Reality.Entity()
method): you'll just have your
entity already loaded from all possible data sources (or nil
if
neither of them knows about it):
argentina = Reality::Entity('Argentina')
# => #<Reality::Entity(Argentina):country>
Then, you can use #describe to see what properties entity has, and
call any of them by name, like argentina.capital
.
Or you can create not loaded entities with just #initialize (it may be useful when you want to further batch-load several of them through List#load!).
Defined Under Namespace
Modules: Coercion
Instance Attribute Summary collapse
-
#values ⇒ Hash<Symbol, Object>
(also: #attributes)
readonly
All values extracted from data sources, in structured form.
-
#wikipage ⇒ Infoboxer::MediaWiki::Page
readonly
Instance of Infoboxer's page.
Class Method Summary collapse
-
.load(name) ⇒ Entity?
Loads Entity from all datasources.
Instance Method Summary collapse
-
#describe ⇒ nil
Prints general object state and all properties with values.
-
#initialize(name, wikidata_id: nil) ⇒ Entity
constructor
Creates new entity.
-
#inspect ⇒ String
Returns entity brief representation.
-
#load! ⇒ self
Loads entity data from all external sources.
-
#loaded? ⇒ Boolean
Returns
true
if entity is loaded already. -
#method_missing(sym, *arg, **opts, &block) ⇒ Object
Entity handles
method_missing
this way:. -
#name ⇒ String
Entity name string.
-
#to_h ⇒ Hash
Converts Entity to hash, preserving only core types (so, you can store this hash in YAML or JSON, for example).
-
#to_json ⇒ String
Converts entity to JSON (same as
entity.to_h.to_json
). - #to_s ⇒ Object
Constructor Details
#initialize(name, wikidata_id: nil) ⇒ Entity
Creates new entity. Initially, entity is not loaded from datasources,
it's just a name. If you want to receive a loaded entity with one
statement, take a look at load, which does new
+ load!
under the hoods.
e = Reality::Entity.new('Mississippi')
# => #<Reality::Entity?(Mississippi)>
e.loaded?
# => false
e.values
# => {}
77 78 79 80 81 |
# File 'lib/reality/entity.rb', line 77 def initialize(name, wikidata_id: nil) @name = name @wikidata_id = wikidata_id @values = {} end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(sym, *arg, **opts, &block) ⇒ Object
Entity handles method_missing
this way:
- loads itself if it was not loaded;
- returns one of #values by method name.
Note, that even if there's no value with required key, method_missing
will return nil
(and not through NoMethodError
as someone may
expect). That's because even supposedly homogenous entities may have different
property sets, and typically you want to do something like
cities.map(&:area).compact.inject(:+)
, not handling exceptions
about "this city has no 'area' property".
221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 |
# File 'lib/reality/entity.rb', line 221 def method_missing(sym, *arg, **opts, &block) if arg.empty? && opts.empty? && !block && sym !~ /[=?!]/ && !UNSUPPORTED_METHODS.include?(sym) load! unless loaded? # now some new method COULD emerge while loading if methods.include?(sym) send(sym) else values[sym] end else super end end |
Instance Attribute Details
#values ⇒ Hash<Symbol, Object> (readonly) Also known as: attributes
All values extracted from data sources, in structured form. You can pretty-previes them via #describe, as well as work with separate values with method call (see #method_missing).
50 51 52 |
# File 'lib/reality/entity.rb', line 50 def values @values end |
#wikipage ⇒ Infoboxer::MediaWiki::Page (readonly)
Instance of Infoboxer's page.
Pretty useful on its own:
puts Reality::Entity('Argentina').wikipage.intro
# Argentina (ˌɑrdʒənˈtiːnə; aɾxenˈtina), officially the Argentine Republic (República Argentina), is a federal republic....
Refer to Infoboxer's documentation for details.
43 44 45 |
# File 'lib/reality/entity.rb', line 43 def wikipage @wikipage end |
Class Method Details
Instance Method Details
#describe ⇒ nil
Prints general object state and all properties with values
Example:
$> Reality::Entity.new('Mississippi').describe
Output:
-------------------------------
<Reality::Entity(Mississippi)>
-------------------------------
capital: #<Reality::Entity?(Jackson)>
coord: #<Reality::Geo::Coord(33°0′0″N,90°0′0″W)>
country: #<Reality::Entity?(United States of America)>
created_at: Wed, 10 Dec 1817
located_in: #<Reality::Entity?(United States of America)>
neighbours: #<Reality::List[Alabama?, Tennessee?, Louisiana?, Arkansas?]>
official_website: "http://www.mississippi.gov"
tz_offset: #<Reality::TZOffset(UTC-06:00)>
148 149 150 151 |
# File 'lib/reality/entity.rb', line 148 def describe puts _describe nil end |
#inspect ⇒ String
Returns entity brief representation. Things to note:
#<Reality::Entity?(Argentina)>
^ ^
| Entity name
Sign of not
loaded entity
#<Reality::Entity(Argentina):country>
^ ^
| Name of "additional type" (to be documented...)
No question mark:
entity is loaded
119 120 121 122 123 124 125 |
# File 'lib/reality/entity.rb', line 119 def inspect if @wikipedia_type && @wikipedia_type.symbol "#<#{self.class}#{loaded? ? '' : '?'}(#{name}):#{@wikipedia_type.symbol}>" else "#<#{self.class}#{loaded? ? '' : '?'}(#{name})>" end end |
#load! ⇒ self
Loads entity data from all external sources.
Note that this method is called implicitly on #method_missing, #describe or #to_h.
Note also that if you need several entities to be loaded, its much more effective to have them grouped into List and batch-loaded via List#load!.
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 |
# File 'lib/reality/entity.rb', line 173 def load! if @wikidata_id @wikidata = Wikidata::Entity.one_by_id(@wikidata_id) if @wikidata && @wikidata.en_wikipage @wikipage = Infoboxer.wikipedia.get(@wikidata.en_wikipage.tr('_', ' ')) end else @wikipage = Infoboxer.wikipedia.get(name) @wikidata = if @wikipage Wikidata::Entity.one_by_wikititle(@wikipage.title) else Wikidata::Entity.one_by_label(name) end end after_load self end |
#loaded? ⇒ Boolean
Returns true
if entity is loaded already.
201 202 203 |
# File 'lib/reality/entity.rb', line 201 def loaded? !!(@wikipage || @wikidata) end |
#name ⇒ String
Entity name string. For not loaded entity returns the name by which it was created. For loaded, it's correct name of Wikipedia page:
e = Reality::Entity.new('Einstein')
# => #<Reality::Entity?(Einstein)>
e.name
# => "Einstein"
e.load!
# => #<Reality::Entity(Albert Einstein)>
e.name
# => "Albert Einstein"
98 99 100 |
# File 'lib/reality/entity.rb', line 98 def name @wikipage ? @wikipage.title : @name end |
#to_h ⇒ Hash
Converts Entity to hash, preserving only core types (so, you can store this hash in YAML or JSON, for example). Some notes on conversion:
- Entity name goes to
:name
key; - Rational values became floating point;
- Measure and Geo::Coord became hashes;
- other entities became: when loaded - hashes, when not loaded - just strings of entity name
Example:
argentina = Reality::Entity('Argentina')
# => #<Reality::Entity(Argentina):country>
argentina.head_of_government.load!
# => #<Reality::Entity(Mauricio Macri)>
agentina.to_h
# {:name=>"Argentina",
# :long_name=>"Argentine Republic",
# :area=>{:amount=>2780400.0, :unit=>"km²"},
# :gdp_ppp=>{:amount=>964279000000.0, :unit=>"$"},
# :population=>{:amount=>43417000.0, :unit=>"person"},
# :head_of_government=>
# {:name=>"Mauricio Macri",
# :birthday=>"1959-02-08",
# ....},
# :country=>"Argentina",
# :continent=>"South America",
# :head_of_state=>"Mauricio Macri",
# :capital=>"Buenos Aires",
# :currency=>"peso",
# :neighbours=>["Uruguay", "Brazil", "Chile", "Paraguay", "Bolivia"],
# :tld=>".ar",
# :adm_divisions=>["Buenos Aires", "Buenos Aires Province", ....],
# :iso2_code=>"AR",
# :iso3_code=>"ARG",
# :part_of=>["Latin America"],
# :tz_offset=>"-03:00",
# :organizations=>["United Nations","Union of South American Nations","Mercosur",...],
# :calling_code=>"+54",
# :created_at=>"1816-01-01",
# :highest_point=>"Aconcagua",
# :coord=>{:lat=>-34.0, :lng=>-64.0},
# :official_website=>"http://www.argentina.gob.ar/",
# :gdp_nominal=>{:amount=>537659972702.0, :unit=>"$"}}
#
306 307 308 309 310 |
# File 'lib/reality/entity.rb', line 306 def to_h load! unless loaded? {name: name}.merge \ values.map{|k, v| [k.to_sym, Coercion.to_simple_type(v)]}.to_h end |
#to_json ⇒ String
Converts entity to JSON (same as entity.to_h.to_json
)
316 317 318 |
# File 'lib/reality/entity.rb', line 316 def to_json to_h.to_json end |
#to_s ⇒ Object
153 154 155 |
# File 'lib/reality/entity.rb', line 153 def to_s name end |