sketchucation logo sketchucation
    • 登入
    Oops, your profile's looking a bit empty! To help us tailor your experience, please fill in key details like your SketchUp version, skill level, operating system, and more. Update and save your info on your profile page today!
    ⚠️ Important | Libfredo 15.8b introduces important bugfixes for Fredo's Extensions Update

    [Code] PCFileTools

    已排程 已置頂 已鎖定 已移動 Developers' Forum
    27 貼文 3 Posters 4.4k 瀏覽 3 Watching
    正在載入更多貼文
    • 從舊到新
    • 從新到舊
    • 最多點贊
    回覆
    • 在新貼文中回覆
    登入後回覆
    此主題已被刪除。只有擁有主題管理權限的使用者可以查看。
    • Dan RathbunD 離線
      Dan Rathbun
      最後由 編輯

      @tig said:

      ... although I'd be wary of overwriting base class ?

      I didn't say anyone should. I said they should be subclasses of the base class. If they are, Ruby would not let anyone make the subclass overwrite the baseclass, because it would be a circular reference.

      EDIT: I tested this at the console. Ruby does not check for circular references using the c-side **=** operator. Anyway, it does not actually create a circular reference. The reference to original baseclass becomes un-identified by any constant, but the object can still be got, via the superclass() method.

      Making a LOCAL constant point at an object (in this case a Class definition,) does not overwrite anything.

      Now obviously, if some stupid 'newb' types File = SKX::WIN::File in the Ruby Console, or in an unwrapped script, THAT global constant that references the base class definition object, is changed (and affects all scripts that are also using it.) So, in order to set it back [without restarting,] it might be a good idea to have a 'secret' reference to the base class definition, kept "out of sight."

      module Ruby
        
        Refs = {}
        # base classes
        Object.constants.sort.each {|ref|
          obj = Object.class_eval "#{ref}"
          Refs[ref]= obj if obj.class==(Class)
        }
        # base modules
        [Comparable,Enumerable,Errno,FileTest,GC,
         Kernel,Marshal,Math,ObjectSpace,Process].each {|obj|
          Refs[obj.name]= obj
        }
        Refs['TOPLEVEL_BINDING']= TOPLEVEL_BINDING
        Refs.freeze
      
        def self.reset_object_ref(ref)
          if ref.is_a?(String) || ref.is_a?(Symbol)
            ref = ref.to_s 
          elsif ref.is_a?(Module) # includes Class
            ref = ref.name
          else
            return nil
          end
          if Ref.has_key?(ref)
            begin
              eval( "#{ref} = ObjectSpace._id2ref(#{Ref[ref].object_id})", TOPLEVEL_BINDING )
            rescue
              return false
            else
              return true
            end
          end
          return false
        end
      
      end#module
      ###
      

      EDIT: I added a reset method to the example, just for kicks.

      @tig said:

      I've kept everything separated for testing - so it still works provided you substitute PCFile.exist?(filepath) for File.exist?(filepath) and so on...

      You won't find many who are willing to go through their code and search and replace, "File." with "PCFile.", besides you haven't provided aliases for the methods you did not implement, which makes a simple editor search and replace, into a tedious manual edit session.

      You might consider, overriding the method_missing callback, whilst you still have them as custom modules:

      def method_missing( sym, *args )
        if File.respond_to?(sym)
          File.method(sym).call(*args)
        else
          raise(NoMethodError,"undefined method `#{sym.to_s}' for #{self.name};#{self.class.name}",caller)
        end
      end#def
      

      and similar for PCDir:

      def method_missing( sym, *args )
        if Dir.respond_to?(sym)
          Dir.method(sym).call(*args)
        else
          raise(NoMethodError,"undefined method `#{sym.to_s}' for #{self.name};#{self.class.name}",caller)
        end
      end#def
      

      I'm not here much anymore.

      1 條回覆 最後回覆 回覆 引用 0
      • Dan RathbunD 離線
        Dan Rathbun
        最後由 編輯

        @tig said:

        ... and I can't see currently how to do the equivalent of ' binmode' etc. Any suggestions/additions gratefully received..

        Ya know.. it's weird that the Core guys made this switch, without a way to test later IF the stream was IN binmode or not.

        I checked the docs, and the Ruby 1.8.7 branch is still the same.

        BUT... in the 1.9.x trunk, they have added a binmode?() boolean query method. (See the online docs for IO class. They also added methods binread and binwrite, special open methods.)
        Of course, they have added a bunch of options, to read and write in several encodings.

        I'm not here much anymore.

        1 條回覆 最後回覆 回覆 引用 0
        • Dan RathbunD 離線
          Dan Rathbun
          最後由 編輯

          What effect do you imagine WIN32OLE.codepage= WIN32OLE::CP_UTF8 would have over CP_ACP (ANSI?/ASCII?), which seems to be the default.

          I'm not here much anymore.

          1 條回覆 最後回覆 回覆 引用 0
          • Dan RathbunD 離線
            Dan Rathbun
            最後由 編輯

            Ok TIG.. a general question:

            most all of the methods are doing this:

            arg = arg.unpack("U*").map{|c|c.chr}.join

            which seems to convert a UTF-8 string (if it is one,) to an ANSI string, before passing it to Windows FSO methods that take and return Unicode strings ...

            1) correct ??

            2) and why ??

            I'm not here much anymore.

            1 條回覆 最後回覆 回覆 引用 0
            • TIGT 離線
              TIG Moderator
              最後由 編輯

              I found that if I didn't do that change to the string then any tests of UTF-8 strings, like PCFile.exist?(path) do not work properly and return ' false' when it should be ' true'... just like the File.exist?(path) version; BUT making that change to the string before testing it seems to return correct results - consistently ' true' when it should be ' true' and ' false' when it should be ' false'. For a simple ANSI character string it works fine either way [the unpack/join has no affect], but if you test with a UTF-8 string with accented characters [perhaps obtained from a UI.openpanel()], that is unpack/joined etc then you can see the difference between what the File.. and PCFile.. versions return...
              There's probably a more elegant way to do this... BUT it seems to work the way I've bodged it together, so now perhaps we can think of better ways of achieving the same difference... 😕

              TIG

              1 條回覆 最後回覆 回覆 引用 0
              • Dan RathbunD 離線
                Dan Rathbun
                最後由 編輯

                That seems to indicate that the FSO methods are doing ANSI comparisons (perhaps by default.)

                I'm not here much anymore.

                1 條回覆 最後回覆 回覆 引用 0
                • thomthomT 離線
                  thomthom
                  最後由 編輯

                  So, does PCFile.exist?() return true for a file with, for example, Japanese characters?

                  Thomas Thomassen — SketchUp Monkey & Coding addict
                  List of my plugins and link to the CookieWare fund

                  1 條回覆 最後回覆 回覆 引用 0
                  • Dan RathbunD 離線
                    Dan Rathbun
                    最後由 編輯

                    Would the Japanese Kanji chars be in the UTF-16 set?

                    Ya know we are all back to the ol' String encoding problem, really.

                    I thot about using Dan Berger's String subclass(es) WideString or whatever he called them, but it seem like it would be combersome. Unless they converted themselves automatically similar to how Numerics use coerce().
                    Currently the interpreter always makes ANSI strings from **" "** and **' '** literals. (and their **%**dilimeter equivs.)

                    I wonder if possible to create a %u function that creates UTF8 strings. And maybe a %U that creates UTF16 ?
                    (Are these defined in Kernel, or are they C-side interpreter functions?

                    (Just throwing issues in the air, "musing out load.")

                    I'm not here much anymore.

                    1 條回覆 最後回覆 回覆 引用 0
                    • thomthomT 離線
                      thomthom
                      最後由 編輯

                      The underlying problem in Ruby 1.8 under windows is that it calls the A version of the file functions instead of the W versions. If a function is called FileFunction is used in C/C++ - when compiled it will translate to FileFunctionA or FileFunctionW depending on whether UNICODE is defined.
                      I was thinking that a C Extension that would forcefully call the FileFunctionW variants would be sure to work as it would be the system doing all the work. Meddling with the string in Ruby is quite likely to cause data to be lost or corrupted.

                      Thomas Thomassen — SketchUp Monkey & Coding addict
                      List of my plugins and link to the CookieWare fund

                      1 條回覆 最後回覆 回覆 引用 0
                      • TIGT 離線
                        TIG Moderator
                        最後由 編輯

                        I only works for UTF-8 [i.e. 'European' accented-characters etc] - the more complex Chinese/Japanese return false when it should be true 😒
                        However, if we have a way of resolving one hopefully the other will follow...

                        TIG

                        1 條回覆 最後回覆 回覆 引用 0
                        • TIGT 離線
                          TIG Moderator
                          最後由 編輯

                          http://www.danielstutzman.com/2011/04/how-to-write-unicode-filenames-in-ruby-1-8-6 uses Win32API and iconv ...

                          TIG

                          1 條回覆 最後回覆 回覆 引用 0
                          • Dan RathbunD 離線
                            Dan Rathbun
                            最後由 編輯

                            BTW.. if interested:

                            This is the Extended lib module FileUtils from Ruby v1.8.6-p287
                            module FileUtils (Ruby v1.8.6-p287)

                            I'm not here much anymore.

                            1 條回覆 最後回覆 回覆 引用 0
                            • Dan RathbunD 離線
                              Dan Rathbun
                              最後由 編輯

                              from the old Pick-axe Book:

                              @unknownuser said:

                              Strings are stored as sequences of 8-bit bytes,[For use in Japan, the jcode library supports a set of operations of strings written with EUC, SJIS, or UTF-8 encoding. The underlying string, however, is still accessed as a series of bytes.] and each byte may contain any of the 256 8-bit values, including null and newline. The substitution mechanisms in Table 18.2* on page 203 allow nonprinting characters to be inserted conveniently and portably.

                              • refers to the table of ** codes

                              Also Standard Types: Strings


                              So it seems that (in my mind,) since Sketchup sets $KCODE to UTF8 when it loads the interpreter, we may not actually have as much of a problem on the Rubyside as I thought.

                              So we have a choice...

                              1) A pure-Ruby patch, that either accesses the system calls (for File functions,) via WIN32OLE or WIN32API (the so libraries.)

                              2) A compiled C patch, ie: "Cut out" the c code files that define classes IO, Dir and File (perhaps also FileTest,) and recompile with either UNICODE #defined, or change the C function calls explicitly to the wide versions. These would be ".so" files, and they would redefine the old methods. (What happens on the C-side when you re-define a C function that has already been defined? Do the C functions that the new Ruby wrappers call, need to be renamed as well?)


                              I'm not here much anymore.

                              1 條回覆 最後回覆 回覆 引用 0
                              • thomthomT 離線
                                thomthom
                                最後由 編輯

                                I was thinking that a C extension that did most of the functions used, like File.exist?, read, write, delete and list files in folders would go a long way. It wouldn't be as extensive as a complete rewrite - therefor more quicker to develop. Then off course not replacing the existing methods - as it'd just open up a vast pool of possible problems which would require even more testing and development.

                                Trying to rewrite the entire File, Dir and IO classes to call the W variant file function just seems like such a massive undertaking that it'd probably never be completed.

                                Thomas Thomassen — SketchUp Monkey & Coding addict
                                List of my plugins and link to the CookieWare fund

                                1 條回覆 最後回覆 回覆 引用 0
                                • TIGT 離線
                                  TIG Moderator
                                  最後由 編輯

                                  Does Sketchup set $KCODE to "UTF8" in all locales - I know it does in UK/US and probably European language locales BUT what about Chinese ? I'll ask someone...
                                  If we get a consistent code for their locale can we modify the pack/join code to say use 'u' not 'U' and get an appropriate conversion in different $KCODE cases ?

                                  TIG

                                  1 條回覆 最後回覆 回覆 引用 0
                                  • Dan RathbunD 離線
                                    Dan Rathbun
                                    最後由 編輯

                                    @thomthom said:

                                    Then of course not replacing the existing methods - as it'd just open up a vast pool of possible problems which would require even more testing and development.

                                    Well what I said before still goes... The new class(es) are in a Library namespace, need to be require(d), and then referenced within an author's namespace via an alias, (as I showed in the examples above.)

                                    I mispoke when I said redefine, they would have the same identifiers, but be within, say SKX::WIN module namespace.

                                    @thomthom said:

                                    Trying to rewrite the entire File, Dir and IO classes to call the W variant file function just seems like such a massive undertaking that it'd probably never be completed.

                                    I was hoping (without yet digging into the C source,) that it might be easy to use Notepad++ search and replace to stick "W" where they need to be.

                                    I'm not here much anymore.

                                    1 條回覆 最後回覆 回覆 引用 0
                                    • thomthomT 離線
                                      thomthom
                                      最後由 編輯

                                      @dan rathbun said:

                                      @thomthom said:

                                      Trying to rewrite the entire File, Dir and IO classes to call the W variant file function just seems like such a massive undertaking that it'd probably never be completed.

                                      I was hoping (without yet digging into the C source,) that it might be easy to use Notepad++ search and replace to stick "W" where they need to be.

                                      Don't think it's that easy. I think there's a few type definitions that also needs to be adjusted. And then you need to ensure that there's no hard coded struct or data type sizes used...

                                      Thomas Thomassen — SketchUp Monkey & Coding addict
                                      List of my plugins and link to the CookieWare fund

                                      1 條回覆 最後回覆 回覆 引用 0
                                      • Dan RathbunD 離線
                                        Dan Rathbun
                                        最後由 編輯

                                        Poking around, finding links to help Adam on his Hebrew webdialog problem, I ran across a link on the Wikipedia Windows Code Pages doc.

                                        Down at the bottom:

                                        @unknownuser said:

                                        See also


                                        AppLocale — a utility to run non-Unicode (code page-based) applications in a locale of the user's choice.

                                        I'm not here much anymore.

                                        1 條回覆 最後回覆 回覆 引用 0
                                        • Dan RathbunD 離線
                                          Dan Rathbun
                                          最後由 編輯

                                          BUMP

                                          I'm not here much anymore.

                                          1 條回覆 最後回覆 回覆 引用 0
                                          • 1
                                          • 2
                                          • 1 / 2
                                          • 第一個貼文
                                            最後的貼文
                                          Buy SketchPlus
                                          Buy SUbD
                                          Buy WrapR
                                          Buy eBook
                                          Buy Modelur
                                          Buy Vertex Tools
                                          Buy SketchCuisine
                                          Buy FormFonts

                                          Advertisement