Class: JsshObject

Inherits:
Object show all
Defined in:
lib/vapir-firefox/jssh_socket.rb

Direct Known Subclasses

JsshArray, JsshDOMNode, JsshHash

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(ref, jssh_socket, other = {}) ⇒ JsshObject

initializes a JsshObject with a string of javascript containing a reference to the object, and a JsshSocket that the object is defined on.

Raises:

  • (ArgumentError)


563
564
565
566
567
568
569
570
571
572
573
# File 'lib/vapir-firefox/jssh_socket.rb', line 563

def initialize(ref, jssh_socket, other={})
  other={:debug_name => ref, :function_result => false}.merge(other)
  raise ArgumentError, "Empty object reference!" if !ref || ref==''
  raise ArgumentError, "Reference must be a string - got #{ref.inspect} (#{ref.class.name})" unless ref.is_a?(String)
  raise ArgumentError, "Not given a JsshSocket, instead given #{jssh_socket.inspect} (#{jssh_socket.class.name})" unless jssh_socket.is_a?(JsshSocket)
  @ref=ref
  @jssh_socket=jssh_socket
  @debug_name=other[:debug_name]
  @function_result=other[:function_result]
#    logger.info { "#{self.class} initialized: #{debug_name} (type #{type})" }
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args) ⇒ Object

method_missing handles unknown method calls in a way that makes it possible to write javascript-like syntax in ruby, to some extent.

method_missing will only try to deal with methods that look like /^[a-z_]*$/i - no special characters, only alphanumeric/underscores, starting with alpha or underscore - with the exception of three special behaviors:

If the method ends with an equals sign (=), it does assignment - it calls JsshSocket#assign_json to do the assignment and returns the assigned value.

If the method ends with a bang (!), then it will attempt to get the value (using json) of the reference, using JsonObject#val. For simple types (null, string, boolean, number), this is what happens by default anyway, but if you have an object or an array that you know you can json-ize, you can use ! to force that. See #invoke documentation for more information.

If the method ends with a question mark (?), then it will attempt to get a string representing the value, using JsonObject#val_str. This is safer than ! because the javascript conversion to json can error. This also catches the JsshUndefinedValueError that can occur, and just returns nil for undefined stuff.

otherwise, method_missing calls to #invoke, and returns a JsshObject, a string, a boolean, a number, or null - see documentation for #invoke.

Since #invoke returns a JsshObject for javascript objects, this means that you can string together method_missings and the result looks rather like javascript.

this lets you do things like: >> jssh_socket.object(‘getWindows()’).length

> 2

>> jssh_socket.object(‘getWindows()’).getBrowser.contentDocument?

> “[object XPCNativeWrapper [object HTMLDocument]]”

>> document=jssh_socket.object(‘getWindows()’).getBrowser.contentDocument

> #<JsshObject:0x34f01fc @ref=“getWindows().getBrowser().contentDocument” …>

>> document.title

> “ruby - Google Search”

>> document.forms.q.value

> “ruby”

>> document.forms.q.value=‘foobar’

> “foobar”

>> document.forms.q.value

> “foobar”

$A and $H, used below, are methods of the Prototype javascript library, which add nice functional methods to arrays and hashes - see www.prototypejs.org/ You can use these methods with method_missing just like any other:

>> js_hash=jssh_socket.object(‘$H’)

> #<JsshObject:0x2beb598 @ref=“$H” …>

>> js_arr=jssh_socket.object(‘$A’)

> #<JsshObject:0x2be40e0 @ref=“$A” …>

>> js_arr.pass(document.body.childNodes).pluck! :tagName

> [“TEXTAREA”, “DIV”, “NOSCRIPT”, “DIV”, “DIV”, “DIV”, “BR”, “TABLE”, “DIV”, “DIV”, “DIV”, “TEXTAREA”, “DIV”, “DIV”, “SCRIPT”]

>> js_arr.pass(document.body.childNodes).pluck! :id

> [“csi”, “header”, “”, “ssb”, “tbd”, “res”, “”, “nav”, “wml”, “”, “”, “hcache”, “xjsd”, “xjsi”, “”]

>> js_hash.pass(document.getElementById(‘tbd’)).keys!

