IronRuby is_a with DateTime - ironruby

Can anybody explain why DateTime in IronRuby is Object[]
sample code
IronRuby 0.9.1.0 on .NET 2.0.50727.4927
Copyright (c) Microsoft Corporation. All rights reserved.
>>> require 'System'
=> true
>>> t = System::DateTime.Now
=> Thu Dec 03 15:32:42 +05:00 2009
>>> t.is_a?(Time)
=> true
>>> t.is_a?(System::DateTime)
=> true
>>> t.is_a?(System::Object)
=> true
>>> t.is_a?(System::Object[])
=> true
>>> t.is_a?(System::Decimal)
=> false

Using [] for generic types is a justifiable syntax for Ruby, but the current behavior you see (using [] on a non-generic type) is a open bug: http://ironruby.codeplex.com/WorkItem/View.aspx?WorkItemId=3355
In Ruby, square brackets are only used for indexing into an array, not define a type-array ... as there is no need for defining the type of a Ruby array. Ruby allows overloading whatever [] means against any object, and Ruby's Class object doesn't have a meaning for [], so we've defined [] to mean getting a generic type. Keep in mind that the of method is the preferred method to use; [] is really only there for convenience and similar syntax with IronPython.

Because System::Object[] is not really an array type. t.is_a?(System::DateTime[]) will return true as well.
I think that what happens here, is that IronRuby considers the square brackets as empty generic type indicators (because creating a generic type is done with the same syntax, for example, System::Collections::Generic::List[String].new).
The right way to do so is as follows:
IronRuby 0.9.3.0 on .NET 2.0.50727.4927
Copyright (c) Microsoft Corporation. All rights reserved.
>>> t = System::DateTime.new
=> 01/01/0001 00:00:00
>>> t.is_a? System::Array.of(System::Object)
=> false

Related

Ruby 2.2.3 invalid date

The following method
now = Date.today
#start_week = Date.commercial(now.cwyear,now.cweek+9)
is returning and argument error invalid date. This was working under ruby 1.9.3. Oddly enough, there are no complaints regarding
#start_week = Date.commercial(now.cwyear,now.cweek+8)
and the console returns Mon, 28 Dec 2015
So the issue is how does one concisely rollover the year in such a context.
Silly. Transform the method to a succinct
#start_week = Date.today.beginning_of_week + 9.weeks
[get percolator running]

Can you specify the return type of a method in a clojure defrecord?

I've created an application-info interface and a class but when I review the generated classes the return type for all of the methods is Object, can I change the return type to String? The documentation says type hinting is possible with defrecord but doesn't give an example, the only examples I could find were for type hinting fields and method arguments.
src/com/vnetpublishing.clj
(ns com.vnetpublishing)
(defprotocol ApplicationInfo
(author [obj])
(author-email [obj])
(copyright [obj])
(app-name [obj])
(version [obj])
)
src/Physics.clj
(ns Physics)
(defrecord info [] com.vnetpublishing.ApplicationInfo
(author [this] "Ralph Ritoch")
(author-email [this] "Ralph Ritoch <root#localhost>")
(copyright [this] "Copyright \u00A9 2014 Ralph Ritoch. All rights reserved.")
(app-name [this] "Physics")
(version [this] "0.0.1-alpha")
)
Look at definterface macro.
Unlike defprotocol, the definterface macro provide a way to write return type hint for methods.
Alan Malloy explain this pretty well here:
"Protocols are for consumption by Clojure functions, which aren't
supposed to be statically typed; interfaces are for consumption by
Java classes, which are required to be statically typed."
You can then use it like:
(definterface Test
(^void returnsVoid [])
(^int returnsInt [])
(^long returnsLong [])
(^String returnsString [])
(^java.util.HashMap returnsJavaUtilHashMap []))
You can type-hint the protocol ...
(defprotocol ApplicationInfo
(author ^String [obj])
; ...
)
but I'm told that this type-hint is probably ignored (see this follow-up question).

MacRuby Pointer to typedef struct

