Class: Amazon::AWS::AWSObject
- Inherits:
-
Object
- Object
- Amazon::AWS::AWSObject
- Includes:
- REXML
- Defined in:
- lib/amazon/aws.rb
Overview
Everything returned by AWS is an AWSObject.
Class Method Summary collapse
-
.load(io) ⇒ Object
This method can be used to load AWSObject data previously serialised by Marshal.dump.
-
.yaml_load(io) ⇒ Object
This method can be used to load AWSObject data previously serialised by YAML.dump.
Instance Method Summary collapse
-
#==(other) ⇒ Object
:nodoc:.
-
#=~(other) ⇒ Object
:nodoc:.
-
#[](key) ⇒ Object
Fake the appearance of an AWSObject as a hash.
-
#each ⇒ Object
(also: #each_property)
Iterator method for cycling through an object’s properties and values.
-
#get(discount = nil) ⇒ Object
For objects of class AWSObject::.*Image, fetch the image in question, optionally overlaying a discount icon for the percentage amount of discount to the image.
-
#initialize(op = nil) ⇒ AWSObject
constructor
A new instance of AWSObject.
-
#inspect ⇒ Object
:nodoc:.
-
#kernel ⇒ Object
Provide a shortcut down to the data likely to be of most interest.
-
#properties ⇒ Object
This alias makes the ability to determine an AWSObject’s properties a little more intuitive.
-
#to_h ⇒ Object
Convert an AWSObject to a Hash.
-
#to_s ⇒ Object
(also: #to_str)
:nodoc:.
-
#walk(node) ⇒ Object
Recursively walk through an XML tree, starting from node.
Constructor Details
#initialize(op = nil) ⇒ AWSObject
Returns a new instance of AWSObject.
290 291 292 293 294 295 296 297 298 299 |
# File 'lib/amazon/aws.rb', line 290 def initialize(op=nil) # The name of this instance variable must never clash with the # uncamelised name of an Amazon tag. # # This is used to store the REXML::Text value of an element, which # exists only when the element contains no children. # @__val__ = nil @__op__ = op if op end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *params) ⇒ Object (private)
302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 |
# File 'lib/amazon/aws.rb', line 302 def method_missing(method, *params) iv = '@' + method.id2name if instance_variables.include?( iv ) # Return the instance variable that matches the method called. # instance_variable_get( iv ) elsif instance_variables.include?( iv.to_sym ) # Ruby 1.9 Object#instance_variables method returns Array of Symbol, # not String. # instance_variable_get( iv.to_sym ) elsif @__val__.respond_to?( method.id2name ) # If our value responds to the method in question, call the method # on that. # @__val__.send( method.id2name ) else nil end end |
Class Method Details
.load(io) ⇒ Object
This method can be used to load AWSObject data previously serialised by Marshal.dump.
Example:
File.open( 'aws.dat' ) { |f| Amazon::AWS::AWSObject.load( f ) }
Marshal.load cannot be used directly, because subclasses of AWSObject are dynamically defined as needed when AWS XML responses are parsed.
Later attempts to load objects instantiated from these classes cause a problem for Marshal, because it knows nothing of classes that were dynamically defined by a separate process.
230 231 232 233 234 235 236 237 238 239 240 |
# File 'lib/amazon/aws.rb', line 230 def AWSObject.load(io) begin Marshal.load( io ) rescue ArgumentError => ex m = ex.to_s.match( /Amazon::AWS::AWSObject::([^ ]+)/ ) const_set( m[1], Class.new( AWSObject ) ) io.rewind retry end end |
.yaml_load(io) ⇒ Object
This method can be used to load AWSObject data previously serialised by YAML.dump.
Example:
File.open( 'aws.yaml' ) { |f| Amazon::AWS::AWSObject.yaml_load( f ) }
The standard YAML.load cannot be used directly, because subclasses of AWSObject are dynamically defined as needed when AWS XML responses are parsed.
Later attempts to load objects instantiated from these classes cause a problem for YAML, because it knows nothing of classes that were dynamically defined by a separate process.
258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 |
# File 'lib/amazon/aws.rb', line 258 def AWSObject.yaml_load(io) io.each do |line| # File data is external, so it's deemed unsafe when $SAFE > 0, which # is the case with mod_ruby, for example, where $SAFE == 1. # # YAML data isn't eval'ed or anything dangerous like that, so we # consider it safe to untaint it. If we don't, mod_ruby will complain # when Module#const_defined? is invoked a few lines down from here. # line.untaint m = line.match( /Amazon::AWS::AWSObject::([^ ]+)/ ) if m cl_name = [ m[1] ] # Module#const_defined? takes 2 parameters in Ruby 1.9. # cl_name << false if RUBY_VERSION >= '1.9.0' unless AWSObject.const_defined?( *cl_name ) AWSObject.const_set( m[1], Class.new( AWSObject ) ) end end end io.rewind YAML.load( io ) end |
Instance Method Details
#==(other) ⇒ Object
:nodoc:
371 372 373 |
# File 'lib/amazon/aws.rb', line 371 def ==(other) # :nodoc: @__val__.to_s == other end |
#=~(other) ⇒ Object
:nodoc:
376 377 378 |
# File 'lib/amazon/aws.rb', line 376 def =~(other) # :nodoc: @__val__.to_s =~ other end |
#[](key) ⇒ Object
Fake the appearance of an AWSObject as a hash. key should be any attribute of the object and can be a String, Symbol or anything else that can be converted to a String with to_s.
447 448 449 |
# File 'lib/amazon/aws.rb', line 447 def [](key) instance_variable_get( "@#{key}" ) end |
#each ⇒ Object Also known as: each_property
Iterator method for cycling through an object’s properties and values.
337 338 339 340 341 |
# File 'lib/amazon/aws.rb', line 337 def each # :yields: property, value self.properties.each do |iv| yield iv, instance_variable_get( "@#{iv}" ) end end |
#get(discount = nil) ⇒ Object
For objects of class AWSObject::.*Image, fetch the image in question, optionally overlaying a discount icon for the percentage amount of discount to the image.
512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 |
# File 'lib/amazon/aws.rb', line 512 def get(discount=nil) if self.class.to_s =~ /Image$/ && @url url = URI.parse( @url[0] ) url.path.sub!( /(\.\d\d\._)/, "\\1PE#{discount}" ) if discount # FIXME: All HTTP in Ruby/AWS should go through the same method. # Net::HTTP.start( url.host, url.port ) do |http| http.get( url.path ) end.body else nil end end |
#inspect ⇒ Object
:nodoc:
346 347 348 349 350 |
# File 'lib/amazon/aws.rb', line 346 def inspect # :nodoc: remove_val if instance_variable_defined?( :@__val__ ) && @__val__.nil? str = super str.sub( /@__val__=/, 'value=' ) if str end |
#kernel ⇒ Object
Provide a shortcut down to the data likely to be of most interest. This method is experimental and may be removed.
398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 |
# File 'lib/amazon/aws.rb', line 398 def kernel # :nodoc: # E.g. Amazon::AWS::SellerListingLookup -> seller_listing_lookup # stub = Amazon.uncamelise( @__op__.class.to_s.sub( /^.+::/, '' ) ) # E.g. seller_listing_response # level1 = stub + '_response' # E.g. seller_listing # level3 = stub.sub( /_[^_]+$/, '' ) # E.g. seller_listings # level2 = level3 + 's' # E.g. # seller_listing_search_response[0].seller_listings[0].seller_listing # self.instance_variable_get( "@#{level1}" )[0]. instance_variable_get( "@#{level2}" )[0]. instance_variable_get( "@#{level3}" ) end |
#properties ⇒ Object
This alias makes the ability to determine an AWSObject’s properties a little more intuitive. It’s pretty much just an alias for the inherited Object#instance_variables method, with a little tidying.
386 387 388 389 390 391 392 |
# File 'lib/amazon/aws.rb', line 386 def properties # Make sure we remove the leading @. # iv = instance_variables.collect { |v| v = v[1..-1] } iv.delete( '__val__' ) iv end |
#to_h ⇒ Object
Convert an AWSObject to a Hash.
426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 |
# File 'lib/amazon/aws.rb', line 426 def to_h hash = {} each do |iv, value| if value.is_a? AWSObject hash[iv] = value.to_h elsif value.is_a?( AWSArray ) && value.size == 1 hash[iv] = value[0] else hash[iv] = value end end hash end |
#to_s ⇒ Object Also known as: to_str
:nodoc:
353 354 355 356 357 358 359 360 361 362 363 364 365 366 |
# File 'lib/amazon/aws.rb', line 353 def to_s # :nodoc: if instance_variable_defined?( :@__val__ ) return @__val__ if @__val__.is_a?( String ) remove_val end string = '' # Assemble the object's details. # each { |iv, value| string << "%s = %s\n" % [ iv, value ] } string end |
#walk(node) ⇒ Object
Recursively walk through an XML tree, starting from node. This is called internally and is not intended for user code.
455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 |
# File 'lib/amazon/aws.rb', line 455 def walk(node) # :nodoc: if node.instance_of?( REXML::Document ) walk( node.root ) elsif node.instance_of?( REXML::Element ) name = Amazon.uncamelise( node.name ) cl_name = [ node.name ] # Module#const_defined? takes 2 parameters in Ruby 1.9. # cl_name << false if RUBY_VERSION >= '1.9.0' # Create a class for the new element type unless it already exists. # unless AWS::AWSObject.const_defined?( *cl_name ) cl = AWS::AWSObject.const_set( node.name, Class.new( AWSObject ) ) # Give it an accessor for @attrib. # cl.send( :attr_accessor, :attrib ) end # Instantiate an object in the newly created class. # obj = AWS::AWSObject.const_get( node.name ).new sym_name = "@#{name}".to_sym if instance_variable_defined?( sym_name) instance_variable_set( sym_name, instance_variable_get( sym_name ) << obj ) else instance_variable_set( sym_name, AWSArray.new( [ obj ] ) ) end if node.has_attributes? obj.attrib = {} node.attributes.each_pair do |a_name, a_value| obj.attrib[a_name.downcase] = a_value.to_s.sub( /^#{a_name}=/, '' ) end end node.children.each { |child| obj.walk( child ) } else # REXML::Text @__val__ = node.to_s end end |