> [“addEventListener”, “appendChild”, “className”, “parentNode”, “getElementsByTagName”, “title”, “style”, “innerHTML”, “nextSibling”, “tagName”, “id”, “nodeName”, “nodeValue”, “nodeType”, “childNodes”, “firstChild”, “lastChild”, “previousSibling”, “attributes”, “ownerDocument”, “insertBefore”, “replaceChild”, “removeChild”, “hasChildNodes”, “cloneNode”, “normalize”, “isSupported”, “namespaceURI”, “prefix”, “localName”, “hasAttributes”, “getAttribute”, “setAttribute”, “removeAttribute”, “getAttributeNode”, “setAttributeNode”, “removeAttributeNode”, “getAttributeNS”, “setAttributeNS”, “removeAttributeNS”, “getAttributeNodeNS”, “setAttributeNodeNS”, “getElementsByTagNameNS”, “hasAttribute”, “hasAttributeNS”, “ELEMENT_NODE”, “ATTRIBUTE_NODE”, “TEXT_NODE”, “CDATA_SECTION_NODE”, “ENTITY_REFERENCE_NODE”, “ENTITY_NODE”, “PROCESSING_INSTRUCTION_NODE”, “COMMENT_NODE”, “DOCUMENT_NODE”, “DOCUMENT_TYPE_NODE”, “DOCUMENT_FRAGMENT_NODE”, “NOTATION_NODE”, “lang”, “dir”, “align”, “offsetTop”, “offsetLeft”, “offsetWidth”, “offsetHeight”, “offsetParent”, “scrollTop”, “scrollLeft”, “scrollHeight”, “scrollWidth”, “clientTop”, “clientLeft”, “clientHeight”, “clientWidth”, “tabIndex”, “contentEditable”, “blur”, “focus”, “spellcheck”, “removeEventListener”, “dispatchEvent”, “baseURI”, “compareDocumentPosition”, “textContent”, “isSameNode”, “lookupPrefix”, “isDefaultNamespace”, “lookupNamespaceURI”, “isEqualNode”, “getFeature”, “setUserData”, “getUserData”, “DOCUMENT_POSITION_DISCONNECTED”, “DOCUMENT_POSITION_PRECEDING”, “DOCUMENT_POSITION_FOLLOWING”, “DOCUMENT_POSITION_CONTAINS”, “DOCUMENT_POSITION_CONTAINED_BY”, “DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC”, “getElementsByClassName”, “getClientRects”, “getBoundingClientRect”]



870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
# File 'lib/vapir-firefox/jssh_socket.rb', line 870

def method_missing(method, *args)
  method=method.to_s
  if method =~ /\A([a-z_][a-z0-9_]*)([=?!])?\z/i
    method = $1
    special = $2
  else # don't deal with any special character crap 
    #Object.instance_method(:method_missing).bind(self).call(method, *args) # let Object#method_missing raise its usual error 
    return super
  end
  case special
  when nil
    invoke(method, *args)
  when '!'
    got=invoke(method, *args)
    got.is_a?(JsshObject) ? got.val : got
  when '?'
    begin
      got=invoke(method, *args)
      got.is_a?(JsshObject) ? got.val_str : got
    rescue JsshUndefinedValueError
      nil
    end
  when '='
    attr(method).assign(*args)
  else
    Object.instance_method(:method_missing).bind(self).call(method, *args) # this shouldn't happen 
  end
end

Instance Attribute Details

#debug_nameObject (readonly)

Returns the value of attribute debug_name.



555
556
557
# File 'lib/vapir-firefox/jssh_socket.rb', line 555

def debug_name
  @debug_name
end

#function_resultObject (readonly)

Returns the value of attribute function_result.



555
556
557
# File 'lib/vapir-firefox/jssh_socket.rb', line 555

def function_result
  @function_result
end

#jssh_socketObject (readonly)

Returns the value of attribute jssh_socket.



554
555
556
# File 'lib/vapir-firefox/jssh_socket.rb', line 554

def jssh_socket
  @jssh_socket
end

#refObject (readonly)

Returns the value of attribute ref.



554
555
556
# File 'lib/vapir-firefox/jssh_socket.rb', line 554

def ref
  @ref
end

#typeObject (readonly)

returns javascript typeof this object



591
592
593
# File 'lib/vapir-firefox/jssh_socket.rb', line 591

def type
  @type
end

Instance Method Details