this code fails with Semgentation Fault: 11, and I can't understand why
framework 'Cocoa'
framework 'CoreFoundation'
framework 'Security'
* keychainObject = Pointer.new_with_type('^{OpaqueSecKeychainRef}')
SecKeychainOpen("/Users/charbon/Library/Keychains/Josja.keychain",keychainObject)
SecKeychainLock(keychainObject)
I'm sure it has to do with the keychainObject type, because this works (it locks the default keychain).
SecKeychainLock(nil)
I'm using the '^{OpaqueSecKeychainRef}' as the type of pointer because that's what the debugger told me it expected when I used a wrong type of pointer.
I hope solving this would help grasping the macruby / cocoa magic.
For reference, the complete output is
cobalt:~ charbon$ macirb Desktop/test.rb
irb(main):001:0> framework 'Cocoa'
=> true
irb(main):002:0> framework 'CoreFoundation'
=> true
irb(main):003:0> framework 'Security'
=> true
irb(main):004:0> * keychainObject = Pointer.new_with_type('^{OpaqueSecKeychainRef}')
=> [#<Pointer:0x4007ac200>]
irb(main):005:0> SecKeychainOpen("/Users/charbon/Library/Keychains/Josja.keychain",keychainObject)
=> 0
irb(main):006:0> SecKeychainLock(keychainObject)
Segmentation fault: 11
If you were writing C you would have written
SecKeychainRef keyChainRef;
SecKeychainOpen("/path/to/...", &keychainRef);
SecKeychainLock(keyChainRef);
i.e. while SecKeychainOpen requires a pointer to a SecKeychainRef (so that the output parameter can be filled in), other apis just require a SecKeychainRef, so you need to dereference the pointer:
framework 'Security'
keychainObject = Pointer.new_with_type('^{OpaqueSecKeychainRef}')
SecKeychainOpen("/Users/charbon/Library/Keychains/Josja.keychain",keychainObject)
SecKeychainLock(keychainObject.value)

String "<<" operator producing warnings and unexpected result in Ruby1.9.3

Please find the code which I ran from the IRB terminal:
Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.
C:\Documents and Settings\rakshiar>irb
irb(main):001:0> src = 'E:\WIPData\Ruby\Scripts\TaxDocumentDownload'
=> "E:\\WIPData\\Ruby\\Scripts\\TaxDocumentDownload"
irb(main):002:0> dest = 'E:\WIPData\Ruby\Scripts'
=> "E:\\WIPData\\Ruby\\Scripts"
irb(main):003:0> dest<<'H00371101'
=> "E:\\WIPData\\Ruby\\ScriptsH00371101"
irb(main):004:0>
Why here such \\ is coming? How to fix that?
When i am running the same part from the script getting the below warnings:
CODE
src = 'E:\WIPData\Ruby\Scripts\TaxDocumentDownload'
dest = 'E:\WIPData\Ruby\Scripts'
dest<<'H00371101'
FileUtils.copy_entry(src, dest, preserve = false, dereference_root = false, remove_destination = false)
Warning:
Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.
C:\Documents and Settings\rakshiar>cd..
C:\Documents and Settings>cd..
C:\>e:
E:\>cd E:\WIPData\Ruby\Scripts
E:\WIPData\Ruby\Scripts>downloadv1.rb
C:/Ruby193/lib/ruby/1.9.1/FileUtils.rb:93: warning: already initialized constant
OPT_TABLE
C:/Ruby193/lib/ruby/1.9.1/FileUtils.rb:1268: warning: already initialized consta
nt S_IF_DOOR
C:/Ruby193/lib/ruby/1.9.1/FileUtils.rb:1496: warning: already initialized consta
nt DIRECTORY_TERM
C:/Ruby193/lib/ruby/1.9.1/FileUtils.rb:1500: warning: already initialized consta
nt SYSCASE
C:/Ruby193/lib/ruby/1.9.1/FileUtils.rb:1619: warning: already initialized consta
nt LOW_METHODS
C:/Ruby193/lib/ruby/1.9.1/FileUtils.rb:1625: warning: already initialized consta
nt METHODS
Could you please say why such warnings are coming?
When try the below from the IRB again different output:
C:\Documents and Settings\rakshiar>irb
irb(main):001:0> src = "E:\WIPData\Ruby\Scripts\TaxDocumentDownload"
=> "E:WIPDataRubyScriptsTaxDocumentDownload"
irb(main):002:0> est = "E:\WIPData\Ruby\Scripts"
=> "E:WIPDataRubyScripts"
irb(main):003:0> est<<"H00371101"
=> "E:WIPDataRubyScriptsH00371101"
irb(main):004:0> est<<"H00371101"
EDIT:
ERROR
E:\WIPData\Ruby\Scripts>downloadv1.rb
E:/WIPData/Ruby/Scripts/downloadv1.rb:87: syntax error, unexpected tCONSTANT, ex
pecting $end
dest<<"H00371101"
^
From the script code part:
src = "E:\WIPData\Ruby\Scripts\TaxDocumentDownload"
dest = "E:\WIPData\Ruby\Scripts\"
dest<<"H00371101"
FileUtils.copy_entry(src, dest, preserve = false, dereference_root = false, remove_destination = false)
I want that src and dest directory as the real directory path. How to get that?
Thanks.
Ruby has, broadly speaking, two types of strings. In a double-quoted string, backslashes "escape" characters - a backslash followed by another letter produces a special character. For example, "\n" gives you a newline. Inside single-quoted strings, the backslash doesn't escape characters - '\n' is just a backslash followed by the letter n. (Actually this isn't 100% true, the exception is '\'' which is a single quote - otherwise there would be no way to embed a single quote in a single-quoted string.
That's why your single-quoted src = 'E:\WIPData\Ruby\Scripts\TaxDocumentDownload' will work, and double-quoted src = "E:\WIPData\Ruby\Scripts\TaxDocumentDownload" will not.
The double-backslashes are printed there because irb uses inspect on the resulting output, which returns the string in double-quoted form (with special characters escaped):
'"Hello," said Andy'.inspect # => "\"Hello,\" said Andy"
They're not really in the string, as you can see with puts:
puts '"Hello," said Andy' # => "Hello," said Andy
The error you have is because of using a double-quoted string, the backslashes are treated as escape characters, so your string is unterminated:
src = "E:\WIPData\Ruby\Scripts\"
dest<<"H00371101"
is parsed the same as
src = 'E:WIPDataRubyScripts"dest<<'H00371101
which is a syntax error.
You should go and read about the difference between single- and double-quoted strings. Here's one resource.
A quick google suggests that you might be doing require 'FileUtils' not require 'fileutils'? This post said that the same warnings disappeared once they changed to the latter. It's because Windows' file system is not case-sensitive - to Ruby, FileUtils.rb and fileutils.rb are two different files, but to Windows, they're the same.
The FileUtils warning it is because you have to change your required gem, like this:
require 'FileUtils' WRONG
require 'fileutils' OKAY
This will solve your warnings :)

