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.
295 296 297 298 299 300 301 302 303 304 |
# File 'lib/amazon/aws.rb', line 295 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)
307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 |
# File 'lib/amazon/aws.rb', line 307 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.
235 236 237 238 239 240 241 242 243 244 245 |
# File 'lib/amazon/aws.rb', line 235 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.
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 288 289 290 291 292 |
# File 'lib/amazon/aws.rb', line 263 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:
376 377 378 |
# File 'lib/amazon/aws.rb', line 376 def ==(other) # :nodoc: @__val__.to_s == other end |
#=~(other) ⇒ Object
:nodoc:
381 382 383 |
# File 'lib/amazon/aws.rb', line 381 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.
452 453 454 |
# File 'lib/amazon/aws.rb', line 452 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.
342 343 344 345 346 |
# File 'lib/amazon/aws.rb', line 342 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.
517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 |
# File 'lib/amazon/aws.rb', line 517 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:
351 352 353 354 355 |
# File 'lib/amazon/aws.rb', line 351 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.
403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 |
# File 'lib/amazon/aws.rb', line 403 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.
391 392 393 394 395 396 397 |
# File 'lib/amazon/aws.rb', line 391 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.
431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 |
# File 'lib/amazon/aws.rb', line 431 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:
358 359 360 361 362 363 364 365 366 367 368 369 370 371 |
# File 'lib/amazon/aws.rb', line 358 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.
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 506 507 508 509 510 |
# File 'lib/amazon/aws.rb', line 460 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 |