#%(operand) ⇒ Object



793
794
795
# File 'lib/vapir-firefox/jssh_socket.rb', line 793

def %(operand)
  binary_operator('%', operand)
end

#*(operand) ⇒ Object



790
791
792
# File 'lib/vapir-firefox/jssh_socket.rb', line 790

def *(operand)
  binary_operator('*', operand)
end

#+(operand) ⇒ Object



781
782
783
# File 'lib/vapir-firefox/jssh_socket.rb', line 781

def +(operand)
  binary_operator('+', operand)
end

#-(operand) ⇒ Object



784
785
786
# File 'lib/vapir-firefox/jssh_socket.rb', line 784

def -(operand)
  binary_operator('-', operand)
end

#/(operand) ⇒ Object



787
788
789
# File 'lib/vapir-firefox/jssh_socket.rb', line 787

def /(operand)
  binary_operator('/', operand)
end

#<(operand) ⇒ Object



802
803
804
# File 'lib/vapir-firefox/jssh_socket.rb', line 802

def <(operand)
  binary_operator('<', operand)
end

#<=(operand) ⇒ Object



808
809
810
# File 'lib/vapir-firefox/jssh_socket.rb', line 808

def <=(operand)
  binary_operator('<=', operand)
end

#==(operand) ⇒ Object



796
797
798
# File 'lib/vapir-firefox/jssh_socket.rb', line 796

def ==(operand)
  operand.is_a?(JsshObject) && binary_operator('==', operand)
end

#>(operand) ⇒ Object



799
800
801
# File 'lib/vapir-firefox/jssh_socket.rb', line 799

def >(operand)
  binary_operator('>', operand)
end

#>=(operand) ⇒ Object



805
806
807
# File 'lib/vapir-firefox/jssh_socket.rb', line 805

def >=(operand)
  binary_operator('>=', operand)
end

#[](key) ⇒ Object