Parse string to JSON/Hash

I'm trying to convert the following string to either a hash or json.
How do I do this in ruby?
[{"place":null,"coordinates":null,"in_reply_to_user_id":null,"in_reply_to_status_id":null,
"favorited":false,"truncated":false,"created_at":"Wed Nov 16 08:00:46 +0000 2011","retweet_count":0,"in_reply_to_screen_name":null,
"user":{"profile_background_image_url":"http:\/\/a1.twimg.com\/profile_background_images\/190989640\/afcx.jpg","protected":false,
"statuses_count":23414,"profile_link_color":"FF0000"},"retweeted":false,"in_reply_to_status_id_str":null,"in_reply_to_user_id_str":null,"contributors":null,"geo":null}]
I'm running ruby1.8.7.
What you have appears to be JSON already, so I assume you're looking to get a Ruby Hash from it. If so, then this should work:
Get a JSON library, I used gem install json_pure, which is a native Ruby implementation (there's a faster, C-based version but you wouldn't notice the difference unless your JSON strings are very large or you have a lot of them).
then
require 'json'
arr = JSON(your_json_string_here)
Note that the string you gave is a single-element array containing something that will map to a Ruby Hash. If you just want the hash:
the_hash = arr[0] # or maybe arr.first
I get this:
{"coordinates"=>nil, "created_at"=>"Wed Nov 16 08:00:46 +0000 2011",
"truncated"=>false, "favorited"=>false, "in_reply_to_user_id_str"=>nil,
"contributors"=>nil, in_reply_to_status_id_str"=>nil, "retweet_count"=>0,
"geo"=>nil, "retweeted"=>false, "in_reply_to_user_id"=>nil,
"user"=>{"profile_link_color"=>"FF0000", "protected"=>false,
"statuses_count"=>23414,
"profile_background_image_url"=>"http://a1.twimg.com/profile_background_images/190989640/afcx.jpg"},
"in_reply_to_screen_name"=>nil, place"=>nil, "in_reply_to_status_id"=>nil}

Resources