returns a JsshObject referring to a subscript of this object, or a value if it is simple (see #val_or_object) subscript is specified as ruby (converted to_jssh).



768
769
770
# File 'lib/vapir-firefox/jssh_socket.rb', line 768

def [](key)
  sub(key).val_or_object(:error_on_undefined => false)
end

#[]=(key, value) ⇒ Object

assigns the given ruby value (passed through json via JsshSocket#assign_json) to the given subscript (key is converted to_jssh).



773
774
775
# File 'lib/vapir-firefox/jssh_socket.rb', line 773

def []=(key, value)
  self.sub(key).assign(value)
end

#assign(val) ⇒ Object

assigns (via JsshSocket#assign) the given ruby value (converted to_jssh) to the reference for this object. returns self.



683
684
685
686
687
688
# File 'lib/vapir-firefox/jssh_socket.rb', line 683

def assign(val)
  @debug_name="(#{debug_name}=#{val.is_a?(JsshObject) ? val.debug_name : val.to_jssh})"
  result=assign_expr val.to_jssh
#    logger.info { "#{self.class} assigned: #{debug_name} (type #{type})" }
  result
end

#assign_expr(val) ⇒ Object

assigns the given javascript expression (string) to the reference for this object



690
691
692
693
694
695
696
697
698
# File 'lib/vapir-firefox/jssh_socket.rb', line 690

def assign_expr(val)
  jssh_socket.value_json("(function(val){#{ref}=val; return null;}(#{val}))")
  @type=nil # uncache this 
  # don't want to use JsshSocket#assign_json because converting the result of the assignment (that is, the expression assigned) to json is error-prone and we don't really care about the result. 
  # don't want to use JsshSocket#assign because the result can be blank and cause send_and_read to wait for data that's not coming - also 
  # using a json function is better because it catches errors much more elegantly. 
  # so, wrap it in a function that returns nil. 
  self
end

#attr(attribute) ⇒ Object

returns a JsshObject referencing the given attribute of this object



674
675
676
677
678
679
# File 'lib/vapir-firefox/jssh_socket.rb', line 674

def attr(attribute)
  unless (attribute.is_a?(String) || attribute.is_a?(Symbol)) && attribute.to_s =~ /\A[a-z_][a-z0-9_]*\z/i
    raise JsshSyntaxError, "#{attribute.inspect} (#{attribute.class.inspect}) is not a valid attribute!"
  end
  JsshObject.new("#{ref}.#{attribute}", jssh_socket, :debug_name => "#{debug_name}.#{attribute}")
end

#binary_operator(operator, operand) ⇒ Object

calls a binary operator with self and another operand



778
779
780
# File 'lib/vapir-firefox/jssh_socket.rb', line 778

def binary_operator(operator, operand)
  JsshObject.new("(#{ref}#{operator}#{operand.to_jssh})", jssh_socket, :debug_name => "(#{debug_name}#{operator}#{operand.is_a?(JsshObject) ? operand.debug_name : operand.to_jssh})").val_or_object
end

#call(*args) ⇒ Object

returns the value (via JsshSocket#value_json) or a JsshObject (see #val_or_object) of the return value of this function (assumes this object is a function) passing it the given arguments (which are converted to_jssh). simply, it just calls self.pass(*args).val_or_object



710
711
712
# File 'lib/vapir-firefox/jssh_socket.rb', line 710

def call(*args)
  pass(*args).val_or_object
end

#define_methods!Object



898
899
900
901
902
903
904
905
# File 'lib/vapir-firefox/jssh_socket.rb', line 898

def define_methods!
  metaclass=(class << self; self; end)
  self.to_hash.keys.grep(/\A[a-z_][a-z0-9_]*\z/i).reject{|k| self.class.method_defined?(k)}.each do |key|
    metaclass.send(:define_method, key) do |*args|
      invoke(key, *args)
    end
  end
end

#id(*args) ⇒ Object



933
934
935
# File 'lib/vapir-firefox/jssh_socket.rb', line 933

def id(*args)
  invoke :id, *args
end

#implemented_interfacesObject



609
610
611
612
613
614
# File 'lib/vapir-firefox/jssh_socket.rb', line 609

def implemented_interfaces
  jssh_socket.Components.interfaces.to_hash.inject([]) do |list, (key, interface)|
    list << interface if instanceof(interface)
    list
  end
end

#inspectObject



992
993
994
# File 'lib/vapir-firefox/jssh_socket.rb', line 992

def inspect
  "\#<#{self.class.name}:0x#{"%.8x"%(self.hash*2)} #{[:type, :debug_name].map{|attr| attr.to_s+'='+send(attr).to_s}.join(', ')}>"
end

#instanceof(interface) ⇒ Object

returns javascript instanceof operator on this and the given interface (expected to be a JsshObject) note that this is javascript, not to be confused with ruby’s #instance_of? method.

example: window.instanceof(window.jssh_socket.Components.interfaces.nsIDOMChromeWindow)

> true



606
607
608
# File 'lib/vapir-firefox/jssh_socket.rb', line 606

def instanceof(interface)
  jssh_socket.instanceof(self.ref, interface.ref)
end

#invoke(attribute, *args) ⇒ Object

returns a JsshObject representing the given attribute. Checks the type, and if it is a function, references the _return value_ of the function (with the given arguments, if any, which are in ruby, converted to_jssh). If the type of the expression is undefined, raises an error (if you want an attribute even if it’s undefined, use #attr).



658
659
660
661
662
663
664
665
666
667
668
669
670
671
# File 'lib/vapir-firefox/jssh_socket.rb', line 658

def invoke(attribute, *args)
  attr_obj=attr(attribute)
  type=attr_obj.type
  case type
  when 'function'
    attr_obj.call(*args)
  else
    if args.empty?
      attr_obj.val_or_object
    else
      raise ArgumentError, "Cannot pass arguments to expression #{attr_obj.ref} of type #{type}"
    end
  end
end

#object_respond_to?(method) ⇒ Boolean

Returns:

  • (Boolean)


910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
# File 'lib/vapir-firefox/jssh_socket.rb', line 910

def object_respond_to?(method)
  method=method.to_s
  if method =~ /^([a-z_][a-z0-9_]*)([=?!])?$/i
    method = $1
    special = $2
  else # don't deal with any special character crap 
    return false
  end

  if self.type=='undefined'
    return false
  elsif special=='='
    if self.type=='object'
      return true # yeah, you can generally assign attributes to objects
    else
      return false # no, you can't generally assign attributes to (boolean, number, string, null)
    end
  else
    attr=attr(method)
    return attr.type!='undefined'
  end
end

#object_typeObject

returns the type of object that is reported by the javascript toString() method, which returns such as “[object Object]” or “[object XPCNativeWrapper [object HTMLDocument]]” This method returns ‘Object’ or ‘XPCNativeWrapper [object HTMLDocument]’ respectively. Raises an error if this JsshObject points to something other than a javascript ‘object’ type (‘function’ or ‘number’ or whatever)



621
622
623
624
625
626
627
628
629
630
631
# File 'lib/vapir-firefox/jssh_socket.rb', line 621

def object_type
  @object_type ||= begin
    case type
    when 'object'
      self.toString! =~ /\A\[object\s+(.*)\]\Z/
      $1
    else
      raise JsshError, "Type is #{type}, not object"
    end
  end
end

#pass(*args) ⇒ Object

returns a JsshObject for this object - assumes that this object is a function - passing this function the specified arguments, which are converted to_jssh



702
703
704
# File 'lib/vapir-firefox/jssh_socket.rb', line 702

def pass(*args)
  JsshObject.new("#{ref}(#{args.map{|arg| arg.to_jssh}.join(', ')})", jssh_socket, :function_result => true, :debug_name => "#{debug_name}(#{args.map{|arg| arg.is_a?(JsshObject) ? arg.debug_name : arg.to_jssh}.join(', ')})")
end

#pretty_print(pp) ⇒ Object



995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
# File 'lib/vapir-firefox/jssh_socket.rb', line 995

def pretty_print(pp)
  pp.object_address_group(self) do
    pp.seplist([:type, :debug_name], lambda { pp.text ',' }) do |attr|
      pp.breakable ' '
      pp.group(0) do
        pp.text attr.to_s
        pp.text ': '
        #pp.breakable
        pp.text send(attr)
      end
    end
  end
end

#respond_to?(method) ⇒ Boolean

Returns:

  • (Boolean)


907
908
909
# File 'lib/vapir-firefox/jssh_socket.rb', line 907

def respond_to?(method)
  super || object_respond_to?(method)
end

#store(js_variable, somewhere_meaningful = true) ⇒ Object

sets the given javascript variable to this object, and returns a JsshObject referring to the variable.

>> foo=document.getElementById(‘guser’).store(‘foo’)

> #<JsshObject:0x2dff870 @ref=“foo” …>

>> foo.tagName

> “DIV”



721
722
723
724
725
# File 'lib/vapir-firefox/jssh_socket.rb', line 721

def store(js_variable, somewhere_meaningful=true)
  stored=JsshObject.new(js_variable, jssh_socket, :function_result => false, :debug_name => somewhere_meaningful ? "(#{js_variable}=#{debug_name})" : debug_name)
  stored.assign_expr(self.ref)
  stored
end

#store_rand_named(&name_proc) ⇒ Object



727
728
729
730
731
732
733
734
735
# File 'lib/vapir-firefox/jssh_socket.rb', line 727

def store_rand_named(&name_proc)
  base=36
  length=6
  begin
    name=name_proc.call(("%#{length}s"%rand(base**length).to_s(base)).tr(' ','0'))
  end while JsshObject.new(name,jssh_socket).type!='undefined'
  # okay, more than one iteration is ridiculously unlikely, sure, but just to be safe. 
  store(name, false)
end

#store_rand_object_key(object) ⇒ Object



743
744
745
746
747
748
# File 'lib/vapir-firefox/jssh_socket.rb', line 743

def store_rand_object_key(object)
  raise ArgumentError("Object is not a JsshObject: got #{object.inspect}") unless object.is_a?(JsshObject)
  store_rand_named do |r|
    object.sub(r).ref
  end
end

#store_rand_prefix(prefix) ⇒ Object



737
738
739
740
741
# File 'lib/vapir-firefox/jssh_socket.rb', line 737

def store_rand_prefix(prefix)
  store_rand_named do |r|
    prefix+"_"+r
  end
end

#store_rand_tempObject



750
751
752
# File 'lib/vapir-firefox/jssh_socket.rb', line 750

def store_rand_temp
  store_rand_object_key(jssh_socket.temp_object)
end

#sub(key) ⇒ Object

returns a JsshObject referring to a subscript of this object, specified as a ruby object converted to javascript via to_jssh



762
763
764
# File 'lib/vapir-firefox/jssh_socket.rb', line 762

def sub(key)
  JsshObject.new("#{ref}[#{key.to_jssh}]", jssh_socket, :debug_name => "#{debug_name}[#{key.is_a?(JsshObject) ? key.debug_name : key.to_jssh}]")
end

#to_arrayObject



958
959
960
# File 'lib/vapir-firefox/jssh_socket.rb', line 958

def to_array
  JsshArray.new(self.ref, self.jssh_socket, :debug_name => debug_name)
end

#to_domObject



964
965
966
# File 'lib/vapir-firefox/jssh_socket.rb', line 964

def to_dom
  JsshDOMNode.new(self.ref, self.jssh_socket, :debug_name => debug_name)
end

#to_hashObject



961
962
963
# File 'lib/vapir-firefox/jssh_socket.rb', line 961

def to_hash
  JsshHash.new(self.ref, self.jssh_socket, :debug_name => debug_name)
end

#to_js_arrayObject



949
950
951
# File 'lib/vapir-firefox/jssh_socket.rb', line 949

def to_js_array
  jssh_socket.object('$A').call(self)
end

#to_js_hashObject



952
953
954
# File 'lib/vapir-firefox/jssh_socket.rb', line 952

def to_js_hash
  jssh_socket.object('$H').call(self)
end

#to_js_hash_safeObject



955
956
957
# File 'lib/vapir-firefox/jssh_socket.rb', line 955

def to_js_hash_safe
  jssh_socket.object('$_H').call(self)
end

#to_json(options = {}) ⇒ Object

this still needs to be defined because when ActiveSupport::JSON.encode is called by to_jssh on an array or hash containing a JsshObject, it calls to_json. which apparently just freezes. I guess that’s because JsshSocket circularly references itself with its instance variables.



945
946
947
# File 'lib/vapir-firefox/jssh_socket.rb', line 945

def to_json(options={})
  ref
end

#to_jsshObject

gives a reference for this object. this is the only class for which to_jssh doesn’t convert the object to json.



939
940
941
# File 'lib/vapir-firefox/jssh_socket.rb', line 939

def to_jssh
  ref
end

#to_ruby_hash(options = {}) ⇒ Object



967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
# File 'lib/vapir-firefox/jssh_socket.rb', line 967

def to_ruby_hash(options={})
  options={:recurse => 1}.merge(options)
  return self if !options[:recurse] || options[:recurse]==0
  return self if self.type!='object'
  next_options=options.merge(:recurse => options[:recurse]-1)
  begin
    keys=self.to_hash.keys
  rescue JsshError
    return self
  end
  keys.inject({}) do |hash, key|
    val=begin
      self[key]
    rescue JsshError
      $!
    end
    hash[key]=if val.is_a?(JsshObject)
      val.to_ruby_hash(next_options)
    else
      val
    end
    hash
  end
end

#valObject

returns the value, via JsshSocket#value_json



576
577
578
# File 'lib/vapir-firefox/jssh_socket.rb', line 576

def val
  jssh_socket.value_json(ref, :error_on_undefined => !function_result)
end

#val_or_object(options = {}) ⇒ Object



633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
# File 'lib/vapir-firefox/jssh_socket.rb', line 633

def val_or_object(options={})
  options={:error_on_undefined=>true}.merge(options)
  if function_result # calling functions multiple times is bad, so store in temp before figuring out what to do with it
    store_rand_object_key(jssh_socket.temp_object).val_or_object(:error_on_undefined => false)
  else
    case self.type
    when 'undefined'
      if !options[:error_on_undefined]
        nil
      else
        raise JsshUndefinedValueError, "undefined expression #{ref}"
      end
    when 'boolean','number','string','null'
      val
    else # 'function','object', or anything else 
      self
    end
  end
end

#val_strObject

returns the value just as a string with no attempt to deal with type using json. via JsshSocket#value

note that this can be slow if it evaluates to a blank string. for example, if ref is just “” then JsshSocket#value will wait DEFAULT_SOCKET_TIMEOUT seconds for data that is not to come. this also happens with functions that return undefined. if ref=“function()do_some_stuff;” (with no return), it will also wait DEFAULT_SOCKET_TIMEOUT.



586
587
588
# File 'lib/vapir-firefox/jssh_socket.rb', line 586

def val_str
  jssh_socket.value(ref)
end